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

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

如果您在 Unix 上运行此命令

echo -n "foo" | openssl dgst -sha1

您将得到以下输出:

(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

(后跟换行符)。

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

答案1

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

echo -n "foo" | openssl dgst -sha1 -binary | xxd -p

会给你这个:

0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

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

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

答案2

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

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

echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //'

在 Linux 上(使用 GNU 工具或 BusyBox),您可以使用sha1sum,不需要安装OpenSSL,并且具有稳定的输出格式。它总是打印文件名,因此请将其删除。

echo -n "foo" | sha1sum | sed 's/ .*//'

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

echo -n "foo" | sha1 -q

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

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

如果您需要将输入通过管道传输到需要校验和且没有最终换行符的程序(这确实很少见),请去掉换行符。

echo -n "foo" | openssl dgst -sha1 | sed 's/^.* //' | tr -d '\n' | unusual_program

答案3

这是另一种选择:

echo -n "foo" | openssl sha1 | awk '{print $2}'

答案4

这是使用 bash 内置函数而不是管道、awk、sed、tr、cut 等来完成此操作的方法:

output="$(openssl sha1 <(printf foo))"; echo ${output/* }

相关内容