balint balint - 1 month ago 23
C# Question

Sign data with MD5WithRSA from .Pem/.Pkcs8 keyfile in C#

I've got the following code sample in Java, and I need to re-enact it in C#:

PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(pkcs8PrivateKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privKey = keyFactory.generatePrivate(privKeySpec);
Signature sign = Signature.getInstance("MD5withRSA");

sign.initSign(privKey);
sign.update(data);
byte[] signature = sign.sign();


Is it possible with the standard .Net Crypto API, or should I use BouncyCastle?
Thanks,

b.

Answer

I am running into a very similar problem trying to create a native C# tool for packing Chrome extensions (using SHA1, not MD5, but that's not a big difference). I believe I have tried literally every possible solution for .Net: System.Security.Cryptography, BouncyCastle, OpenSSL.Net and Chilkat RSA.

The best solution is probably Chilkat; their interface is the cleanest and most straightforward, it's well-supported and well-documented, and there are a million examples. For instance, here's some code using their library that does something very close to what you want: http://www.example-code.com/csharp/rsa_signPkcs8.asp. However, it's not free (though $150 is not unreasonable, seeing as I have burned 2 days trying to figure this out, and I make a bit more than $75 a day!).

As a free alternative, JavaScience offers up a number of crypto utilities in source form for multiple languages (including C#/.Net) at http://www.jensign.com/JavaScience/cryptoutils/index.html. The one that's most salient to what you are trying to do is opensslkey (http://www.jensign.com/opensslkey/index.html), which will let you generate a RSACryptoServiceProvider from a .pem file. You can then use that provider to sign your code:

        string pemContents = new StreamReader("pkcs8privatekey.pem").ReadToEnd();
        var der = opensslkey.DecodePkcs8PrivateKey(pemContents);
        RSACryptoServiceProvider rsa = opensslkey.DecodePrivateKeyInfo(der);

        signature = rsa.SignData(data, new MD5CryptoServiceProvider());
Comments