2 minute read

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

  1. Encryption
  2. 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 *

Loading...