none
RSA private key from PEM file and Java code converting to C# RRS feed

  • Question

  • Hi everyone.

    Can you help me, please. I stacked on one problem - I can't correctly convert Java code to C# and use the RSA private key from *.pem file.

    public String sign(String message) throws SignatureException{
         try {
                 Signature sign = Signature.getInstance("SHA1withRSA");
                 sign.initSign(privateKey);
                 sign.update(message.getBytes("UTF-8"));
                 return new String(Base64.encodeBase64(sign.sign()),"UTF-8");
         } catch (Exception ex) {
                throw new SignatureException(ex);
         }
    }

    public boolean verify(String message, String signature) throws SignatureException{
         try {
                 Signature sign = Signature.getInstance("SHA1withRSA");
                 sign.initVerify(publicKey);
                 sign.update(message.getBytes("UTF-8"));
                 return sign.verify(Base64.decodeBase64(signature.getBytes("UTF-8")));
         } catch (Exception ex) {
                 throw new SignatureException(ex);
         }
    }

    Wednesday, January 9, 2019 7:48 AM

Answers

  • Thank you very much Jack.


    Finally I got this code, which signs from private.pem file, and verify it from public.pem file. Hopefully this would help anybody to use this type of signing in asp.net.

    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    using Org.BouncyCastle.Crypto;
    using Org.BouncyCastle.Crypto.Parameters;
    using Org.BouncyCastle.OpenSsl;
    using Org.BouncyCastle.Security;
    
    public class PemReader{
    
    private string Signature(string message)
            {
                string privateKeyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "private.pem");
    
                var privateRsa = RsaProviderFromPrivateKeyInPemFile(privateKeyPath);
    
                var signedData = privateRsa.SignData(Encoding.UTF8.GetBytes(message), CryptoConfig.MapNameToOID("SHA1"));
    
                return Convert.ToBase64String(signedData);
            }
    
    private bool Verify(string message, string signedData)
            {
                string publicKeyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "public.pem");
    
                var publicRsa= RsaProviderFromPublicKeyInPemFile(publicKeyPath);
    
                var verifiedData = publicRsa.VerifyData(Encoding.UTF8.GetBytes(message), CryptoConfig.MapNameToOID("SHA1"), Convert.FromBase64String(signedData));
    
                return verifiedData;
            }
    
      public RSACryptoServiceProvider RsaProviderFromPrivateKeyInPemFile(string privateKeyPath)
            {
                using (TextReader privateKeyTextReader = new StringReader(File.ReadAllText(privateKeyPath)))
                {
                    PemReader pr = new PemReader(privateKeyTextReader);
                    AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
                    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)keyPair.Private);
    
                    RSACryptoServiceProvider csp = new RSACryptoServiceProvider(); 
                    csp.ImportParameters(rsaParams);
                    return csp;
                }
            }
    
    public RSACryptoServiceProvider RsaProviderFromPublicKeyInPemFile(string publicKeyPath)
            {
                using (TextReader privateKeyTextReader = new StringReader(File.ReadAllText(publicKeyPath)))
                {
                    PemReader pr = new PemReader(privateKeyTextReader);
                    AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();
                    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);
    
                    RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
                    csp.ImportParameters(rsaParams);
                    return csp;
                }
            }
    
    }
    
    
    
    

    • Marked as answer by Derderer Friday, January 11, 2019 8:28 AM
    Thursday, January 10, 2019 1:22 PM

