RSA 是資訊安全領域最經典的非對稱加密演算法,廣泛應用於金鑰交換、數位簽章、資料加密等場景。.NET Framework 內建 System.Security.Cryptography.RSACryptoServiceProvider 提供完整的 RSA 實作,開發者無需自行實作複雜的數學運算即可安全使用。本文系統說明金鑰產生、加解密、XML 序列化儲存等核心操作,並附上可直接套用的程式碼範例。
| 類別/結構 | 用途 |
|---|---|
RSACryptoServiceProvider | RSA 實作主類別,提供加密、解密、簽章、驗證、匯入匯出參數等方法 |
RSAParameters | 儲存 RSA 八大參數:Modulus、Exponent、P、Q、DP、DQ、InverseQ、D |
金鑰對應關係:
Modulus + Exponent(加密、驗簽)using (var rsa = new RSACryptoServiceProvider(2048)) // 2048 bits 建議最小長度
{
// 公鑰參數
RSAParameters publicParams = rsa.ExportParameters(false);
// 私鑰參數(含公鑰參數)
RSAParameters privateParams = rsa.ExportParameters(true);
}
/// 公鑰加密
public byte[] EncryptWithPublicKey(byte[] data, RSAParameters publicKey)
{
using (var rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(publicKey);
// 第二個參數 false = PKCS#1 v1.5 padding;true = OAEP padding (建議)
return rsa.Encrypt(data, false);
}
}
/// 私鑰解密
public byte[] DecryptWithPrivateKey(byte[] encryptedData, RSAParameters privateKey)
{
using (var rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(privateKey);
return rsa.Decrypt(encryptedData, false);
}
}
注意:RSA 直接加密的資料長度受限於金鑰長度(2048 bits 约可加密 245 bytes)。實務上通常採用「混合加密」:用 AES 加密大量資料,再用 RSA 加密 AES 金鑰。
using (var rsa = new RSACryptoServiceProvider(2048))
{
// 儲存私鑰 (含公鑰)
string privateKeyXml = rsa.ToXmlString(true);
System.IO.File.WriteAllText(@"D:\Keys\PrivateKey.xml", privateKeyXml);
// 僅儲存公鑰
string publicKeyXml = rsa.ToXmlString(false);
System.IO.File.WriteAllText(@"D:\Keys\PublicKey.xml", publicKeyXml);
}
// 載入公鑰
using (var rsaPub = new RSACryptoServiceProvider())
{
string publicKeyXml = System.IO.File.ReadAllText(@"D:\Keys\PublicKey.xml");
rsaPub.FromXmlString(publicKeyXml);
// 可進行加密、驗簽
}
// 載入私鑰
using (var rsaPri = new RSACryptoServiceProvider())
{
string privateKeyXml = System.IO.File.ReadAllText(@"D:\Keys\PrivateKey.xml");
rsaPri.FromXmlString(privateKeyXml);
// 可進行解密、簽章
}
Encrypt(data, true)) 而非 PKCS#1 v1.5,抵禦選擇密文攻擊。CspParameters.KeyContainerName)。System.Security.Cryptography.RSA 抽象基類與 RSA.Create() 工廠模式,支援跨平台與硬體加速。// 1. 產生隨機 AES 金鑰
using (var aes = Aes.Create())
{
aes.KeySize = 256;
aes.GenerateKey();
aes.GenerateIV();
byte[] aesKey = aes.Key;
byte[] aesIV = aes.IV;
// 2. 用 RSA 公鑰加密 AES 金鑰
byte[] encryptedAesKey = EncryptWithPublicKey(aesKey, publicParams);
// 3. 用 AES 加密實際資料
byte[] encryptedData;
using (var encryptor = aes.CreateEncryptor())
using (var ms = new MemoryStream())
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
cs.Write(plainData, 0, plainData.Length);
cs.FlushFinalBlock();
encryptedData = ms.ToArray();
}
// 4. 傳輸:encryptedAesKey + aesIV + encryptedData
// 接收端:私鑰解密 AES Key → AES 解密資料
}