首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET 加密解密完全指南:對稱、非對稱、雜湊與最佳實務

     編輯:ASP.NET 基礎

前言:資料安全的三大支柱

在 ASP.NET 應用中,資料保護主要仰賴三類密碼學原語:對稱加密(效能高、適合大量資料)、非對稱加密(金鑰管理彈性、適合金鑰交換與數位簽章)、雜湊函數(單向、驗證完整性)。.NET Framework 在 System.Security.Cryptography 命名空間提供完整實作,本文系統梳理演算法選型、程式碼範例與落地陷阱。

一、演算法選型速查表

類別演算法特性推薦場景
對稱加密AES (Rijndael)區塊 128-bit,金鑰 128/192/256-bit,速度快、安全性高現代應用首選,資料庫欄位加密、API Token 加密
3DES三重 DES,相容舊系統,速度較慢舊系統遷移過渡期
DES56-bit 金鑰,已不安全嚴禁新專案使用
RC2/RC4串流加密,RC4 已知弱點不推薦
Blowfish/Twofish非標準,需第三方庫特殊相容需求
非對稱加密RSA金鑰 1024~4096-bit,加密慢、簽章驗證快金鑰交換、數位簽章、JWT 簽名
DSA/ECDSA僅簽章,ECDSA 金鑰更短效能更好區塊鏈、憑證簽章
ECC橢圓曲線,同等安全性金鑰極短行動裝置、物聯網
雜湊/完整性SHA-256/384/512SHA-2 家族,目前標準密碼雜湊(配合 Salt)、檔案完整性、區塊鏈
HMAC-SHA256帶金鑰雜湊,防範長度擴展攻擊API 簽名驗證、Token 完整性
MD5/SHA1已知碰撞弱點嚴禁安全用途,僅限非安全校驗(如快取 Key)
BCrypt/PBKDF2/Argon2慢速雜湊,專為密碼設計儲存使用者密碼唯一正解

二、.NET 核心類別對照

  • 對稱:AesManaged、TripleDESCryptoServiceProvider
  • 非對稱:RSACryptoServiceProvider、DSACryptoServiceProvider、ECDsaCng (.NET Core 3.0+)
  • 雜湊:SHA256Managed、HMACSHA256、MD5CryptoServiceProvider(僅相容)
  • 密碼雜湊:Rfc2898DeriveBytes (PBKDF2)、ASP.NET Core 內建 IPasswordHasher<TUser> (BCrypt/PBKDF2)
  • 隨機數:RandomNumberGenerator (CSPRNG),嚴禁 使用 System.Random

三、實戰程式碼範例

1. AES-GCM 認證加密(.NET Core 3.0+ 推薦)

public static (byte[] ciphertext, byte[] nonce, byte[] tag) EncryptAesGcm(byte[] plaintext, byte[] key) {
    using var aes = new AesGcm(key);
    var nonce = RandomNumberGenerator.GetBytes(12); // 96-bit nonce
    var tag = new byte[16];
    var ciphertext = new byte[plaintext.Length];
    aes.Encrypt(nonce, plaintext, ciphertext, tag);
    return (ciphertext, nonce, tag);
}

public static byte[] DecryptAesGcm(byte[] ciphertext, byte[] nonce, byte[] tag, byte[] key) {
    using var aes = new AesGcm(key);
    var plaintext = new byte[ciphertext.Length];
    aes.Decrypt(nonce, ciphertext, tag, plaintext);
    return plaintext;
}

2. RSA 非對稱加解密(金鑰交換場景)

// 加密(公開金鑰)
public static byte[] RsaEncrypt(byte[] data, RSA publicKey) {
    return publicKey.Encrypt(data, RSAEncryptionPadding.OaepSHA256);
}

// 解密(私有金鑰)
public static byte[] RsaDecrypt(byte[] ciphertext, RSA privateKey) {
    return privateKey.Decrypt(ciphertext, RSAEncryptionPadding.OaepSHA256);
}

// 簽章/驗簽
public static byte[] RsaSign(byte[] data, RSA privateKey) {
    return privateKey.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}
