RSA Encryption In C# using Microsoft Cryptography Library
Sample class library implementing RSA encryption using Microsoft’s Cryptography Library
Introduction
RSA (Rivest–Shamir–Adleman) is a public-key cryptosystem. In such a cryptosystem, a pair of keys is used often called private and public key pair.
Public key cryptosystems are used for 2 major use cases
- Encryption
- Verification
Focus of this article is encryption. With a public key cryptosystem, private key is always kept secure by the owner and public key is publically accessible. Encryption is always done with a public key, this ensures that only the owner of private key can access the data unencrypted and will remain private between the encrytor and owner of private key.
RSA In .NET Core
RSA represents the abstract base class from which all implementations of RSA mush inherit. .NET provides following implementations of RSA at the time of writing.
- RSACng
- RSACryptoServiceProvider - used on windows
- RSAOpenSsl - used on linux/osx if openssl is installed
RSA abstract base class also provides static methods to create an instance of an implementation
- Create() - creates an instance based on platform
Implementation
Lets start using RSA in our code. We would need to include System.Security.Cryptography
namespace.
using System.Security.Cryptography;
Key Generation
GenerateKeyPair method creates a new instance of RSA, sets desired key size and export parameters and convert to RsaPrivateKeyParameters
/RsaPublicKeyParameters
helper classes and export those as json strings.
Encryption
Encrypt method accepts a string and RsaPublicKeyParameters
serialized as json, encrypts string with key using OaepSHA256
padding and returns a base64 encoded encrypted string.
We will start by creating an instance of RSA and importing key.
var rsa = RSA.Create();
var rsaParameters = JsonConvert.DeserializeObject<RsaPublicKeyParameters>(publicKeyJson).ToRSAParameters();
rsa.ImportParameters(rsaParameters);
Call Encrypt
method on rsa
instance to encrypt data.
var encryptedData = rsa.Encrypt(dataToEncrypt, RSAEncryptionPadding.OaepSHA256);
We then convert encrypted data to base64 string and return to caller.
Complete code for the method is below
public string Encrypt(string plainText, string publicKeyJson)
{
using (var rsa = RSA.Create())
{
var rsaParameters = JsonConvert.DeserializeObject<RsaPublicKeyParameters>(publicKeyJson).ToRSAParameters();
rsa.ImportParameters(rsaParameters);
var dataToEncrypt = Encoding.UTF8.GetBytes(plainText);
var encryptedData = rsa.Encrypt(dataToEncrypt, RSAEncryptionPadding.OaepSHA256);
return Convert.ToBase64String(encryptedData);
}
}
Decryption
Decrypt method works in conjunction with Encrypt method above, it accepts base64 encoded string and RsaPrivateKeyParameters
serialized as json. It imports key, performs decryption and returns plain text.
We will start by creating an instance of RSA and importing key.
var rsa = RSA.Create();
var rsaParameters = JsonConvert.DeserializeObject<RsaPrivateKeyParameters>(privateKeyJson).ToRSAParameters();
rsa.ImportParameters(rsaParameters);
Call Decrypt
method on rsa
instance to decrypt data.
var decryptedData = rsa.Decrypt(dataToDecrypt, RSAEncryptionPadding.OaepSHA256);
We then convert decrypted data to string and return to caller.
Complete code for the method is below
public string Decrypt(string encryptedData, string privateKeyJson)
{
using (var rsa = RSA.Create())
{
var rsaParameters = JsonConvert.DeserializeObject<RsaPrivateKeyParameters>(privateKeyJson).ToRSAParameters();
rsa.ImportParameters(rsaParameters);
var dataToDecrypt = Convert.FromBase64String(encryptedData);
var decryptedData = rsa.Decrypt(dataToDecrypt, RSAEncryptionPadding.OaepSHA256);
return Encoding.UTF8.GetString(decryptedData);
}
}
Complete code for the wrapper class that implements encryption and decryption using RSA can be found at RsaCrypto.cs. Unit tests for the wrapper class can be found at RsaCryptoTests.cs. Complete project as class library along with tests is at CryptoSandbox.
References
https://en.wikipedia.org/wiki/RSA_(cryptosystem) https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rsa?view=netcore-2.2
Leave a Comment
Your email address will not be published. Required fields are marked *