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


31

如果您在Unix上运行此命令

echo -n "foo" | openssl dgst -sha1

您将获得以下输出:

(stdin)= 0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

(后跟换行符)。

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


@MarkDavidson Hmm,很有趣。您确定它甚至都没有添加换行符吗?

Answers:


22

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

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

会给你这个:

0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33

如果有人决定再次更改文本输出格式,则此方法应具有前瞻性。我确定他们会将前缀固定为“ SHA1(stdin)=”以与文件输入的前缀一致。

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


4
每行仅输出20-30个八位位组(或40-60个字符)。对于SHA-256校验和,有时这还不够。使用该-c 256选项将其扩展到每行256个八位位组。
Rockallite

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

在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

这是完美的情况=>复制并粘贴解决方案图。谢谢!
奥伯斯特(Oberstet)

6

这是另一种选择:

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

1
我知道问题是使用这种特定格式询问的,但是,如果有人尝试将其扩展为包括文件名,则如果文件名中包含空格,则可能会中断。请留意在此居住的其他人。
卡梅隆·加格农

2

这是一种使用bash内置插件而不是管道,awk,sed,tr,cut等方式来实现的方法:

output="$(openssl sha1 <(printf foo))"; echo ${output/* }
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.