Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read a PEM RSA private key from .NET

I've got an RSA private key in PEM format, is there a straight forward way to read that from .NET and instantiate an RSACryptoServiceProvider to decrypt data encrypted with the corresponding public key?

like image 550
Simone Avatar asked Oct 28 '08 15:10

Simone


People also ask

How do I read a PEM file?

Certificate Decoder A PEM encoded certificate is a block of encoded text that contains all of the certificate information and public key. Another simple way to view the information in a certificate on a Windows machine is to just double-click the certificate file.

What is PEM RSA private key?

PEM encoded RSA private key is a format that stores an RSA private key, for use with cryptographic systems such as SSL. A public key can be derived from the private key, and the public key may be associated with one or more certificate files.


2 Answers

Update 03/03/2021

.NET 5 now supports this out of the box.

To try the code snippet below, generate a keypair and encrypt some text at http://travistidwell.com/jsencrypt/demo/

var privateKey = @"-----BEGIN RSA PRIVATE KEY----- { the full PEM private key }  -----END RSA PRIVATE KEY-----";  var rsa = RSA.Create(); rsa.ImportFromPem(privateKey.ToCharArray());  var decryptedBytes = rsa.Decrypt(     Convert.FromBase64String("{ base64-encoded encrypted string }"),      RSAEncryptionPadding.Pkcs1 );  // this will print the original unencrypted string Console.WriteLine(Encoding.UTF8.GetString(decryptedBytes)); 

Original answer

I solved, thanks. In case anyone's interested, bouncycastle did the trick, just took me some time due to lack of knowledge from on my side and documentation. This is the code:

var bytesToDecrypt = Convert.FromBase64String("la0Cz.....D43g=="); // string to decrypt, base64 encoded   AsymmetricCipherKeyPair keyPair;    using (var reader = File.OpenText(@"c:\myprivatekey.pem")) // file containing RSA PKCS1 private key     keyPair = (AsymmetricCipherKeyPair) new PemReader(reader).ReadObject();    var decryptEngine = new Pkcs1Encoding(new RsaEngine()); decryptEngine.Init(false, keyPair.Private);    var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length));  
like image 107
Simone Avatar answered Oct 01 '22 20:10

Simone


With respect to easily importing the RSA private key, without using 3rd party code such as BouncyCastle, I think the answer is "No, not with a PEM of the private key alone."

However, as alluded to above by Simone, you can simply combine the PEM of the private key (*.key) and the certificate file using that key (*.crt) into a *.pfx file which can then be easily imported.

To generate the PFX file from the command line:

openssl pkcs12 -in a.crt -inkey a.key -export -out a.pfx 

Then use normally with the .NET certificate class such as:

using System.Security.Cryptography.X509Certificates;  X509Certificate2 combinedCertificate = new X509Certificate2(@"C:\path\to\file.pfx"); 

Now you can follow the example from MSDN for encrypting and decrypting via RSACryptoServiceProvider:

I left out that for decrypting you would need to import using the PFX password and the Exportable flag. (see: BouncyCastle RSAPrivateKey to .NET RSAPrivateKey)

X509KeyStorageFlags flags = X509KeyStorageFlags.Exportable; X509Certificate2 cert = new X509Certificate2("my.pfx", "somepass", flags);  RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey; RSAParameters rsaParam = rsa.ExportParameters(true);  
like image 40
SeventhPath Avatar answered Oct 01 '22 19:10

SeventhPath