SHA-256 same string return different byte[]?

2020-06-07 04:47发布

问题:

I need SHA-256 to be my key for AES-256. But my example SHA-256 is:

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);

Return not a same value byte[]:

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

HASH 1 is [B@629f0666

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

HASH 2 is [B@1bc6a36e

How do I get same byte[] to be key for AES-256?

回答1:

The [B@629f0666 and [B@1bc6a36e thingies are not the contents of hash and hash2 respectively, they are their default toString() representations. The [B part is telling you that it is an array of bytes, and the hex number that follows is its identity hash code, which is something akin to an address in memory. (Not exactly an address, but it is useful to think of it that way.)

And of course, since they are two different arrays, they live in different locations in memory, so their default toString() representations differ. But that's irrelevant: their contents are identical.

In order to see that they are identical, you don't have to print them, you can simply compare them byte by byte. But if you insist on printing them, your attempt with new String( hash2, StandardCharsets.UTF_8 ); is mistaken, because it is trying to reinterpret random bytes as unicode characters, which of course gives funny results. Take a look at this answer: How to convert a byte array to a hex string in Java?

(And in any case, note that the two strings of garbage are identical, so this should be telling you that your byte arrays are identical, too.)



回答2:

You need to call messageDigest.reset() between successive utilizations of the same object to compute hash for different data.

This because MessageDigest is meant to be used with chunks of data that you feed to it not all at once (by calling update(...)). So the behavior is to keep updating the internal hash until you reset the state through reset().

Basically in your code the second digest is for the string "ALIBABAALIBABA"



标签: java hash