"openssl dgst -sha1" 产生一个无关的 "(stdin)=" 前缀和尾随换行符

38 openssl stdin

如果你在你的 Unix 上运行这个命令

echo -n "foo" | openssl dgst -sha1
Run Code Online (Sandbox Code Playgroud)

你会得到这个输出:

(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
Run Code Online (Sandbox Code Playgroud)

(后跟换行符)。

如何强制 openssl 不显示(stdin)=前缀,并避免尾随换行符?

Evi*_*ker 34

原始二进制格式不会添加任何无关的输出。
输出为二进制然后转换为十六进制:

echo -n "foo" | openssl dgst -sha1 -binary | xxd -p
Run Code Online (Sandbox Code Playgroud)

会给你这个:

0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33
Run Code Online (Sandbox Code Playgroud)

如果有人决定再次更改文本输出格式,此方法应该是面向未来的。我确信他们会将前缀修复为“SHA1(stdin)=”,以与文件输入的前缀保持一致。

我不敢相信他们改变了这一点!我想知道有多少脚本被破坏了。

  • 它每行仅输出 20-30 个八位字节(或 40-60 个字符)。对于 SHA-256 校验和,有时这还不够。使用 `-c 256` 选项将其扩展到每行 256 个八位字节。 (10认同)

Gil*_*il' 16

我在 Ubuntu 11.10 上的 OpenSSL 1.0.0e 下观察到这种行为,而 OpenSSL 0.9.8k 和 0.9.8t 只输出散列。OpenSSL 的命令行设计得并不灵活,它更像是一种从命令行执行加密计算的快速而肮脏的方式。

如果要使用 OpenSSL,请过滤输出:

echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //'
Run Code Online (Sandbox Code Playgroud)

在 Linux(使用 GNU 工具或 BusyBox)上,您可以使用sha1sum,它不需要安装 OpenSSL 并且具有稳定的输出格式。它总是打印一个文件名,所以把它去掉。

echo -n "foo" | sha1sum | sed 's/ .*//'
Run Code Online (Sandbox Code Playgroud)

在包括 OSX 在内的 BSD 系统上,您可以使用sha1.

echo -n "foo" | sha1 -q
Run Code Online (Sandbox Code Playgroud)

所有这些都以十六进制输出校验和,后跟换行符。unix 系统下的文本总是由一系列行组成,每行以换行符结尾。如果将命令的输出存储在 shell 变量中,最后的换行符将被剥离。

digest=$(echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //')
Run Code Online (Sandbox Code Playgroud)

如果您需要将输入通过管道传输到需要校验和且没有最终换行符的程序中(这种情况非常罕见),请去掉换行符。

echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //' | tr -d '\n' | unusual_program
Run Code Online (Sandbox Code Playgroud)


小智 8

这是另一种选择:

echo -n "foo" | openssl sha1 | awk '{print $2}'
Run Code Online (Sandbox Code Playgroud)