2012-01-04 70 views
2

我正在使用以下代码来散列传入的字符串,期望多次应用于该方法的相同的东西总是会得到相同的结果。该场景将用于密码散列和稍后验证。但它似乎并不奏效 - 我为同一个输入字符串得到了两个不同的blob。我的代码有什么不对吗?SHA将相同的字符串散列到不同的块中

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

添加相关语言的标签。我相信你忘了添加'Java'。 – 2012-01-04 18:01:55

+0

谢谢,补充一下。 – tom 2012-01-04 18:03:14

+0

SHA是** NOT **加密。 – Dan 2012-01-04 18:04:28

回答

5

你真的没有给予足够的信息,但我怀疑你被分心本:

System.out.println("raw = " + raw.toString()); 

那将打印出像[[email protected]具有没有做的东西字节数组中的数据。你应该打印出hash而不是 - 如果你的token真的是一样的,那么应该是对于所有呼叫都是相同的。

(正如丹指出,你的方法不当命名为:哈希是不加密的同时,请不要赶Exception刚咽下这样的例外似乎很奇怪,刚刚在失败时返回token,。 )

编辑:如上所述,我假设Base64.encode实际上返回一个字符串,它可能不会。我建议this base64 implementation这是公共领域,并有一个合理的API - 编码调用返回一个字符串,这是完全合适的。当然,你不需要明确的toString()调用以及...

+0

感谢您的收获!什么是真正的加密所需的额外步骤?我的代码是根据一些说密码加密的示例代码编写的。 – tom 2012-01-04 18:13:29

+1

@tom:对于密码,您可能*不应该使用可逆加密。即使散列本身并不好 - 你至少应该对散列进行加盐,以及选择合适的散列算法。 (做更多细节的搜索salt hash加密。) – 2012-01-04 18:21:19

+0

非常感谢解释。 – tom 2012-01-04 18:28:40

1

我不知道你使用的是什么Base64类,但我将假设来自Apache Commons。你这样做:

String hash = Base64.encodeBase64(raw).toString(); 

这是调用任何随机字节数组的toString方法是从Base64.encodeBase64()方法返回。这就是为什么你的结果每次都是随机的,你只是以String的形式返回一个对象引用。试试这个:

String hash = Base64.encodeBase64String(raw); 

编辑

正如在另一篇文章中指出,直接转换为字符串可能是一个坏主意。我稍微编辑了我的答案以反映这一点。

相关问题