HMAC-SHA1 в bash

97

Есть ли сценарий bash для генерации HMAC-SHA1хэша?

Я ищу что-то эквивалентное следующему PHP-коду:

hash_hmac("sha1", "value", "key");
отметка
источник

Ответы:

192

Я понимаю, что это не совсем то, о чем вы просите, но нет смысла изобретать колесо и писать версию для bash.

Вы можете просто использовать эту opensslкоманду для генерации хэша в вашем скрипте.

[me@home] echo -n "value" | openssl dgst -sha1 -hmac "key"
57443a4c052350a44638835d64fd66822f813319

Или просто:

[me@home] echo -n "value" | openssl sha1 -hmac "key"
57443a4c052350a44638835d64fd66822f813319

Не забудьте использовать -nwith, echoиначе к строке будет добавлен символ разрыва строки, что изменит ваши данные и хэш.

Эта команда поступает из пакета OpenSSL, который уже должен быть установлен (или легко установлен) в Linux / Unix, Cygwin и т.п.

Обратите внимание, что более старые версии openssl(например, поставляемые с RHEL4) могут не предоставлять такую -hmacвозможность.


В качестве альтернативного решения, но в основном для того, чтобы доказать, что результаты такие же, мы также можем вызвать PHP hmac_sha1()из командной строки:

[me@home]$ echo '<?= hash_hmac("sha1", "value", "key") ?>' | php
57443a4c052350a44638835d64fd66822f813319
Шон Чин
источник
Реализации OpenSSL очень медленные. Если вам нужно делать это время от времени, это нормально, но если вы пытаетесь вычислить огромное количество хэшей, вам нужно исследовать разные возможности.
Marcin
1
@Marcin: вы можете процитировать источник с этим?
sehe
6
У меня был такой же вопрос с HMAC-SHA256. То же решение, но sha1заменено на sha256:-)
mogsie
1
Да, вы можете, но следите за переносами строк в вашем файле, так как это также будет считаться частью значения.
Шон Чин
1
@ShawnChin, в этом примере какая кодировка / формат ключа? Должна ли это быть кодировка base64, такая как закрытый ключ, созданный с помощью openssl genrsa? Кроме того, ссылка на документацию openssl приводит к
ошибке
41

Вот функция bash, которая работает как hash_hmac PHP:

#!/bin/bash

function hash_hmac {
  digest="$1"
  data="$2"
  key="$3"
  shift 3
  echo -n "$data" | openssl dgst "-$digest" -hmac "$key" "$@"
}

# hex output by default
hash_hmac "sha1" "value" "key"

# raw output by adding the "-binary" flag
hash_hmac "sha1" "value" "key" -binary | base64

# other algos also work
hash_hmac "md5"  "value" "key"
Мартин
источник
Это хороший способ подвести итог. +1
Шон Чин
+1 потому что, в отличие от выбранного ответа, этот отвечает на заданный вопрос. (Хотя оба они полезны.)
Alexx Roche
но как передать аргумент data в сценарий, если он многострочный? Как тело xml или json без потери отступов.
HyperioN
@HyperioN , если у вас есть данные JSON в файл , который вы могли бы просто сделать это: hash_hmac "sha1" "$(cat your-json-file)" "key". В качестве альтернативы вы можете просто пропустить свой файл openssl dgstбез использования этой hash_hmacфункции.
Мартин
Спасибо за бит-двоичный. Для меня это был недостающий элемент
jgreen
9

Спасибо за функцию hash_hmac! Но для моего приложения этого было мало. В случае, если кому-то интересно, мне пришлось несколько раз повторно хешировать материал, используя ключ, который был результатом предыдущего хеширования и, следовательно, является двоичным вводом. (Подпись аутентификации Amazon AWS создается следующим образом.)

Так что мне нужен был способ предоставить двоичный ключ каким-то образом, чтобы не нарушить алгоритм. Потом я нашел это: http://openssl.6102.n7.nabble.com/command-line-hmac-with-key-in-hex-td6754.html

Ответ Стивена Хенсона требует, чтобы функция hash_hmac возвращала значение в шестнадцатеричном формате. Поэтому необходимо повторить следующее:

$ echo -n "$data" | openssl dgst "-$digest" -hmac "$key" | sed -e 's/^.* //'

Тогда следующий вызов должен будет предоставить ключ в виде шестнадцатеричного числа:

$ echo -n "$data" | openssl dgst "-$digest" -mac HMAC -macopt "hexkey:$key" | sed -e 's/^.* //'

Надеюсь, это поможет любому, возможно, тому, кто пытается создать сценарии bash для аннулирования записей CloudFront на AWS (например, я!) (Я еще не тестировал это, но я думаю, что это причина того, почему мой сценарий bash не работает, а мой PHP работает ...)

Воутер Тилен
источник
0

Установив node.js, вы можете использовать инструмент HMAC-CLI :

npx hmac-cli generate 'value' -h sha1 -s key

возвращает:

57443a4c052350a44638835d64fd66822f813319
Terite
источник