SHA-256相同的字符串返回不同的byte []?

时间:2015-10-11 00:43:55

标签: java hash

我需要SHA-256作为AES-256的密钥。 但我的示例SHA-256是:

MessageDigest messageDigest;
messageDigest = MessageDigest.getInstance("SHA-256");

String input = new String("ALIBABA");
messageDigest.update(input.getBytes(Charset.forName("UTF-8")));
byte[] hash = messageDigest.digest();
String hash1s = new String(hash,StandardCharsets.UTF_8);
System.out.println("HASH 1 is "+hash1s);
System.out.println("HASH 1 is "+hash);

String input2 = new String("ALIBABA");
messageDigest.update(input2.getBytes(Charset.forName("UTF-8")));
byte[] hash2 = messageDigest.digest();
String hash2s = new String(hash2,StandardCharsets.UTF_8);
System.out.println("HASH 2 is "+hash2s);
System.out.println("HASH 2 is "+hash2);

返回不同的值byte []:

  

HASH 1为V%��%�P�9�P��v�/�/ e \ BF}�$]

     

HASH 1是[B @ 629f0666

     

HASH 2为V%��%�P�9�P��v�/�/ e \ BF}�$]

     

HASH 2是[B @ 1bc6a36e

如何将相同的byte []作为AES-256的密钥?

2 个答案:

答案 0 :(得分:5)

[B@629f0666[B@1bc6a36e内容分别不是hashhash2的内容,它们是默认的toString()表示形式。 [B部分告诉您它是一个字节数组,后面的十六进制数是它的标识哈希码,它类似于内存中的地址。 (不完全是一个地址,但以这种方式思考是有用的。)

当然,由于它们是两个不同的数组,它们位于内存中的不同位置,因此它们的默认toString()表示形式不同。但那是无关紧要的:他们的内容是相同的。

为了看到它们是相同的,你不必打印它们,你可以简单地逐字节比较它们。但是如果你坚持打印它们,那么new String( hash2, StandardCharsets.UTF_8 );的尝试是错误的,因为它试图将随机字节重新解释为unicode字符,这当然会产生有趣的结果。看一下这个答案:How to convert a byte array to a hex string in Java?

(在任何情况下,请注意两个垃圾串是相同的,所以这应该告诉你你的字节数组也是相同的。)

答案 1 :(得分:1)

您需要在同一对象的连续使用之间调用messageDigest.reset()来计算不同数据的哈希值。

这是因为MessageDigest意味着与您提供给它的数据块一起使用(通过调用update(...))。因此,行为是继续更新内部哈希,直到您通过reset()重置状态。

在您的代码中,第二个摘要基本上是字符串"ALIBABAALIBABA"