DidiSoft OpenSSL Library for .NET offers RSA cryptography methods located in the DidiSoft.OpenSsl.OpenSslRsa class, designed to provide compatibility with the classic OpenSSL tool openssl rsautl , openssl genrsa and openssl rsa commands.
Table of contents
- RSA keys
- RSA encryption
- RSA decryption
- RSA digital signatures
- RSA signature verification
- RSA_private_encrypt
- RSA_public_decrypt
RSA encryption
RSA encryption is done with the OpenSSL command openssl rsautl -encrypt. Here we are going to shown how to accomplish the same result with .NET. The public RSA key provided as encryption parameter can be in PEM, DER format or as X.509 certificate.
C# example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using System; using DidiSoft.OpenSsl.Rsa; class RsaEncryptDemo { public static void Main(string[] args) { OpenSslRsa rsa = new OpenSslRsa(); bool base64Encode = true; OpenSslRsa.Padding padding = OpenSslRsa.Padding.Pkcs1; string encryptedString = rsa.EncryptString("Hello world", @"Data\public_key.pem", base64Encode, padding); } } |
VB.NET example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | Imports System Imports DidiSoft.OpenSsl.Rsa Class RsaEncryptDemo Public Shared Sub Main(args As String()) Dim rsa As New OpenSslRsa() Dim base64Encode As Boolean = True Dim padding As OpenSslRsa.Padding = OpenSslRsa.Padding.Pkcs1 Dim encryptedString As String = _ rsa.EncryptString("Hello world", "Data\public_key.pem", base64Encode, padding) End Sub End Class |
RSA decryption
Private key
In order to decrypt RSA encrypted data, we need the private RSA key corresponding to the public key used to encrypt the input data. If the private key is protected with a password it shall also be specified.
Base-64 or hexadecimal format
When decrypting data the OpenSslRsa.Decrypt methods auto-detect if the data is base-64 encoded and will automatically decode it before decrypting.
Padding
The padding of the encrypted data if different from PKCS#1 shall also be specified explicitly.
C# example
1 2 3 4 5 6 7 8 9 10 11 12 13 | using System; using DidiSoft.OpenSsl; class RsaDecryptDemo { public static void Main(string[] args) { OpenSslRsa rsa = new OpenSslRsa(); string encryptedString = rsa.EncryptString("Hello world", @"Data\public_key.pem"); string decryptedString = rsa.DecryptString(encryptedString, @"Data\private_key.pem"); } } |
VB.NET example
1 2 3 4 5 6 7 8 9 10 11 | Imports System Imports DidiSoft.OpenSsl Class RsaDecryptDemo Public Shared Sub Main(args As String()) Dim rsa As New OpenSslRsa() Dim encryptedString As String = rsa.EncryptString("Hello world", "Data\public_key.pem") Dim decryptedString As String = rsa.DecryptString(encryptedString, "Data\private_key.pem") End SubEnd Class |
RSA digital signatures
In order to create an RSA signature we need a private RSA key (if password-protected, the password must be specified as well). Another optional parameter is the Hash digest algorithm for the signature (later we are gonna need it again in order to verify the signature).
C# example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | using System; using DidiSoft.OpenSsl; class RsaSignDemo { public static void Main(string[] args) { OpenSslRsa rsa = new OpenSslRsa(); bool base64Encode = true; // create the signature as Base-64 encoded string string signatureString = rsa.SignString("Hello world", @"Data\private_key.pem", HashAlgorithm.Sha1, base64Encode); // or we may need the raw signature bytes byte[] signatureBytes = rsa.SignStringRaw("Hello world", @"Data\private_key.pem", HashAlgorithm.Sha1); } } |
VB.NET example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Imports System Imports DidiSoft.OpenSsl Class RsaSignDemo Public Shared Sub Main(args As String()) Dim rsa As New OpenSslRsa() Dim base64Encode As Boolean = True ' create the signature as Base-64 encoded string Dim signatureString As String = rsa.SignString("Hello world", "Data\private_key.pem", HashAlgorithm.Sha1, base64Encode) ' or we may need the raw signature bytes Dim signatureBytes As Byte() = rsa.SignStringRaw("Hello world", "Data\private_key.pem", HashAlgorithm.Sha1) End Sub End Class |
Verify signatures
Signature verification is the opposite of the signing process. It takes the correct public key and uses it to calculate again the signature hash and compare it with the provided signature.
Unfortunately, the plain RSA signatures don’t make any difference between tempered signature and wrong public key, so both cases are considered a signature verification failure.
C# example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | using System; using DidiSoft.OpenSsl; class RsaSignDemo { public static void Main(string[] args) { OpenSslRsa rsa = new OpenSslRsa(); string signatureString = rsa.SignString("Hello world", @"Data\private_key.pem", HashAlgorithm.Sha1); bool signatureOk = rsa.VerifyString("Hello world", signatureString, @"Data\public_key.pem", HashAlgorithm.Sha1); } } |
VB.NET example
1 2 3 4 5 6 7 8 9 10 11 12 | Imports System Imports DidiSoft.OpenSsl Class RsaSignDemo Public Shared Sub Main(args As String()) Dim rsa As New OpenSslRsa() Dim signatureString As String = rsa.SignString("Hello world", "Data\private_key.pem", HashAlgorithm.Sha1) Dim signatureOk As Boolean = rsa.VerifyString("Hello world", signatureString, "Data\public_key.pem", HashAlgorithm.Sha1) End Sub End Class |
RSA_private_encrypt
The method OpenSslRsa.PrivateEncrypt is equivalent of RSA_private_encrypt. It is a low-level signature creation routine that expects the input tu be already hashed (although this is not mandatory). In the example below we are going to create RSA signature this way:
DidiSoft.OpenSsl.Rsa.OpenSslRsa rsa = new DidiSoft.OpenSsl.Rsa.OpenSslRsa(); byte[] data = new byte[] { 10, 20, 21, 32, 22, 45, 67, 93, 76, 90, 91, 03, 56 }; byte[] signed = rsa.PrivateEncrypt(data, File.ReadAllBytes(Keys.privKeyLocation), OpenSslRsa.Padding.None); |
RSA_public_decrypt
RSA_public_decrypt extracts data created with RSA_private_encrypt. It is a low-level version of Verifying a signature.
In the example below in addition to invoking OpenSslRsa.PublicDecrypt we are going to create the RSA public key by specifying the modulus and exponent explicitly (instead of loading the key from a file):
DidiSoft.OpenSsl.Rsa.OpenSslRsa rsa = new DidiSoft.OpenSsl.Rsa.OpenSslRsa(); // load data cerated with RSA_private_encrypt/PrivateEncrypt byte[] privateEncryptedData = ...; // create public key on the fly string pubModulusHex = "..."; long pubExponentLong = 65537; DidiSoft.OpenSsl.Rsa.RsaPublicKey pubKey = new DidiSoft.OpenSsl.Rsa.RsaPublicKey(pubModulusHex, pubExponentLong); byte[] decrypted = rsa.PublicDecrypt(privateEncryptedData, pubKey, OpenSslRsa.Padding.None); |
Summary
This tutorial illustrated how to perform OpenSSL compatible RSA cryptographic operations in .NET Framework.