views:

7908

answers:

4

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

+1  A: 

You might take a look at JavaScience's source for OpenSSLKey. (OpenSSLKey.cs)

There's code in there that does exactly what you want to do.

In fact, they have a lot of crypto source code available here.

SoloBold
Tried, doesn't work, and didn't take the time to go through the code yet, I'd hope there was a simpler solution.
Simone
Could you give details on what failed? I took a look at the code, and it seems like it should work. Perhaps you could even post the PEM-file? (If you have a non-sensitive one).
Rasmus Faber
+1  A: 

Check http://msdn.microsoft.com/en-us/library/dd203099.aspx

under Cryptography Application Block.

Don't know if you will get your answer, but it's worth a try.

Edit after Comment.

Ok then check this code.

using System.Security.Cryptography;


public static string DecryptEncryptedData(stringBase64EncryptedData, stringPathToPrivateKeyFile) { 
    X509Certificate2myCertificate; 
    try{ 
        myCertificate = newX509Certificate2(PathToPrivateKeyFile); 
    } catch{ 
        throw newCryptographicException("Unable to open key file."); 
    } 

    RSACryptoServiceProvider rsaObj; 
    if(myCertificate.HasPrivateKey) { 
         rsaObj = (RSACryptoServiceProvider)myCertificate.PrivateKey; 
    } else 
        throw newCryptographicException("Private key not contained within certificate."); 

    if(rsaObj == null) 
        returnString.Empty; 

    byte[] decryptedBytes; 
    try{ 
        decryptedBytes = rsaObj.Decrypt(Convert.FromBase64String(Base64EncryptedData), false); 
    } catch { 
        throw newCryptographicException("Unable to decrypt data."); 
    } 

    //    Check to make sure we decrpyted the string 
   if(decryptedBytes.Length == 0) 
        returnString.Empty; 
    else 
        returnSystem.Text.Encoding.UTF8.GetString(decryptedBytes); 
}
João Augusto
Nope, it doesn't support any asymmetric algorithms.
Simone
This code can't load a PEM rsa private key, it needs a certificate file based on that key, which can be generated, but I would like to avoid that step.
Simone
Ok, then tell me where do you have your private key?
João Augusto
In a text file in PEM format.
Simone
Ok, then check "Edit2"
João Augusto
If you read my reply to the previous answer you'll see that I already tried and it didn't work.
Simone
Didn't noticed, I removed the last part since it's equal to the first answer.
João Augusto
A: 

The stuff between the

-----BEGIN RSA PRIVATE KEY----

and

-----END RSA PRIVATE KEY-----

is the base64 encoding of a PKCS#8 PrivateKeyInfo (unless it says RSA ENCRYPTED PRIVATE KEY in which case it is a EncryptedPrivateKeyInfo).

It is not that hard to decode manually, but otherwise your best bet is to P/Invoke to CryptImportPKCS8.

Rasmus Faber
+3  A: 

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));
Simone