生成,签名和验证数字签名

时间:2016-11-12 17:03:30

标签: openssl signature

所以这是我项目中的一个问题。

  

在此任务中,我们将使用OpenSSL生成数字签名。请准备任何大小的文件(example.txt)。还准备RSA公钥/私钥对。然后执行以下操作:

     
      
  1. 签署example.txt的SHA256哈希值;保存example.sha256中的输出。
  2.   
  3. 验证example.sha256中的数字签名。
  4.   
  5. 稍微修改example.txt,然后再次验证数字签名。
  6.         

    请描述您是如何执行上述三项操作的(例如,您使用的确切命令等)。描述您观察到的内容并解释您的观察结果。还请解释为什么数字签名一般有用。

所以,我做了以下几点。

1.创建私钥/公钥对

openssl genrsa -out private.pem 1024

2。提取公钥。

openssl rsa -in private.pem -out public.pem -outform PEM -pubout

第3。创建数据的哈希值。

echo 'data to sign' > example.txt

openssl dgst -sha256 < example.txt > hash

4。使用私钥将哈希签名到名为example.sha256

的文件
openssl rsautl -sign -inkey private.pem -keyform PEM -in hash  > example.sha256

5。验证文件(example.txt)和数字签名(example.sha256)

openssl dgst -sha256 -verify public.pem -signature example.sha256 example.txt

完成所有这些操作后,收到错误消息“验证失败

如果我在某个地方出错,请纠正我。

2 个答案:

答案 0 :(得分:3)

请勿使用rsautl

根据PKCS1.5,当签署进入RSA操作的数据格式时,看起来像这样:

<padding><metadata><hash of input>

(元数据指定使用了哪个散列函数。)

当您尝试验证签名时,此格式是openssl dgst -verify正在寻找的格式。但是,这不是您在步骤中创建的内容。

首先,openssl dgst的默认输出是结果哈希的十六进制编码,而不是原始字节。

其次,rsautl相当“低级别”,并且在签名时不添加openssl dgst -verify期望的元数据,尽管它确实添加了填充。

这两件事共同意味着您使用的数据如下所示:

<padding><hex digits of hash of input>

显然这与openssl dgst -verify所期望的不匹配,因此验证失败。

可以为rsautl创建格式正确的输入,但它很尴尬并且涉及处理ASN.1细节。您也可以使用rsautl -verify代替dgst -verify,但这也需要更多细节,这意味着您使用的是非标准签名格式。

最简单的解决方案是使用openssl dgst来创建和验证签名。使用单个命令替换步骤3和4(创建example.txt文件除外):

$ openssl dgst -sha256 -sign private.pem -out example.sha256 example.txt

这会散列数据,正确格式化散列并执行RSA操作。生成的文件应使用openssl dgst -verify命令正确验证。

答案 1 :(得分:1)

感谢Matt的解决方案。小尼特: OP似乎要对散列而不是实际的整个数据进行签名(这也是我希望做的事情)。因此,请使用下面的代码来生成签名:

openssl dgst -sha256 -sign private.pem -out hash.sig哈希

并在下面验证签名

openssl dgst -sha256-验证public.pem -signature hash.sig哈希

最后是类似下面的内容,以验证有效载荷的完整性:

回显“ hash example.txt” | sha256sum -c --strict