2012年4月4日 星期三

在C#中使用RSA加解密

RSA是非對稱式加密,金鑰分為公鑰和私鑰兩種,詳情可參考RSA加密演算法。一般來說,公鑰會存成.crt,並且撒出去讓大家知道,而私鑰則是存成.pfx,由自己保管,同時加上密碼來保護

在使用這兩把鑰匙的時候,需先用X509Certificate2物件將其讀出

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;
}

有時會需要將鑰匙存入資料庫,可以採用XML的格式,RSACryptoServiceProvider有提供很方便的存讀XML字串的函式。

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;
}

注意,不論是公鑰或私鑰皆可以取得一個RSACryptoServiceProvider的物件。實際上在使用RSA加解密演算法時,有時會需要用到私鑰加密,公鑰解密(數位簽章,由自己發給別人,證實該資訊是由我發出),有時則是公鑰加密,私鑰解密(確認只有自己才可以看的到的文件),所以這兩把鑰匙的用法是相同的。

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);
}

在這邊使用哪種padding演算法都可以,但是記得加解密的時候需要用同樣的演算法即可。另外,因為加解密時都是採用byte陣列做為原始資料,所以如果原本是string物件的話,可以透過Convert.FromBase64String及Encoding.UTF8.GetString互為轉換。

--
參考資料
RSACryptoServiceProvider Class
Optimal asymmetric encryption padding

沒有留言:

張貼留言