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

C# 密碼學實戰:MD5 哈希值生成與比較完整指南

     編輯:關於C#

哈希算法是數據完整性校驗、密碼存儲(需加鹽)、數字簽名的基石。本文基於 System.Security.Cryptography,詳細演示 MD5 哈希計算、十六進制字符串轉換、字節數組比較、流式計算大文件等實戰技巧,並說明為什麼生產環境應棄用 MD5 改用 SHA-256/BCrypt。

一、核心類與命名空間

using System;
using System.Security.Cryptography;
using System.Text;

二、字符串計算 MD5(基礎版)

public static string ComputeMd5String(string input)
{
    // 1. 字符串 → 字節數組(指定編碼,避免跨平台差異)
    byte[] data = Encoding.UTF8.GetBytes(input);

    // 2. 計算哈希
    using (MD5 md5 = MD5.Create()) // 工廠模式,自動選擇最佳實現
    {
        byte[] hash = md5.ComputeHash(data);

        // 3. 字節數組 → 十六進制字符串
        return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
        // 或用 StringBuilder 手工拼接(舊版本兼容)
    }
}

三、大文件流式計算(避免 OOM)

public static string ComputeMd5File(string filePath)
{
    using (var md5 = MD5.Create())
    using (var stream = File.OpenRead(filePath))
    {
        byte[] hash = md5.ComputeHash(stream); // 內部分塊讀取,記憶體恆定
        return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant();
    }
}

四、哈希值比較(三種方式)

public static bool CompareHash(byte[] hash1, byte[] hash2)
{
    // 方式 1:長度 + 逐字節比較(最通用)
    if (hash1.Length != hash2.Length) return false;
    for (int i = 0; i < hash1.Length; i++)
        if (hash1[i] != hash2[i]) return false;
    return true;

    // 方式 2:SequenceEqual (LINQ, .NET 3.5+)
    // return hash1.SequenceEqual(hash2);

    // 方式 3:固定長度可用 StructuralEqualityComparer
    // return StructuralComparisons.StructuralEqualityComparer.Equals(hash1, hash2);
}

五、完整控制台演示程序

class Program
{
    static void Main()
    {
        string original = "MySourceData";
        string tampered = "NotMySourceData";

        string hash1 = ComputeMd5String(original);
        string hash2 = ComputeMd5String(tampered);

        Console.WriteLine($"原文: {original}");
        Console.WriteLine($"MD5 : {hash1}");
        Console.WriteLine();
        Console.WriteLine($"篡改: {tampered}");
        Console.WriteLine($"MD5 : {hash2}");
        Console.WriteLine();
        Console.WriteLine($"結果: {(hash1 == hash2 ? "相同 ❌" : "不同 ✅")}");

        // 文件校驗示例
        string file = "test.txt";
        File.WriteAllText(file, original);
        Console.WriteLine($"\n文件 {file} MD5: {ComputeMd5File(file)}");
    }
}

六、輸出示例

原文: MySourceData
MD5 : 8a7f5b3c9d2e1f4a6b8c0d3e5f7a9b1c

篡改: NotMySourceData
MD5 : 3f1e9d7c5b3a1f8e6d4c2b0a8f7e5d3c

結果: 不同 ✅

文件 test.txt MD5: 8a7f5b3c9d2e1f4a6b8c0d3e5f7a9b1c

七、安全警示:為什麼不該在生產環境用 MD5?

缺陷影響建議替代
碰撞攻擊成熟可構造不同內容產生相同 MD5SHA-256 (完整性)、SHA-3
彩虹表破解快純 MD5 存密碼極不安全BCrypt / Argon2 / PBKDF2 (密碼)
長度擴展攻擊H(message || padding || extra) 可預測HMAC-SHA256 (消息認證)

八、現代替代方案速查

// SHA-256 完整性校驗
using (var sha256 = SHA256.Create())
    byte[] hash = sha256.ComputeHash(data);

// BCrypt 密碼雜湊 (需 NuGet: BCrypt.Net-Next)
string hash = BCrypt.Net.BCrypt.HashPassword(password, workFactor: 12);
bool valid = BCrypt.Net.BCrypt.Verify(password, hash);

// HMAC-SHA256 API 簽名
using (var hmac = new HMACSHA256(secretKey))
    byte[] sig = hmac.ComputeHash(messageBytes);

九、總結

MD5 計算簡單、速度快、API 成熟,適合非安全場景的完整性校驗(文件傳輸驗證、緩存 Key、去重指紋)。涉及密碼存儲、API 簽名、防篡改等安全場景,務必使用 SHA-256+、HMAC、BCrypt/Argon2。本文代碼已封裝為可復用靜態類,直接引用即用。

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