【问题标题】:Getting different output from openssl when piping file into command将文件传输到命令时从 openssl 获取不同的输出
【发布时间】:2013-05-20 16:52:55
【问题描述】:

我想使用 dsa 密钥和 openssl 签署文件。 DGST(1) 手册页内容如下:

文件...

要消化的一个或多个文件。如果没有指定文件,则 使用标准输入。

对我来说,这意味着以下两个终端命令应该给出相同的结果,但它们没有。我通过od 管道输出,因为结果是二进制的。

  1. 在命令行指定文件

    openssl dgst -dss1 -sign private_key.pem test_archive.zip | od -x
    0000000      2c30    1402    e30d    9073    0059    0de7    f03e    8fd2
    0000020      874b    5252    b025    8f44    1402    ed26    2f55    7fa4
    0000040      f474    0426    1d44    787c    ecd6    5059    921b        
    0000056
    
  2. 将文件输入到 openssl 命令中

    openssl dgst -dss1 -sign private_key.pem < test_archive.zip | od -x
    0000000      2c30    1402    2444    c3a5    f498    7bb8    3dfe    715d
    0000020      e179    c5ad    c0a5    2b16    1402    173b    692b    9d71
    0000040      3970    c497    9994    9cbc    4cfd    d642    62df        
    0000056
    

如您所见,两个输出并不相同,尽管在两种情况下应签名的文件是相同的。

为什么会这样?我在这里遗漏了什么明显的东西吗?

编辑

我在 FreeBSD 上使用 OpenSSL 版本 0.9.8y 2013 年 2 月 5 日,在 Mac OS X 10.7.5 上使用 0.9.8r 版本 2011 年 2 月 8 日,并观察两者的效果。

编辑 2 - 如何生成测试密钥

用于生成适当密钥的小 shell 脚本

#!/bin/bash

openssl=/usr/bin/openssl
${openssl} dsaparam 1024 < /dev/urandom > dsaparam.pem
${openssl} gendsa dsaparam.pem -out private_key.pem
${openssl} dsa -in private_key.pem -pubout -out public_key.pem
rm dsaparam.pem

我还在 CentOS 6 Linux 系统上使用 OpenSSL 版本 1.0.0-fips 进行了测试,结果显示出同样奇怪的行为。

编辑 3 - 测试了更多版本

2013 年 2 月 11 日新编译的 OpenSSL 版本 1.0.1e 也显示了这种行为。

【问题讨论】:

  • 魔术!你确定私钥文件和数据文件都没有改变吗?
  • 两个文件都在我的硬盘上,命令的两个变种一个接一个地直接执行。

标签: shell openssl pipe


【解决方案1】:

我无法重现此(OpenSSL 1.0.1 2012 年 3 月 14 日)。 (我使用的是 RSA 密钥)我认为有三种可能:

  1. OpenSSL 错误 [或不同的默认选项] 您可能有不同的版本存在错误。例如: http://rt.openssl.org/Ticket/Display.html?id=2965
    (我不一定认为是这个特定的错误,但它是相似的。)

  2. 密钥已更改。

  3. 压缩文件已更改


尝试将 -binary 添加到您的命令中。查看#1,可能是我的版本默认执行--binary,不包括摘要类型。

openssl dgst -sha1  </dev/null
(stdin)= da39a3ee5e6b4b0d3255bfef95601890afd80709

openssl dgst -sha1  /dev/null
SHA1(/dev/null)= da39a3ee5e6b4b0d3255bfef95601890afd80709

使用 dsa 密钥,我可以在多个版本的 openssl(1.0.1 和 0.9.8y)中重现这一点

使用 -hex 选项,我还能够确认前缀正在更改。

(1.0.1)

openssl dgst -hex -dss1 -sign private_key.pem config
DSA-DSA(config)= 302e021500ca417b14be6e1c08426d4f4cdb3beb51181e6055021500e6a768689cfe9c6f7538e9ec2f952c9465fea80b

openssl dgst -hex -dss1 -sign private_key.pem <config
(stdin)= 302c02142a59682765ae10e37fe114ca63a21cdf4127ff5302141c8b3ac5caf538a23dc43b20cc9c01b1278c0d8e

(0.9.8 岁)

apps/openssl dgst -hex -dss1 -sign private_key.pem config
DSA(config)= 302e0215008aef560f547425fb4360e24be343fa6db2dc4551021500eb594cea70455400838dc0a14dae7b86614c5218

apps/openssl dgst -hex -dss1 -sign private_key.pem <config    302c02146aa92d6cf2cc9a6fb1d340fed21c29d05f936fc002141fd9e781def4897cfc306b7a68a92b90e6861cb9

注意:所有 4 个命令都有不同的二进制输出。鉴于十六进制哈希相同但前缀不同,推断前缀的差异导致输出的变化似乎是合理的。

【讨论】:

  • 我添加了两个命令 -binary 并没有帮助。另外,我在使用 sha1 函数时没有观察到这种奇怪的行为。
  • 什么版本的openssl? (openssl version)
  • 向主要问题添加了 openssl 版本。
  • 我仍然认为这可能是一个 openssl 错误。我尝试编译 0.9.8y 但不知道如何生成适当的密钥,所以我无法确认。我敢打赌,如果您下载源代码、编译并在 apps/openssl 中试用该版本,它将按预期工作。
  • 我将生成公钥和私钥对的脚本添加到我的问题中。如果你能重现这种行为会很有趣。
【解决方案2】:

OpenSSL 的行为不是错误。如果文件通过标准输入管道输入或在命令行中指定,则创建的签名不同,但如果使用测试,则两个输出都是有效的签名

openssl dgst -dss1 -verify public_key.pem -signature file_with_archive_signature.sig test_archive.zip

因此,我认为不看算法,每个文件都有多个有效签名,但签名仅对一个文件有效(忽略冲突)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-08
    • 2014-09-28
    • 2011-05-21
    相关资源
    最近更新 更多