无法使用 DSA 签名

无法使用 DSA 签名

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-pkeyutlDSA 表示允许签名和验证。我使用的是 OpenSSL 1.1.0g

答案1

TLDR:它似乎openssl pkeyutl被设计用于对哈希进行签名,但却被输入了一个需要哈希的较小文件;OpenSSL 1.1.0g(但不是 OpenSSL 1.0.2g)中的一些检查发现了这个错误。


值得一提的是,当我使用 OpenSSL 1.0.2g 尝试该问题的命令时,没有出现任何错误。但我发现有 3 个原因可能导致失败(首先,应该失败):

  1. openssl pkeyutl文档中没有说明不执行哈希运算,这应该由外部完成。所以我猜想,当输入文件比预期的要短时,openssl pkeyutl bark的新版本会失败。私钥的参数,因为这是唯一合理的做法。这至少与手册页

    对于 RSA、ECDSA 和 DSA 签名,此实用程序不会对输入数据执行哈希处理,而是直接将数据用作签名算法的输入。根据密钥类型、签名类型和填充模式,输入数据的最大可接受长度会有所不同。一般而言,对于 RSA,签名数据不能长于密钥模数;对于 ECDSA 和 DSA,数据不能长于字段大小,否则将被默默截断为字段大小。

    换句话说,如果 digest 的值是 sha1,则输入应该是 SHA-1 哈希函数输出的 20 字节长的二进制编码。

  2. 如今,1024 位 DSA 已被弃用,并且在某些地方(包括一些 SSH 实现)对它的支持已被立即删除。

  3. 如今,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)。评论,我将其添加-sha256openssl dgst,但没有什么区别。实验表明-pkeyopt dsa_paramgen_q_bits:256,即使手册页明确指出-pkeyopt dsa_paramgen_md:sha256了以下事项:

dsa_paramgen_md:digest
参数生成期间要使用的摘要。必须是sha1sha224或之一sha256。如果设置,则将匹配指定摘要的输出大小并且dsa_paramgen_q_bits参数将被忽略(..)

相关内容