public static bool RsaVerify(byte[] data, byte[] signature, RSA publicKey) {
    return publicKey.VerifyData(data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
}

3. 密碼雜湊:PBKDF2 (Rfc2898DeriveBytes) 與 BCrypt

// PBKDF2 範例(.NET Framework 內建)
public static (string hash, string salt) HashPasswordPbkdf2(string password, int iterations = 100_000) {
    var salt = RandomNumberGenerator.GetBytes(16);
    using var pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations, HashAlgorithmName.SHA256);
    var hash = pbkdf2.GetBytes(32);
    return (Convert.ToBase64String(hash), Convert.ToBase64String(salt));
}

public static bool VerifyPasswordPbkdf2(string password, string hashB64, string saltB64, int iterations = 100_000) {
    var hash = Convert.FromBase64String(hashB64);
    var salt = Convert.FromBase64String(saltB64);
    using var pbkdf2 = new Rfc2898DeriveBytes(password, salt, iterations, HashAlgorithmName.SHA256);
    var computed = pbkdf2.GetBytes(32);
    return CryptographicOperations.FixedTimeEquals(hash, computed);
}

// ASP.NET Core 專案直接使用內建服務
// services.AddIdentityCore<User>().AddPasswordHasher<PasswordHasher<User>>();
// var hasher = new PasswordHasher<User>();
// var hash = hasher.HashPassword(user, password);
// var result = hasher.VerifyHashedPassword(user, hash, password);

4. QueryString 加密傳遞(Base64 + URL Encode)

// 加密端
string encrypted = Convert.ToBase64String(Encoding.UTF8.GetBytes("sensitive_id=123"));
string urlSafe = HttpUtility.UrlEncode(encrypted); // 將 + / = 轉義
Response.Redirect($"Target.aspx?token={urlSafe}");

// 解密端
string token = HttpUtility.UrlDecode(Request.QueryString["token"]);
string decrypted = Encoding.UTF8.GetString(Convert.FromBase64String(token));

四、關鍵落地陷阱與防禦清單

  1. 金鑰管理:勿硬編碼金鑰,使用 Azure Key Vault / AWS KMS / HashiCorp Vault,或至少存於環境變數 / appsettings.json(生產環境加密)。
  2. IV/Nonce 唯一性:同一金鑰下 Nonce 絕不可重複(AES-GCM 重複會洩露明文),使用 CSPRNG 產生並隨密文儲存。
  3. 認證加密:優先用 AES-GCM / ChaCha20-Poly1305,避免「加密後再 HMAC」的組合錯誤(Encrypt-then-MAC 需嚴格實作)。
  4. 填充模式:RSA 必須用 OAEP,禁用 PKCS#1 v1.5(Bleichenbacher 攻擊)。
  5. 時序攻擊防禦:比對雜湊/簽章時使用 CryptographicOperations.FixedTimeEquals。
  6. 演算法淘汰:建立演算法清單與淘汰時間表,定期輪換金鑰並遷移舊資料。
  7. 錯誤訊息不洩露細節:解密失敗統一回傳「驗證失敗」,避免 Padding Oracle 攻擊。

五、遷移建議:從舊專案到現代化

  • FormsAuthentication.HashPasswordForStoringInConfigFile → IPasswordHasher (BCrypt/PBKDF2)
  • DES/3DES/RC2 → AES-GCM
  • MD5/SHA1 → SHA-256/HMAC-SHA256
  • RSACryptoServiceProvider (CAPI) → RSA (CNG) / ECDsa
  • 自訂加密工具類 → 使用 Microsoft.AspNetCore.DataProtection 統一管理金鑰輪換、用途隔離

結語

加密不是買一套庫就能「設定後忘記」的功能,而是包含金鑰生命週期、演算法治理、事件響應的系統工程。建議團隊建立密碼學策略文件,明確各資料類型的保護等級、演算法、金鑰輪換週期與事故處理流程,並納入程式碼審查與滲透測試範圍。安全是成本,但洩露是毀滅性打擊——投資正確的加密架構,永遠划算。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved