2

我想使用 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

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

编辑 3 - 测试了更多版本

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

4

2 回答 2

2

我无法重现此 (OpenSSL 1.0.1 14 Mar 2012) 。(我使用的是 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 个命令都有不同的二进制输出。鉴于十六进制哈希相同但前缀不同,推断前缀的差异导致输出的变化似乎是合理的。

于 2013-05-20T17:24:17.623 回答
0

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

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

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

于 2013-05-21T17:01:58.047 回答