1

There are some SO quetions but no helped me. I would like to convert byte[] from org.apache.commons.codec.digest.HmacUtils to String. This code produces some weird output:

final String value = "value";
final String key = "key";
byte[] bytes = HmacUtils.hmacSha1(key, value);
String s = new String(bytes);

What am I doing wrong?

Artegon
  • 2,734
  • 6
  • 32
  • 62
  • 1
    Generally, you display sha1 hashes in hex. [Commons Codec](https://commons.apache.org/proper/commons-codec/) has a hex encoder. – Elliott Frisch Sep 26 '15 at 19:41
  • Probably relevant, possibly duplicate: http://stackoverflow.com/questions/9655181/how-to-convert-a-byte-array-to-a-hex-string-in-java The resulting 'random binary' of the hash function will otherwise *not* be a useful text/string value. – user2864740 Sep 26 '15 at 19:53

4 Answers4

2

Try to use:

String st = HmacUtils.hmacSha1Hex(key, value);
Dmitry JJ
  • 169
  • 2
  • 11
1

First, the result of hmacSha1 would produce a digest, not not a clear String. Besides, you may have to specify an encoding format, for example

String s = new String(bytes, "US-ASCII");

or

String s = new String(bytes, "UTF-8");
ufuoma
  • 187
  • 6
  • Well, still I am getting a weird output ("WD:L#P�F8�]d�f�/�3") that doesn't correspond to this testing application - http://www.freeformatter.com/hmac-generator.html. – Artegon Sep 26 '15 at 19:54
  • @user1315357 The confusion is the problem/expected output is not clearly specified. – user2864740 Sep 26 '15 at 19:57
1

For a more general solution, if you don't have HmacUtils available:

// Prepare a buffer for the string
StringBuilder builder = new StringBuilder(bytes.length*2);
// Iterate through all bytes in the array
for(byte b : bytes) {
    // Convert them into a hex string
    builder.append(String.format("%02x",b));
    // builder.append(String.format("%02x",b).toUpperCase()); // for upper case characters
}
// Done
String s = builder.toString();

To explain your problem: You are using a hash function. So a hash is usually an array of bytes which should look quite random.

If you use new String(bytes) you try to create a string from these bytes. But Java will try to convert the bytes to characters.

For example: The byte 65 (hex 0x41) becomes the letter 'A'. 66 (hex 0x42) the letter 'B' and so on. Some numbers can't be converted into readable characters. Thats why you see strange characters like '�'.

So new String(new byte[]{0x41, 0x42, 0x43}) will become 'ABC'.

You want something else: You want each byte converted into a 2 digit hex String (and append these strings).

Greetings!

Stefan A
  • 111
  • 7
0

You may need to have an encoding format. Check out this link here.

UTF-8 byte[] to String

Community
  • 1
  • 1
Edwin
  • 198
  • 3
  • 12