SHA将相同的字符串散列到不同的blob中

时间:2012-01-04 17:59:52

标签: java passwords sha

我使用以下代码来散列传入的字符串,期望多次应用于该方法的相同内容将始终获得相同的结果。该方案将用于密码散列和以后的验证。但它似乎不起作用 - 我为相同的输入字符串获得了两个不同的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;
}

2 个答案:

答案 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可能是一个坏主意。我稍微编辑了我的回答以反映这一点。