SHA512Digest合并字节数组及encodePassword方法单指令失效排查
问题诊断与修复方案
嘿,我一眼就瞅出你encodePassword方法里的问题了——就是那行digester.update(hash, 0, mergedPasswordAndSalt.length());完全不符合预期!
错误原因分析
你现在的写法犯了两个关键错误:
- 你传给
update方法的是刚初始化的空hash数组(里面全是0字节),而不是你真正要哈希的「密码+盐」内容; - 长度参数用的是
mergedPasswordAndSalt字符串的长度,但字符串长度和它转换成字节数组后的长度可能不一致(比如中文UTF-8编码下,一个字符占多个字节),这会导致数据截断或越界。
SHA512Digest的update方法的作用是喂入要计算哈希的原始数据,而不是提前传入用来存结果的空数组。
修正后的代码
把错误的那行替换成以下内容,同时补全迭代哈希的逻辑(假设你定义了ITERATIONS常量):
private static byte[] encodePassword(String password, String salt) throws UnsupportedEncodingException { String mergedPasswordAndSalt = mergePasswordAndSalt(password, salt); SHA512Digest digester = new SHA512Digest(); byte[] hash = new byte[digester.getDigestSize()]; // 修正核心:将合并后的字符串转为字节数组,喂入digester byte[] mergedBytes = mergedPasswordAndSalt.getBytes("UTF-8"); // 指定编码避免乱码 digester.update(mergedBytes, 0, mergedBytes.length); digester.doFinal(hash, 0); System.out.println("init hash= " + Base64.encode(hash)); // 补全迭代哈希逻辑(多次哈希增强安全性) for (int i = 1; i < ITERATIONS; i++) { digester.update(hash, 0, hash.length); digester.doFinal(hash, 0); // 可选:打印每次迭代后的哈希值,方便调试 // System.out.println("iteration " + i + " hash= " + Base64.encode(hash)); } return hash; }
额外优化建议
- 建议使用
StandardCharsets.UTF_8替代字符串编码名,避免UnsupportedEncodingException(需要Java 7+):byte[] mergedBytes = mergedPasswordAndSalt.getBytes(StandardCharsets.UTF_8); - 确保
mergePasswordAndSalt方法的逻辑正确(比如不会出现盐为空或拼接方式不合理的情况),这也是密码哈希安全性的关键一环。
内容的提问来源于stack exchange,提问作者Zain Elabidine
相关产品推荐
相关产品推荐

