md5在c#中是不可逆哈希而非加密,因碰撞漏洞和彩虹表攻击风险,已不适用于密码存储、签名等安全场景;仅推荐用于文件校验或兼容旧协议,且必须用encoding.utf8编码字符串并做非空检查,.net 5+优先使用md5.hashdata()。

MD5 在 C# 中早已不推荐用于安全敏感场景,它不是加密而是哈希,且已被证实可碰撞、易被彩虹表破解。如果你只是做文件校验、缓存键生成或兼容旧协议,可以用;但千万别用来存密码、签名校验或传输凭证。
用 System.Security.Cryptography.MD5 生成字符串哈希
这是最直接的方式,但要注意:MD5 类型只接受 byte[] 输入,所以必须先将字符串编码为字节数组。默认用 UTF8 编码,别用 Unicode 或 ASCII,否则结果不一致。
常见错误现象:System.ArgumentNullException: Value cannot be null. —— 往往是传了 null 字符串没判空;或者用了 Encoding.Default 导致跨平台结果不同。
- 始终显式指定
Encoding.UTF8 - 对输入字符串做非空检查,空串建议返回
MD5.HashData(new byte[0])而不是跳过 - .NET 5+ 推荐用静态方法
MD5.HashData(...),比创建实例更轻量
string input = "hello";
byte[] bytes = Encoding.UTF8.GetBytes(input);
byte[] hashBytes = MD5.HashData(bytes);
string hashHex = BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); // → "5d41402abc4b2a76b9719d911017c592"
为什么不能直接用 string.GetHashCode() 替代 MD5?
string.GetHashCode() 是运行时内部散列,目的仅是哈希表快速查找,不保证跨进程、跨版本、跨平台一致。同一字符串在 .NET 5 和 .NET 6 下可能返回不同值,甚至重启应用后也变。
- 它不满足确定性(deterministic)要求,无法用于持久化或网络传输
- 无密码学安全性,且输出是
int,范围太小,冲突率极高 - 和 MD5 完全不是同一类工具:一个是语言运行时优化,一个是标准哈希算法
替代方案:什么时候该换 SHA256 或 SHA512?
只要涉及用户密码、API 签名、数据完整性校验,都应弃用 MD5。.NET 提供统一接口,替换成本很低。
- 把
MD5.HashData(...)换成SHA256.HashData(...)即可,其余逻辑完全不变 - 注意输出长度:MD5 是 128 位(32 字符 hex),SHA256 是 256 位(64 字符 hex),别硬截断
- 若需 Base64 编码(比如 JWT payload),用
Convert.ToBase64String(hashBytes),别用 hex
// 更安全的等效写法 byte[] hashBytes = SHA256.HashData(Encoding.UTF8.GetBytes(input)); string hashBase64 = Convert.ToBase64String(hashBytes); // → "fHXWz...+kQ=="
真正容易被忽略的是编码一致性——哪怕算法选对了,Encoding.UTF8 写成 Encoding.GetEncoding("GB2312") 就会导致服务端客户端哈希不匹配。这种问题在线上查半天,最后发现只是编码参数多敲了一个空格。











