I'm trying to encrypt and decrypt some data with RSA. I've looked up teh RSA
class but I'm only seeing the abstract class https://msdn.microsoft.com/en-us/library/system.security.cryptography.rsa(v=vs.110).aspx
I've read that the RSA class in DNX5 is different from the one in .net 4.6.1 Is that a different one than what I'm seeing? If so where can I find the documentation to use that one? It also appears that RSACryptoServiceProvider
is not working in .net core and I only have access to the RSA
abstract class.
The problem with RSA is that as these keys get longer, the increase in security isn't commensurate to the increase in computational power it takes to use them. It's just not sustainable. The CAB Forum just mandated that keys used for signing software must now be at least 3072-bit in length if you're using RSA.
Key generation. The keys for the RSA algorithm are generated in the following way: Choose two distinct prime numbers p and q. For security purposes, the integers p and q should be chosen at random and should be similar in magnitude but differ in length by a few digits to make factoring harder.
You should avoid using RSACryptoServiceProvider
if you can. It only works on Windows (and it's the less good RSA implementation on Windows). Stick to the RSA
base class, and create new instances via RSA.Create()
using (RSA rsa = RSA.Create()) { rsa.KeySize = desiredKeySizeInBits; // when the key next gets used it will be created at that keysize. DoStuffWithThePrivateKey(rsa); }
Unfortunately, the default for RSA.Create() on .NET Framework is RSACryptoServiceProvider, which doesn't respect set_KeySize. So if you need ephemeral keys you'll need to use different code on .NET Framework vs .NET Core:
using (RSA rsa = new RSACng()) { rsa.KeySize = desiredKeySizeInBits; DoStuffWithThePrivateKey(rsa); }
Or, if you need to support versions earlier than 4.6 (where RSACng didn't exist) / 4.6.2 (where most of the .NET Framework worked happily with RSACng objects instead of RSACryptoServiceProvider objects) you can continue to use the older implementation:
using (RSA rsa = new RSACryptoServiceProvider(desiredKeySizeInBits)) { // Since before net46 the Encrypt/Decrypt, SignData/VerifyData, SignHash/VerifyHash // methods were not defined at the RSA base class, you might need to keep this strongly // typed as RSACryptoServiceProvider. DoStuffWithThePrivateKey(rsa); }
Even though RSACng, in general, is easier to work with than RSACryptoServiceProvider, RSACryptoServiceProvider should work fine in this context, so RSA.Create() is good on all platforms:
using (RSA rsa = RSA.Create()) { rsa.ImportParameters(rsaParameters); DoStuffWithWhateverKindOfKeyYouImported(rsa); }
using (RSA rsa = cert.GetRSAPublicKey()) { DoStuffWithThePublicKey(rsa); }
or
using (RSA rsa = cert.GetRSAPrivateKey()) { DoStuffWithThePrivateKey(rsa); }
// Do NOT put this in a using block, since the object is shared by all callers: RSA rsaPrivate = (RSA)cert.PrivateKey; DoStuffWithThePrivateKey(rsaPrivate); // Do NOT put this in a using block, since the object is shared by all callers: RSA rsaPublicOnly = (RSA)cert.PublicKey.Key; DoStuffWithThePublicKey(rsaPublic);
I was going to include some samples about RSACryptoServiceProvider (WinXP+/CAPI) and RSACng (Win7+/CNG) creating/opening named keys, but that's not a very common scenario in .NET; and it certainly isn't portable (portability to other OSes being one of the more compelling arguments for .NET Core).
For .NET Core 1.0 and 1.1, you get access to the RSA base class from the System.Security.Cryptography.Algorithms
package. In .NET Core 2.0 it will be included in the netstandard
package reference.
If you need to do complex interop with the OS you can reference System.Security.Cryptography.Cng
(Windows CNG), System.Security.Cryptography.Csp
(Windows CAPI/CryptoServiceProvider), or System.Security.Cryptography.OpenSsl
(Linux OpenSSL, macOS OpenSSL) and get access to the interop-enabled classes (RSACng, RSACryptoServiceProvider, RSAOpenSsl). But, really, you shouldn't do that.
You will need to use the dotnetcore library instead. Add the System.Security.Cryptography.Algorithms
Nuget package to your project. You can find it here: System.Security.Cryptography.Algorithms
It provides all the common Algorithms for your project.
Here is the RSACryptoServiceProvider class that you would use for the Encrypt() and Decrypt() methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With