HMAC-SHA1 w bash

97

Czy istnieje skrypt bash do generowania HMAC-SHA1skrótu?

Szukam czegoś równoważnego z następującym kodem PHP:

hash_hmac("sha1", "value", "key");
znak
źródło

Odpowiedzi:

191

Zdaję sobie sprawę, że nie jest to dokładnie to, o co prosisz, ale nie ma sensu odkrywać na nowo koła i pisać wersji bash.

Możesz po prostu użyć opensslpolecenia, aby wygenerować skrót w swoim skrypcie.

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

Lub po prostu:

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

Pamiętaj, aby używać -nz echolub w przeciwnym razie znak końca wiersza jest dołączany do ciągu, co zmienia dane i hash.

To polecenie pochodzi z pakietu OpenSSL, który powinien być już zainstalowany (lub łatwy do zainstalowania) w wybranym przez Ciebie systemie Linux / Unix, Cygwin i tym podobnych.

Zwróć uwagę, że starsze wersje openssl(takie jak dostarczana z RHEL4) mogą nie zapewniać takiej -hmacopcji.


Jako rozwiązanie alternatywne, ale głównie po to, aby udowodnić, że wyniki są takie same, możemy również wywołać PHP hmac_sha1()z linii poleceń:

[me@home]$ echo '<?= hash_hmac("sha1", "value", "key") ?>' | php
57443a4c052350a44638835d64fd66822f813319
Shawn Chin
źródło
Implementacje OpenSSL są bardzo wolne. Jeśli musisz to zrobić od czasu do czasu, to w porządku, ale jeśli próbujesz obliczyć ogromne ilości skrótów, chcesz zbadać różne możliwości.
Marcin
1
@Marcin: czy możesz zacytować źródło z tym?
sehe
6
Miałem to samo pytanie z HMAC-SHA256. To samo rozwiązanie, ale sha1zastąpione przez sha256:-)
mogsie
1
Tak, możesz, ale uważaj na podziały wierszy w pliku, ponieważ również to zostanie uznane za część wartości.
Shawn Chin
1
@ShawnChin, w tym przykładzie, jakie jest kodowanie / format klucza? Czy powinno to być kodowanie base64, takie jak klucz prywatny utworzony za pomocą openssl genrsa? Ponadto link do dokumentacji openssl prowadzi do
błędu
41

Oto funkcja bash, która działa jak hash_hmacz 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"
Jaskółka oknówka
źródło
To miły sposób na zakończenie sprawy. +1
Shawn Chin
+1, ponieważ w przeciwieństwie do wybranej odpowiedzi, ta odpowiada na zadane pytanie. (Chociaż oba są pomocne.)
Alexx Roche
ale jak przekazać argument „data” do skryptu, jeśli jest on wieloliniowy? Podobnie jak treść XML lub JSON bez utraty wcięcia.
HyperioN,
@HyperioN jeśli masz danych json w pliku można po prostu to zrobić: hash_hmac "sha1" "$(cat your-json-file)" "key". Alternatywnie możesz po prostu przepuścić plik openssl dgstbez użycia tej hash_hmacfunkcji.
Martin
Dziękuję za bit binarny. To był dla mnie brakujący element
jgreen
9

Dzięki za funkcję hash_hmac! Ale to nie wystarczyło dla mojej aplikacji. Na wypadek, gdyby ktoś się zastanawiał, musiałem kilka razy ponownie haszować coś za pomocą klucza, który był wynikiem poprzedniego hashowania, a zatem jest wejściem binarnym. (Podpis uwierzytelniania Amazon AWS jest tworzony w ten sposób).

Potrzebowałem więc sposobu na dostarczenie klucza binarnego w sposób, który nie złamałby algorytmu. Potem znalazłem to: http://openssl.6102.n7.nabble.com/command-line-hmac-with-key-in-hex-td6754.html

Odpowiedź Stephena Hensona wymaga, aby funkcja hash_hmac zwracała wartość w formacie szesnastkowym. Musi więc odzwierciedlać następujące informacje:

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

Następnie następne wywołanie wymagałoby podania klucza w postaci szesnastkowej:

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

Mam nadzieję, że pomoże to każdemu, prawdopodobnie komuś, kto próbuje stworzyć skrypty bash, aby unieważnić wpisy CloudFront na AWS (jak ja!) (Jeszcze tego nie testowałem, ale myślę, że to jest przyczyną dlaczego mój skrypt bash nie działa, a mój PHP tak ...)

Wouter Thielen
źródło
0

Po zainstalowaniu node.js możesz skorzystać z narzędzia HMAC-CLI :

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

zwroty:

57443a4c052350a44638835d64fd66822f813319
Terite
źródło