bash中的HMAC-SHA1


95

是否有一个bash脚本来生成一个 HMAC-SHA1哈希?

我正在寻找与以下PHP代码等效的内容:

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

Answers:


185

我意识到这并不是您所要的,但是重新发明轮子并编写bash版本毫无意义。

您可以简单地使用openssl命令在脚本中生成哈希。

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

或者简单地:

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

切记-necho否则在字符串后附加一个换行符,这会更改您的数据和哈希。

该命令来自OpenSSL软件包,在您选择的Linux / Unix,Cygwin等操作系统中,应该已经安装(或轻松安装)了OpenSSL软件包。

请注意,较旧的版本openssl(例如RHEL4附带的版本)可能不提供该-hmac选项。


作为一种替代解决方案,但主要是为了证明结果相同,我们还可以hmac_sha1()从命令行调用PHP :

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

OpenSSL的实现非常慢。如果您偶尔需要这样做,那么很好,但是如果您要计算大量的哈希值,则需要研究不同的途径。
Marcin

1
@Marcin:你能引用一个来源吗?
sehe 2011年

6
我对HMAC-SHA256有相同的问题。相同的解决方案,但sha1替换为sha256:-)
mogsie 2012年

1
是的,您可以,但是请注意文件中的换行符,因为这也将被视为值的一部分。
肖恩·金

1
@ShawnChin,在此示例中,密钥的编码/格式是什么?它应该是base64编码,例如使用创建的私钥openssl genrsa吗?此外,OpenSSL文档链接导致404
卡洛斯Macasaet

40

这是一个bash函数,类似于hash_hmacPHP:

#!/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 2013年

但是,如果它是多行,如何将'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

Stephen Henson的答复要求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脚本以使AWS上的CloudFront条目无效的人(像我一样!)(我尚未对其进行测试,但是我认为这就是为什么我的bash脚本的原因不起作用,我的PHP可以...)


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.