Wednesday, April 4, 2012

Use RSA in C#

RSA is one of the asymmetric encryption algorithm. There are two keys, public and private, in this algorithm. Detail is reference to RSA. In general, the public key is saved as a .crt file and the private key is saved as a .pfx file with password.

To use these two keys, you need to load them by an X509Certificate2 object.

using System.Security.Cryptography.X509Certificates;

RSACryptoServiceProvider LoadPublicKeyFromFile(
string publicKeyFile)
{
///load public key from .crt
X509Certificate2 pubKey =
new X509Certificate2(publicKeyFile);

return (RSACryptoServiceProvider)pubKey.PublicKey.Key;
}

RSACryptoServiceProvider LoadPrivateKeyFromFile(
string privateKeyFile, string password)
{
///load private key from .pfx with password
X509Certificate2 priKey =
new X509Certificate2(privateKeyFile, password);

return (RSACryptoServiceProvider)priKey.PrivateKey;
}

Sometimes, you might need to save the keys into a database. RSACryptoServiceProvider provide simple functions to let you convert it to/from an xml string.

string ToXmlString(RSACryptoServiceProvider key)
{
/// true for private key, false for public key
return key.ToXmlString(true);
}

RSACryptoServiceProvider FromXmlString(string xmlString)
{
RSACryptoServiceProvider key =
new RSACryptoServiceProvider();
key.FromXmlString(xmlString);

return key;
}

Remember, you can get a RSACryptoServiceProvider object whenever you load a public or a private key. Sometimes you might need to use the private key to encrypt a message as a signature and others can use the public key to decrypt and verify if the signature is right from you. And sometimes you might need to use the public key to encrypt a message so that only the private key owner can decrypt it. The usages for both these keys are the same.

byte[] Encrypt(byte[] rawData, RSACryptoServiceProvider key)
{
/// encrypt without OAEP, but PKCS#1 v1.5 padding
return key.Encrypt(rawData, false);
}

byte[] Decrypt(byte[] encData, RSACryptoServiceProvider key)
{
/// decrypt without OAEP, but PKCS#1 v1.5 padding
return key.Decrypt(rawData, false);
}

You can use either padding algorithm, but remember to use the same algorithm in both encryption and decryption. Besides, since the sources for both encryption and decryption are byte arrays. You might need to use Convert.FromBase64String and Encoding.UTF8.GetString to convert strings to/from byte arrays.

--
Reference
RSACryptoServiceProvider Class
Optimal asymmetric encryption padding

No comments:

Post a Comment