0

I have this Powershell snippet, which I cannot change and provides the Hash I need to match:

$key = 'test'
$bytes = [Text.Encoding]::UTF8.GetBytes($key)
WRITE-HOST "bytes: " $bytes
$hmacsha = new-object system.security.cryptography.HMACSHA1
$hmacsha.key = $bytes
$hash = $hmacsha.ComputeHash($bytes)
WRITE-HOST "hash: " $hash

Which gives this result:

bytes:  116 101 115 116
hash:  12 148 81 92 21 229 9 91 138 135 165 11 160 223 59 243 142 208 95 230

And this in Java:

String key = "test";
byte[] bytes = key.getBytes("UTF-8");
System.out.println("bytes: " + Arrays.toString(bytes));

MessageDigest md = MessageDigest.getInstance("SHA-1");
byte[] keyBytes = md.digest(bytes);
SecretKey sk = new SecretKeySpec(keyBytes, "HmacSHA1");
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(sk);
byte[] hash = mac.doFinal(keyBytes);
System.out.println("hash 1: " + Arrays.toString(hash));

sk = new SecretKeySpec(bytes, "HmacSHA1");
mac = Mac.getInstance("HmacSHA1");
mac.init(sk);
hash = mac.doFinal(bytes);
System.out.println("hash 2: " + Arrays.toString(hash));

Which outputs:

bytes: [116, 101, 115, 116]
hash 1: [-112, -37, 64, 65, -91, -97, 36, 60, -80, -110, 62, -105, -63, -69, -79, -18, 29, -95, 23, -116]
hash 2: [12, -108, 81, 92, 21, -27, 9, 91, -118, -121, -91, 11, -96, -33, 59, -13, -114, -48, 95, -26]

I cannot seem to get the Hash to match what Powershell is outputting. In both examples I am creating a hmacsha1 instance with a key of "test", then getting the hash of "test", but both have some minor difference causing them to give different results.

1 Answer 1

1

You are not getting 2 different hashes. Matter of fact ...

12, -108, 81, 92, 21, -27, 9, 91, -118, -121, -91, 11, -96, -33, 59, -13, -114, -48, 95, -26

is the same as

12 148 81 92 21 229 9 91 138 135 165 11 160 223 59 243 142 208 95 230

What is happening is in java when you turn to string it is making these values signed.

An example of this is with -108 and 148

00000000,10010100 = 148
11111111,10010100 = -108

If you want to make the byte look unsigned you can use 0xFF combined with the byte.

byte b = (byte) Integer.parseInt("148");
System.out.println(b);

outputs : -108

byte b = (byte) Integer.parseInt("148");
System.out.println(b & 0xFF);

outputs : 148

What is happening is you are usinga bitwise AND operator so 0xFF = 255 aka 11111111 and matching common bits and keeping them.

00000000,11111111 = 255 aka 0xFF
11111111,10010100 = -108
--------
00000000,10010100 = 148
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.