MD5在C#中仅适用于非敏感场景,不可用于密码存储;应使用MD5.Create()而非MD5CryptoServiceProvider;必须用Encoding.UTF8.GetBytes()确保跨平台一致性;拼接十六进制字符串须用StringBuilder提升性能。

MD5.Create() 是唯一推荐的创建方式
在 .NET 6+ 中,MD5CryptoServiceProvider 已被标记为 obsolete,编译会警告,且未来版本可能直接移除。工厂方法 MD5.Create() 才是官方统一入口,它返回 HashAlgorithm 接口,便于后续无缝切换到 SHA256 或 SHA512。
- ✅ 正确写法:
using (MD5 md5 = MD5.Create()) { ... } - ❌ 避免写法:
new MD5CryptoServiceProvider()(尤其新项目) - ⚠️ 注意:
MD5.Create()自动处理资源释放,配合using可防内存泄漏
Encoding.UTF8.GetBytes() 不是可选项,是必须项
字符串转字节这一步若用错编码,同一输入在 Windows 和 Linux 上会算出不同 MD5——不是 bug,是你没控制住变量。
- ✅ 始终用
Encoding.UTF8.GetBytes(input):跨平台、可复现、Web 标准 - ❌ 别用
Encoding.ASCII.GetBytes():中文、emoji 全丢,静默失败 - ❌ 别用
Encoding.Default:Windows 默认可能是 GBK,Linux 可能是 UTF-8,结果不可控
拼接十六进制字符串必须用 StringBuilder
MD5 输出是 16 字节,转成 32 位小写十六进制字符串(如 "e84d7e1a...")。若用 string += 循环拼接,每次都会新建字符串对象,16 次操作实际分配 16 个临时字符串——高频调用(比如日志批量打点)时性能明显下滑。
- ✅ 正确写法:
StringBuilder sb = new StringBuilder(); for (int i = 0; i - ❌ 错误写法:
string result = ""; for (...) result += hashBytes[i].ToString("x2"); - ? 小技巧:
"x2"表示两位小写十六进制,"X2"是大写;别漏掉2,否则单字节可能只输出一位(如0xa→"a")
对密码加密?请直接跳过 MD5
MD5 碰撞攻击已实操可行,彩虹表满天飞,GPU 每秒可穷举上亿次。你写的 ComputeMD5("123456"),结果是公开可查的。
- ? 绝对不要:把
MD5(password)存数据库、JWT payload、配置文件 - ✅ 正确路径:密码必须加盐 + 迭代 + 慢哈希,.NET 原生支持
Rfc2898DeriveBytes(PBKDF2)或第三方BCrypt.Net-Next/Argon2 - ⚠️ 特别注意:即使加了盐,用 MD5 做哈希函数本身仍是脆弱的——盐不能救算法缺陷


