All replies

  • You can find solution for this from StackOverflow.

    As usual, for any cryptographic operation related questions that Microsoft does not cover with .NET framework, you're likely to find its support on BouncyCastle library.

    Wednesday, January 9, 2019 7:56 AM
    Answerer
  • Hi Derderer,

    Thank you for posting here.

    According to your description, you want to convert Java code to C# correctly and use the RSA private key from *.pem file.

    Please refer to the following code.

    using System.Security.Cryptography;
    using Org.BouncyCastle.OpenSsl;
    using Org.BouncyCastle.Crypto;
    using Org.BouncyCastle.Security;
    using Org.BouncyCastle.Crypto.Parameters;
    using Org.BouncyCastle.Crypto.Encodings;
    using Org.BouncyCastle.Crypto.Engines;
    
    public static string sign(string message)
            {
                string decrypted="something";
                try
                {
                    var bytesToDecrypt = Convert.FromBase64String(message);
                    StreamReader sr = new StreamReader(@"D:\test.pem");
                    PemReader pr = new PemReader(sr);
                    AsymmetricCipherKeyPair KeyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
                    var decryptEngine = new Pkcs1Encoding(new RsaEngine());
                    decryptEngine.Init(false, KeyPair.Private);
                    decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));
                }
                catch (CryptographicException e)
                {
                    Console.WriteLine(e.Message);
                }
                return decrypted;
            }
            public static bool verify(string message,string signature, RSAParameters publicKey)
            {
                  
                    bool success = false;
                    using (var rsa = new RSACryptoServiceProvider())
                    {
                        byte[] bytesToVerify = Convert.FromBase64String(message);
                        byte[] signedBytes = Convert.FromBase64String(signature);
                        try
                        {
                            rsa.ImportParameters(publicKey);
    
                            SHA512Managed Hash = new SHA512Managed();
    
                            byte[] hashedData = Hash.ComputeHash(signedBytes);
    
                            success = rsa.VerifyData(bytesToVerify, CryptoConfig.MapNameToOID("SHA1"), signedBytes);
                        }
                        catch (CryptographicException e)
                        {
                            Console.WriteLine(e.Message);
                        }
                    }
                    return success;
            }
    

    Hope my suggestion could be helpful.

    Best regards,

    Jack



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, January 10, 2019 7:44 AM
    Moderator
  • Thank you very much Jack.


    Finally I got this code, which signs from private.pem file, and verify it from public.pem file. Hopefully this would help anybody to use this type of signing in asp.net.

    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    using Org.BouncyCastle.Crypto;
    using Org.BouncyCastle.Crypto.Parameters;
    using Org.BouncyCastle.OpenSsl;
    using Org.BouncyCastle.Security;
    
    public class PemReader{
    
    private string Signature(string message)
            {
                string privateKeyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "private.pem");
    
                var privateRsa = RsaProviderFromPrivateKeyInPemFile(privateKeyPath);
    
                var signedData = privateRsa.SignData(Encoding.UTF8.GetBytes(message), CryptoConfig.MapNameToOID("SHA1"));
    
                return Convert.ToBase64String(signedData);
            }
    
    private bool Verify(string message, string signedData)
            {
                string publicKeyPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "public.pem");
    
                var publicRsa= RsaProviderFromPublicKeyInPemFile(publicKeyPath);
    
                var verifiedData = publicRsa.VerifyData(Encoding.UTF8.GetBytes(message), CryptoConfig.MapNameToOID("SHA1"), Convert.FromBase64String(signedData));
    
                return verifiedData;
            }
    
      public RSACryptoServiceProvider RsaProviderFromPrivateKeyInPemFile(string privateKeyPath)
            {
                using (TextReader privateKeyTextReader = new StringReader(File.ReadAllText(privateKeyPath)))
                {
                    PemReader pr = new PemReader(privateKeyTextReader);
                    AsymmetricCipherKeyPair keyPair = (AsymmetricCipherKeyPair)pr.ReadObject();
                    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)keyPair.Private);
    
                    RSACryptoServiceProvider csp = new RSACryptoServiceProvider(); 
                    csp.ImportParameters(rsaParams);
                    return csp;
                }
            }
    
    public RSACryptoServiceProvider RsaProviderFromPublicKeyInPemFile(string publicKeyPath)
            {
                using (TextReader privateKeyTextReader = new StringReader(File.ReadAllText(publicKeyPath)))
                {
                    PemReader pr = new PemReader(privateKeyTextReader);
                    AsymmetricKeyParameter publicKey = (AsymmetricKeyParameter)pr.ReadObject();
                    RSAParameters rsaParams = DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);
    
                    RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
                    csp.ImportParameters(rsaParams);
                    return csp;
                }
            }
    
    }
    
    
    
    

    • Marked as answer by Derderer Friday, January 11, 2019 8:28 AM
    Thursday, January 10, 2019 1:22 PM