HMAC-SHA1 в bash


95

Чи існує скрипт bash для генерації HMAC-SHA1хешу?

Я шукаю щось еквівалентне наступному коду PHP:

hash_hmac("sha1", "value", "key");

Відповіді:


185

Я розумію, що це не зовсім те, про що ви просите, але немає сенсу винаходити колесо і писати версію bash.

Ви можете просто використовувати opensslкоманду для створення хешу у вашому сценарії.

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

Або просто:

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

Чи не забувайте використовувати -nз echoабо ще символ розриву рядка додається в рядок і змінює дані і хеш.

Ця команда походить від пакету OpenSSL, який уже слід встановити (або легко встановити) у вашому виборі Linux / Unix, Cygwin та подібних.

Зверніть увагу, що старіші версії openssl(наприклад, що постачаються з RHEL4) можуть не надавати цю -hmacопцію.


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

[me@home]$ echo '<?= hash_hmac("sha1", "value", "key") ?>' | php
57443a4c052350a44638835d64fd66822f813319

Впровадження OpenSSL відбувається дуже повільно. Якщо вам потрібно це робити іноді, це нормально, але якщо ви намагаєтеся розрахувати величезну кількість хешів, ви хочете дослідити різні шляхи.
Марцін

1
@Marcin: чи можете ви цитувати це джерело?
sehe

6
У мене було те саме питання з HMAC-SHA256. Те саме рішення, але sha1замінено на sha256:-)
mogsie

1
Так, ви можете, але слідкуйте за розривами рядків у вашому файлі, оскільки це також вважатиметься частиною значення.
Шон Чін

1
@ShawnChin, у цьому прикладі, яке кодування / формат ключа? Це має бути кодування base64, як закритий ключ, створений за допомогою openssl genrsa? Крім того, посилання на документацію openssl дає 404.
Карлос Макасает,

40

Ось функція 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, оскільки на відміну від обраної відповіді, цей відповідає на поставлене запитання. (Хоча обидва корисні.)
Алекс Рош

але, як ви передаєте аргумент 'data' до сценарію, якщо він є багаторядковим? Як і тіло xml або json без втрати відступу.
HyperioN

@HyperioN , якщо у вас є дані JSON в файл , який ви могли б просто зробити це: hash_hmac "sha1" "$(cat your-json-file)" "key". Крім того, ви можете просто передати файл openssl dgstбез використання цієї hash_hmacфункції.
Мартін

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/^.* //'

Тоді для наступного дзвінка потрібно буде надати ключ як hexit:

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

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


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.