c#中md5哈希由system.security.cryptography.md5直接支持,但它是不可逆哈希而非加密,不适用于密码存储;须显式用utf-8编码、bitconverter转小写十六进制;大文件需流式计算,避免内存溢出。

MD5加密在C#中用System.Security.Cryptography.MD5类实现
直接结论:C#标准库已提供完整支持,无需第三方包。但要注意MD5是哈希算法,不是加密——它不可逆,且已不推荐用于安全敏感场景(如密码存储)。
实际使用时,最常踩的坑是编码不一致导致结果不同:比如字符串转byte[]时没指定Encoding.UTF8,用了默认编码(可能为Encoding.default,windows平台下通常是GBK),结果和Java/Python等其他语言对不上。
- 始终显式使用
Encoding.UTF8.GetBytes(input),别依赖隐式转换 -
MD5.Create()返回的是接口MD5,可直接调用ComputeHash() - 输出是
byte[],转16进制字符串时建议用BitConverter.ToString(hash).Replace("-", "").ToLower(),避免手动拼接出错
C# MD5字符串哈希的完整示例(含空值处理)
以下代码覆盖常见需求:输入非空校验、UTF-8编码、小写16进制输出。注意using确保MD5实例被正确释放。
public static string ComputeMD5(string input) { if (string.IsNullOrEmpty(input)) return string.Empty; <pre class='brush:php;toolbar:false;'>using (var md5 = System.Security.Cryptography.MD5.Create()) { var bytes = System.Text.Encoding.UTF8.GetBytes(input); var hash = md5.ComputeHash(bytes); return BitConverter.ToString(hash).Replace("-", "").ToLower(); }
}
调用示例:ComputeMD5("hello") → "5d41402abc4b2a76b9719d911017c592"。这个结果与linux md5sum、Python hashlib.md5(b"hello").hexdigest()完全一致。
为什么不要用MD5存密码?替代方案是什么
MD5存在严重碰撞漏洞,且计算极快,容易被彩虹表或暴力破解。即使加盐(salt),也不足以弥补其设计缺陷。
- 密码哈希必须用慢哈希(slow hash):如
Argon2、scrypt、bcrypt或.NET内置的Rfc2898DeriveBytes(即PBKDF2) - .NET 5+ 推荐用
microsoft.AspNetCore.Cryptography.KeyDerivation中的KeyDerivation.Pbkdf2方法,它默认使用HMAC-SHA256 + 10万次迭代 - 若仅需兼容旧系统做校验(如对接老API),才用MD5,且务必确认对方也是UTF-8 + 小写十六进制
MD5文件校验的正确写法(避免内存溢出)
对大文件直接读入内存会崩,必须流式计算。关键点是不用File.ReadAllBytes(),改用FileStream配合ComputeHash(Stream)。
public static string ComputeMD5OfFile(string filePath) { if (!System.IO.File.Exists(filePath)) throw new System.IO.FileNotFoundException($"File not found: {filePath}"); <pre class='brush:php;toolbar:false;'>using (var md5 = System.Security.Cryptography.MD5.Create()) using (var stream = new System.IO.FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read, 8192, System.IO.FileOptions.SequentialScan)) { var hash = md5.ComputeHash(stream); return BitConverter.ToString(hash).Replace("-", "").ToLower(); }
}
注意FileOptions.SequentialScan提示OS做顺序读优化,bufferSize=8192是合理默认值;若文件普遍超1GB,可适当调大缓冲区,但提升有限,重点还是流式处理本身。
真正容易被忽略的是:调试时随手用console.WriteLine打印大文件MD5结果,却忘了ide控制台可能截断长字符串——建议先赋值给变量再断点查看,或写入临时文件比对。