.NET Framework 內建完整的加密服務提供者(CSP),無需自行實作演算法。本文整理 對稱加密 DES、雜湊 SHA1、非對稱加密 RSA 三種最常見演算法的標準庫用法,提供可直接複製的封裝方法,並說明金鑰管理、IV、填充模式等關鍵細節。
using System.Security.Cryptography;
using System.Text;
特性:金鑰 8 位元組 (64 位,含 8 位奇偶校驗)、區塊 8 位元組、速度快、適合大量資料。
private static readonly byte[] DefaultIV = { 0xEF, 0xAB, 0x56, 0x78, 0x90, 0x34, 0xCD, 0x12 };
/// DES 加密,回傳 Base64 字串
public static string EncryptDES(string plainText, string key)
{
try
{
byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
byte[] iv = DefaultIV;
byte[] input = Encoding.UTF8.GetBytes(plainText);
using (var des = DES.Create())
using (var ms = new MemoryStream())
using (var cs = new CryptoStream(ms, des.CreateEncryptor(keyBytes, iv), CryptoStreamMode.Write))
{
cs.Write(input, 0, input.Length);
cs.FlushFinalBlock();
return Convert.ToBase64String(ms.ToArray());
}
}
catch { return plainText; } // 或拋出自訂例外
}
/// DES 解密
public static string DecryptDES(string cipherText, string key)
{
try
{
byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
byte[] iv = DefaultIV;
byte[] input = Convert.FromBase64String(cipherText);
using (var des = DES.Create())
using (var ms = new MemoryStream())
using (var cs = new CryptoStream(ms, des.CreateDecryptor(keyBytes, iv), CryptoStreamMode.Write))
{
cs.Write(input, 0, input.Length);
cs.FlushFinalBlock();
return Encoding.UTF8.GetString(ms.ToArray());
}
}
catch { return cipherText; }
}
Aes.Create())。Rfc2898DeriveBytes (PBKDF2) 從密碼衍生,勿硬編碼。用途:檔案完整性驗證、密碼雜湊 (需加鹽)、數位簽名輸入。
public static string HashSHA1(string input)
{
using (var sha1 = SHA1.Create())
{
byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(input));
var sb = new StringBuilder(hash.Length * 2);
foreach (byte b in hash) sb.AppendFormat("{0:x2}", b);
return sb.ToString(); // 40 字元十六進位
}
}
注意:SHA1 碰撞攻擊已實用化,新專案請改用 SHA256 或 SHA512。
原理:公開金鑰加密、私鑰解密;金鑰長度建議 ≥ 2048 位。RSA 速度慢,實務採「混合加密」:RSA 加密隨機產生的 AES 金鑰,AES 加密實際資料。
public sealed class RsaCryptographer
{
private readonly RSACryptoServiceProvider _rsa = new(2048);
private readonly RC2CryptoServiceProvider _rc2 = new() { KeySize = 128 }; // 示範用 RC2,實務改 AES
// 匯出公開金鑰參數供他人加密
public RSAParameters ExportPublicKey() => _rsa.ExportParameters(false);
// 匯入他人公開金鑰
public void ImportPublicKey(RSAParameters pubKey) => _rsa.ImportParameters(pubKey);
// 加密:產生隨機 RC2 金鑰 -> RSA 加密 RC2 金鑰 -> RC2 加密資料
public (byte[] CipherData, byte[] EncryptedKey, byte[] IV) Encrypt(string plainText)
{
byte[] data = Encoding.Unicode.GetBytes(plainText);
_rc2.GenerateKey(); _rc2.GenerateIV();
return (
CipherData: Transform(data, _rc2.CreateEncryptor()),
EncryptedKey: _rsa.Encrypt(_rc2.Key, false), // false = PKCS#1 v1.5
IV: _rc2.IV
);
}
// 解密:RSA 解密 RC2 金鑰 -> RC2 解密資料
public string Decrypt(byte[] cipherData, byte[] encryptedKey, byte[] iv)
{
_rc2.IV = iv;
_rc2.Key = _rsa.Decrypt(encryptedKey, false);
byte[] plain = Transform(cipherData, _rc2.CreateDecryptor());
return Encoding.Unicode.GetString(plain);
}
private static byte[] Transform(byte[] input, ICryptoTransform transformer)
{
using (var ms = new MemoryStream())
using (var cs = new CryptoStream(ms, transformer, CryptoStreamMode.Write))
{
cs.Write(input, 0, input.Length);
cs.FlushFinalBlock();
return ms.ToArray();
}
}
}
// Alice 產生金鑰對
var alice = new RsaCryptographer();
var alicePub = alice.ExportPublicKey();
// Bob 取得 Alice 公開鑰加密訊息
var bob = new RsaCryptographer();
bob.ImportPublicKey(alicePub);
var (cipher, encKey, iv) = bob.Encrypt("Hello Alice!");
// Alice 用私鑰解密
string msg = alice.Decrypt(cipher, encKey, iv); // "Hello Alice!"
| 演算法 | 舊 API | 新建議 API | 說明 |
|---|---|---|---|
| 對稱加密 | DES, RijndaelManaged | Aes.GenerateKey(), Aes.EncryptCbc() | AES-GCM 提供認證加密 (AEAD) |
| 雜湊 | SHA1, MD5 | SHA256, SHA512 | SHA1/MD5 已棄用 |
| 非對稱 | RSACryptoServiceProvider | RSA.Create() + Encrypt/Decrypt(OAEP) | 支援 OAEP SHA-256、PSS 簽名 |
| 密碼衍生 | Rfc2898DeriveBytes | Rfc2898DeriveBytes (SHA256) | 迭代次數 ≥ 100,000 |
.NET 加密標準庫功能完備,核心在於正確選擇演算法、安全管理金鑰/IV、使用高層封裝 (CryptoStream) 避免手動處理區塊/填充。新專案請全面採用 AES-GCM、SHA256+、RSA-OAEP,並參考 Microsoft 官方加密模型指引。