我使用以下代码来散列传入的字符串,期望多次应用于该方法的相同内容将始终获得相同的结果。该方案将用于密码散列和以后的验证。但它似乎不起作用 - 我为相同的输入字符串获得了两个不同的blob。我的代码有什么问题或遗漏吗?
public synchronized String encrypt(String token) {
try {
MessageDigest sha = MessageDigest.getInstance("SHA");
sha.reset();
sha.update(token.getBytes("UTF-8"));
byte[] raw = sha.digest();
System.out.println("raw = " + raw.toString());
String hash = Base64.encodeBase64(raw).toString();
return hash;
} catch (Exception e) {
}
return token;
}
答案 0 :(得分:5)
你还没有给出足够的信息,但我怀疑你被这分心了:
System.out.println("raw = " + raw.toString());
这将打印出[B@30a4effe
之类的内容,其中 nothing 与字节数组中的数据有关。如果您的hash
真的相同,则应打印token
代替所有来电 。
(正如Dan所说,你的方法名称不合适:哈希不是加密。另外,请不要抓住Exception
或只是吞下这样的例外。看起来很漂亮奇数只是在失败时返回token
。)
编辑:如上所述,我假设Base64.encode
实际上返回一个字符串,它可能不会。我建议this base64 implementation是公共域并且有一个合理的API - 编码调用返回一个String,这是完全合适的。当然,您也不需要明确的toString()
调用......
答案 1 :(得分:1)
我不知道你正在使用什么Base64类,但我会假设来自Apache Commons的那个。你这样做:
String hash = Base64.encodeBase64(raw).toString();
在toString
方法返回的任何随机字节数组上调用Base64.encodeBase64()
方法。这就是为什么你的结果每次都是随机的,你只是将一个对象引用作为String返回。试试这个:
String hash = Base64.encodeBase64String(raw);
修改强>
正如另一篇文章所指出的,直接转换为String可能是一个坏主意。我稍微编辑了我的回答以反映这一点。