Получение HmacSHA1 Java Hash для соответствия Powershell Hash - PullRequest
0 голосов
/ 29 сентября 2018

У меня есть этот фрагмент кода Powershell, который я не могу изменить и предоставляет хэш, который мне нужно сопоставить:

$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

, который дает такой результат:

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

И это в 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));

Какие выходные данные:

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]

Я не могу получить хэш, совпадающий с тем, что выводит Powershell.В обоих примерах я создаю экземпляр hmacsha1 с ключом «test», затем получаю хэш «test», но оба имеют незначительные различия, заставляющие их давать разные результаты.

1 Ответ

0 голосов
/ 29 сентября 2018

Вы не получаете 2 разных хэша.Дело в том ...

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

- это то же самое, что и

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

То, что происходит в Java, когда вы обращаетесь к строке, делает эти значения подписанными.

Примером этого являются -108 и 148

00000000,10010100 = 148
11111111,10010100 = -108

Если вы хотите, чтобы байт выглядел беззнаковым, вы можете использовать 0xFF в сочетании с байтом.

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

выходы: -108

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

выходы: 148

Что происходит, вы используете битовый оператор AND, так что 0xFF = 255 или 11111111 и соответствуетобщие биты и их хранение.

00000000,11111111 = 255 aka 0xFF
11111111,10010100 = -108
--------
00000000,10010100 = 148
...