SHA256在C#中是不可逆哈希而非加密,需UTF8编码字符串、ComputeHash计算、Convert.ToHexString转小写十六进制;必须using释放资源,加盐应避免简单拼接,密码存储推荐Argon2/BCrypt而非SHA256。

SHA256 在 C# 中不是“加密”,而是哈希——不可逆,且默认不加盐;直接用 SHA256.Create() 得到的是原始字节数组,不转成十六进制字符串就容易误以为“没结果”。
为什么 SHA256.Create() 返回空或乱码?
因为 SHA256.Create().ComputeHash() 返回的是 byte[],直接 .ToString() 会输出类型名(如 System.Byte[]),不是哈希值。
- 必须手动把字节数组转为十六进制字符串:用
BitConverter.ToString(hash).Replace("-", "").ToLower(),或更安全的Convert.ToHexString(hash).ToLower()(.NET 5+) - 如果输入是字符串,得先指定编码(推荐
Encoding.UTF8),否则中文等会出错 - 别用
ASCIIEncoding处理含 Unicode 的文本——它会静默丢弃无法表示的字符
如何正确哈希字符串(含中文、特殊符号)?
核心是三步:编码 → 计算 → 格式化。下面是最简可靠写法:
string input = "你好,world!123";
using var sha256 = SHA256.Create();
byte[] bytes = Encoding.UTF8.GetBytes(input);
byte[] hash = sha256.ComputeHash(bytes);
string result = Convert.ToHexString(hash).ToLower(); // .NET 5+
// 或兼容旧版:BitConverter.ToString(hash).Replace("-", "").ToLower()
-
Convert.ToHexString()比BitConverter.ToString()更快、更安全(无分隔符、无额外分配) - 务必在
using块中使用SHA256实例——它实现了IDisposable,不释放可能泄漏句柄(尤其高频调用时) - 不要重复 new SHA256CryptoServiceProvider() ——
SHA256.Create()已自动选择最优实现(如 Windows 上是 CNG)
需要加盐(salt)时怎么处理?
SHA256 本身不内置加盐逻辑,盐必须手动拼接。常见错误是把盐和原文简单字符串拼接(如 salt + input),这存在长度扩展风险;生产环境应改用 Rfc2898DeriveBytes(PBKDF2)或 HashAlgorithmName.SHA256 + HMAC。
- 若只是简单防彩虹表,可拼接 salt 字节数组:
var allBytes = salt.Concat(Encoding.UTF8.GetBytes(input)).ToArray() - 盐必须随机且唯一(每次生成新
RandomNumberGenerator.GetBytes(salt)),不能硬编码 - 存储时需同时保存 salt 和 hash(例如 JSON:
{"salt": "abc...", "hash": "def..."}),验证时重新计算比对
真正要注意的不是“怎么写出哈希值”,而是“是否理解它不可逆、不防碰撞、不等于密码学安全的密钥派生”——尤其是把 SHA256 直接用于密码存储,哪怕加了盐,也远不如 Argon2 或 BCrypt。


















