将文件传递到命令时从openssl获取不同的输出

时间:2013-05-20 16:52:55

标签: shell openssl pipe

我想使用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
    
  3. 正如您所看到的两个输出都不相同,尽管在两种情况下应签名的文件都是相同的。

    为什么会这样?我错过了一些明显的东西吗?

    修改

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

    编辑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也显示了这种行为。

2 个答案:

答案 0 :(得分:2)

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

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

  2. 密钥已更改。

  3. zipfile已更改


  4. 尝试在命令中添加-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.8y)

    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个命令都有不同的二进制输出。鉴于十六进制哈希值相同但前缀不同,推断前缀中的差异导致输出中的更改似乎是合理的。

答案 1 :(得分:0)

OpenSSL的行为不是错误。如果文件在via stdin中传送或在命令行中指定,则创建的签名是不同的,但如果使用

进行测试,则两个输出都是有效的签名
openssl dgst -dss1 -verify public_key.pem -signature file_with_archive_signature.sig test_archive.zip

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