密碼雜湊是資安基礎。MD5(128-bit)與 SHA1(160-bit)雖已知碰撞弱點,**不適合高安全性場景**(如數位簽章、SSL 憑證),但對一般應用程式密碼儲存、資料完整性驗證仍具參考價值。本文整理 ASP.NET 三種實作方式。
| 演算法 | 核心類別 | 便捷方法 |
|---|---|---|
| MD5 | MD5CryptoServiceProvider, MD5.Create() | FormsAuthentication.HashPasswordForStoringInConfigFile(str, "MD5") |
| SHA1 | SHA1CryptoServiceProvider, SHA1.Create() | FormsAuthentication.HashPasswordForStoringInConfigFile(str, "SHA1") |
public string GetMd5Method1(string source)
{
using (MD5 md5 = new MD5CryptoServiceProvider())
{
byte[] hash = md5.ComputeHash(Encoding.Default.GetBytes(source));
// 取 9-25 位(16 字元),或完整 32 字元
string result = BitConverter.ToString(hash, 4, 8).Replace("-", "");
// 完整版:BitConverter.ToString(hash).Replace("-", "");
return result;
}
}
public string GetMd5Method2(string source)
{
using (MD5 md5 = MD5.Create())
{
byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(source)); // 建議 UTF-8
StringBuilder sb = new StringBuilder();
foreach (byte b in hash)
sb.Append(b.ToString("X2")); // 大寫十六進位,兩位數補零
return sb.ToString();
}
}
public string GetMd5Method3(string source)
{
return FormsAuthentication.HashPasswordForStoringInConfigFile(source, "MD5");
}
// 方法二 SHA1 版
public string GetSha1Method2(string source)
{
using (SHA1 sha1 = SHA1.Create())
{
byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(source));
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
}
// 方法三 SHA1 版
public string GetSha1Method3(string source)
{
return FormsAuthentication.HashPasswordForStoringInConfigFile(source, "SHA1");
}
| 維度 | 方法一 | 方法二 | 方法三 |
|---|---|---|---|
| 彈性 | 高(可切片輸出) | 高(可控編碼、格式) | 低(固定 32/40 字元大寫) |
| 編碼控制 | Encoding.Default(系統相關) | **可指定 UTF-8/Unicode**(推薦) | 內部固定 |
| 效能 | 同級 | 同級 | 同級 |
| 相依性 | System.Security.Cryptography | System.Security.Cryptography | System.Web.Security |
| 適用場景 | 需特定長度輸出 | **通用推薦** | 快速原型、相容舊代碼 |
IPasswordHasher<TUser> 預設使用 PBKDF2 + HMAC-SHA256 + 隨機 Salt// 註冊時
var hasher = new PasswordHasher<User>();
user.PasswordHash = hasher.HashPassword(user, plainPassword);
// 登入驗證
var result = hasher.VerifyHashedPassword(user, user.PasswordHash, inputPassword);
if (result == PasswordVerificationResult.SuccessRehashNeeded)
{
// 演算法升級,重新雜湊存儲
user.PasswordHash = hasher.HashPassword(user, inputPassword);
await _userRepo.UpdateAsync(user);
}
理解傳統雜湊實作有助於維護舊系統,但新專務請直接採用現代密碼雜湊標準,守住資安第一道防線。