1

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?

Community
  • 1
  • 1
BeGood
  • 191
  • 2
  • 9

3 Answers3

5

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

Community
  • 1
  • 1
Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
1

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"

Jack
  • 131,802
  • 30
  • 241
  • 343
  • But why still have same String hash – BeGood Oct 11 '15 at 00:54
  • Because you are not converting a `byte[]` array to a literal `String` representation of it, you are interpreting a `byte[]` as an UTF-8 `String` object. But this makes no sense since the digest is not a `String` but numerical values. Try `System.out.println(Arrays.toString(hash2));` – Jack Oct 11 '15 at 00:56
  • Then you are not doing things correctly or you didn't post your exact code. You should take care of what you post, this definitely works: http://ideone.com/S36oUA – Jack Oct 11 '15 at 01:08
0

Someone may need a more simple explanation. String contains info not only for chars in it, but also some other info. May be for example about it's position in String pool etc. That info also included in .toByteArray() so results differ for 2 same strings. A piece of advice is to use char[] instead. Here is some code.

byte[] toBytes(char[] chars) {
  CharBuffer charBuffer = CharBuffer.wrap(chars);
  ByteBuffer byteBuffer = Charset.forName("UTF-8").encode(charBuffer);
  byte[] bytes = Arrays.copyOfRange(byteBuffer.array(),
          byteBuffer.position(), byteBuffer.limit());
  Arrays.fill(byteBuffer.array(), (byte) 0); // clear sensitive data
  return bytes;
}

...

bytesToHex(MessageDigest
             .getInstance("SHA-256")
             .digest(toBytes(charArray)));

...

String bytesToHex(byte[] bytes){
  //any way you want to convert byte array to String
  //for example using apache.commons.codec:
  return Hex.encodeHexString(bytes);
}
ilya_kas
  • 159
  • 1
  • 6