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.