DSA 密钥通过以下方式创建:
openssl genpkey -genparam -algorithm DSA -out dsaparams.pem -pkeyopt dsa_paramgen_bits:1024
openssl genpkey -paramfile dsaparams.pem -out dsakey.pem
当我尝试签名时,显示此错误:
echo 'bacon' > text
openssl pkeyutl -sign -in text -inkey dsakey.pem -out sig
Public Key operation error
可以使用openssl dgst -sign
但不能使用上述命令进行签名。
为什么会发生这种情况?man openssl-pkeyutl
DSA 表示允许签名和验证。我使用的是 OpenSSL 1.1.0g
答案1
TLDR:它似乎openssl pkeyutl
被设计用于对哈希进行签名,但却被输入了一个需要哈希的较小文件;OpenSSL 1.1.0g(但不是 OpenSSL 1.0.2g)中的一些检查发现了这个错误。
值得一提的是,当我使用 OpenSSL 1.0.2g 尝试该问题的命令时,没有出现任何错误。但我发现有 3 个原因可能导致失败(首先,应该失败):
openssl pkeyutl
文档中没有说明不执行哈希运算,这应该由外部完成。所以我猜想,当输入文件比预期的要短时,openssl pkeyutl
bark的新版本会失败。问私钥的参数,因为这是唯一合理的做法。这至少与手册页:对于 RSA、ECDSA 和 DSA 签名,此实用程序不会对输入数据执行哈希处理,而是直接将数据用作签名算法的输入。根据密钥类型、签名类型和填充模式,输入数据的最大可接受长度会有所不同。一般而言,对于 RSA,签名数据不能长于密钥模数;对于 ECDSA 和 DSA,数据不能长于字段大小,否则将被默默截断为字段大小。
换句话说,如果 digest 的值是 sha1,则输入应该是 SHA-1 哈希函数输出的 20 字节长的二进制编码。
如今,1024 位 DSA 已被弃用,并且在某些地方(包括一些 SSH 实现)对它的支持已被立即删除。
- 如今,SHA-1 已被弃用。
我建议至少使用 2048 位 DSA、SHA-256,并在计算签名之前对文件进行哈希处理openssl dgst
,当无法进行哈希处理时,最好使用可以先进行哈希处理再进行签名的方法openssl pkeyutl
。我不是 openssl 专家,但我会尝试调查以下内容:
# generate a private key and extract the public key
openssl genpkey -paramfile dsaparams.pem -out dsaprivkey.pem
openssl dsa -in dsaprivkey.pem -pubout > dsapubkey.pem
# create a file "myfile" to be signed
echo 'The Magic Words are Squeamish Ossifrage' > myfile
# create signature "myfile.sig"
openssl dgst -sha256 -sign dsaprivkey.pem myfile > myfile.sig
# verify "myfile" against signature "myfile.sig" and public key
openssl dgst -sha256 -verify dsapubkey.pem -signature myfile.sig myfile
注:前一次尝试使 openssl 1.0.2g 生成具有 160 位的签名问(可能使用 SHA-1)。评论,我将其添加-sha256
到openssl dgst
,但没有什么区别。实验表明-pkeyopt dsa_paramgen_q_bits:256
,即使手册页明确指出-pkeyopt dsa_paramgen_md:sha256
了以下事项:
dsa_paramgen_md:digest
参数生成期间要使用的摘要。必须是sha1
、sha224
或之一sha256
。如果设置,则问将匹配指定摘要的输出大小并且dsa_paramgen_q_bits
参数将被忽略(..)