RSA and DSA Asymmetric Encryption Basics
Asymmetric encryption requires a public and private key pair. The public key is used to encrypt data, and the private key is used to decrypt data that has been encrypted with the paired public key. The examples below refer to RSA, but the process is identical for DSA. Both the RSA and DSA components are included in the IPWorks Encrypt toolkit.
Creating or Setting the Private and Public Keys
To create or load keys with the component, you can either use the Certificate type or the RSAKey type.
Loading Keys via Certificates
The easiest way to set public and private keys is to use certificates. For encryption, the RecipientCert property should be set to the certificate which contains the appropriate public key (your partner's public certificate). For decryption, the Certificate property should be set to the certificate which contains the paired private key (your private key). For instance:
Rsa rsa = new Rsa();
rsa.RecipientCert = new Certificate(CertStoreTypes.cstPublicKeyFile, "C:\\Partner.cer", "", "*");
rsa.Certificate = new Certificate(CertStoreTypes.cstPFXFile, "C:\\MyCert.pfx", "test", "*");
Creating or Loading Keys via RSAKey
If you're creating the keys in code, or if you want more advanced control over the mathematical parameters of the keys, you can use the Key and RecipientKey properties instead of certificates. These properties are both of the RSAKey type and provide access to key data in string format.
Creating Keys in Code
After calling CreateKey(), the Key and RecipientKey properties will be populated. The PrivateKey field of the Key property and the PublicKey field of the RecipientKey property will contain a string-encoded representation of the mathematical parameters of the two keys. You can use these fields to easily store the keys in a database or with string variables in code.
Here's an example of creating a public and private key pair in code, and storing the keys as strings for later use:
Rsa rsa = new Rsa();
rsa.CreateKey();
String privKeyData = rsa.Key.PrivateKey;
String pubKeyData = rsa.Key.PublicKey;
To use these strings later, you would simply set the PrivateKey field of the Key property and the PubliKey of the RecipientKey property, like this:
rsa.Key = new RSAKey();
rsa.Key.PrivateKey = privKeyData;
rsa.RecipientKey = new RSAKey();
rsa.RecipientKey.PublicKey = pubKeyData;
Using the Mathematical Parameters of the Keys
The RSAKey type can be instantiated with the mathematical parameters of public and private keys, and also provides access to these parameters.
A public key consists of a modulus and an exponent, available through the Modulus and Exponent fields.
A private key can be represented in one of two ways, both mathematically equivalent. The first format consists of: Modulus, P, Q, DP, and DQ. The second format is simpler, consisting of just Modulus and D, but has decreased performance when decrypting and signing.
If you are using external cryptography tools which generate these mathematical parameters, you can instantiate RSAKey by passing these parameters to the constructor, and use them with the RSA component by setting the Key and RecipientKey properties appropriately.
Encrypting and Decrypting
The RSA component can encrypt and decrypt data from a file, string, or byte array. Simply set the InputFile, InputMessage, or InputMessageB property, respectively. Once the RecipientCert (or RecipientKey) and input is set, simply call the Encrypt method. Below is an example of encrypting a message:
Rsa rsa = new Rsa();
Certificate cert = new Certificate(CertStoreTypes.cstPFXFile, certificateFilePath, "test", "*");
rsa.RecipientCert = cert;
rsa.InputMessage = "Encrypt me please!";
rsa.Encrypt();
String encryptedMessage = rsa.OutputMessage;
Decrypting
An encrypted message can only be decrypted by the private key that is paired with the public key that encrypted it. To decrypt, set the Certificate (or Key) property to the appropriate private key, set the input to the encrypted data, and call the Decrypt method. Below is an example of decrypting a message:
Rsa rsa = new Rsa();
Certificate cert = new Certificate(CertStoreTypes.cstPFXFile, certificateFilePath, "test", "*");
rsa.Certificate = cert;
rsa.InputMessage = encryptedMessage;
rsa.Decrypt();
Console.WriteLine(rsa.OutputMessage);
Putting it Together
The following sample application creates a public/private key pair, then uses them to encrypt and decrypt a simple message.
//create public/private key pair
Rsa rsa = new Rsa();
rsa.CreateKey();
string privKeyData = rsa.Key.PrivateKey;
string pubKeyData = rsa.Key.PublicKey;
rsa.Reset();
//encrypt with public key
rsa.InputMessage = "Hello World!";
rsa.RecipientKey = new RSAKey();
rsa.RecipientKey.PublicKey = pubKeyData;
rsa.Encrypt();
string encryptedMessage = rsa.OutputMessage;
rsa.Reset();
//decrypt with private key
rsa.InputMessage = encryptedMessage;
rsa.Key = new RSAKey();
rsa.Key.PrivateKey = privKeyData;
rsa.Decrypt();
Console.WriteLine(rsa.OutputMessage);
We appreciate your feedback. If you have any questions, comments, or suggestions about this article please contact our support team at kb@nsoftware.com.