如何正确在数据库存储PasswordHash与PasswordSalt?含问题与扩展建议
密码哈希与盐存储的问题解答
问题核心回顾
你使用binary(500)存储HMACSHA512生成的哈希(64字节)和盐(64字节)时,数据库自动填充0到500字节,导致验证时哈希对比失败。以下是针对你问题的具体解答:
1. 存储此类数据的最佳实践
- 选用可变长度二进制类型:放弃固定长度的
binary(n),改用varbinary(n)(SQL Server)、bytea(PostgreSQL)或BLOB(MySQL)这类可变长度类型,它们仅存储实际字节数据,不会自动填充0。 - 匹配算法固定长度:HMACSHA512的哈希和盐均为固定64字节,可直接指定
varbinary(64),既节省空间又从根源避免长度匹配问题。若未来更换算法,再同步调整字段长度即可。 - 直接存储二进制数据:不要将哈希/盐转换为Base64或十六进制字符串存储(除非有特殊业务需求),直接存二进制更高效,也能减少转换过程中的潜在错误。
2. 是否需要在写入数据库前处理数据
不需要额外处理。只要数据库字段类型选择正确(可变长度二进制),直接写入生成的byte[]即可。如果已经使用了固定长度字段,最彻底的解决方案是修改字段类型;临时方案可在读取数据后截取有效长度(比如取前64字节),但不推荐长期使用。
3. 考虑未来SHA-1024需求的存储大小推荐
- SHA-1024的输出长度为128字节(1024位),对应的HMAC-SHA-1024密钥(盐)建议使用128字节(与哈希输出长度一致,或不短于哈希长度)。
- 为兼容未来算法迭代,可将字段设为
varbinary(256)(256字节足够覆盖绝大多数主流哈希算法的输出,包括SHA-3系列的大长度哈希);若追求极致灵活性,也可使用varbinary(max),但需注意数据库的存储限制(密码哈希本身不会占用过大空间)。
关于SHA-512是否过度设计的补充
2014年的观点在当前依然有参考价值,需结合场景判断:
- 普通Web应用场景下,SHA-256已足够满足安全需求,HMAC-SHA256的哈希(32字节)+32字节盐完全够用,且计算速度比SHA-512更快(尤其是32位系统)。
- SHA-512的优势在于理论抗碰撞性更强,但目前SHA-2系列(包括SHA-256、SHA-512)均未被成功破解,普通场景下使用SHA-512算不上“过度设计”,只是属于冗余安全。若你的系统涉及金融、涉密等高安全要求场景,使用SHA-512或SHA-3-512是合理选择。
- 绝对禁止使用SHA-1,其碰撞漏洞已被证实,完全不适合密码存储。
内容的提问来源于stack exchange,提问作者WowDogeCode
相关产品推荐
相关产品推荐

