当前位置: 首页 > 知识库问答 >
问题:

Openssl ECDSA按原样签名输入-无摘要

解阳泽
2023-03-14

我正在尝试用openssl签署现有的摘要。

假设我已经有了一个摘要“mydigest”。尽管如此,我不想使用:

echo -n "mydigest" | openssl dgst -sha256 -sign key.pem | openssl enc -A -base64

我有ECDSA而不是rsa,所以我假设我不应该使用<code>rsautl</code>它按原样使用输入。

所以我的假设是,我需要一些东西来按原样(mydigest)输入,并用我的ECDSA私钥签名。

我尝试了以下方法,以查看使用不同哈希算法创建的哈希大小是否对符号结果有任何影响:

echo -n "mydigest" | openssl pkeyutl -sign -inkey key.pem | openssl enc -A -base64

echo -n "my-very-very-very-long-digest" | openssl pkeyutl -sign -inkey key.pem | openssl enc -A -base64

但就输出长度而言,两个命令的输出大小相同。我会假设大的my-very.。-long-digest 它应该返回更大的输出(因为它应该按原样获取输入而不缩短(哈希)。

========================================

编辑。

也许下面的例子将有助于理解我在问什么。这是一个带有弹力城堡的例子。

 // sign something
String messageToSign = "something_to_sign";
ECDomainParameters domain = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN());
ECDSASigner signer = new ECDSASigner();
signer.init(true, new ECPrivateKeyParameters(privateKey, domain));
MessageDigest digest = MessageDigest.getInstance("Keccak-256");
byte[] hash = digest.digest(messageToSign.getBytes(StandardCharsets.UTF_8));
BigInteger[] signature = signer.generateSignature(hash);

让我们假设我有以下内容:

  1. 散 列。
  2. 钥匙。

现在我想使用openssl创建签名,它应该将哈希作为输入,而不创建哈希。基本上我想替换

BigInteger[] signature = signer.generateSignature(hash);

在openssl的例子中。

openssl * ????? *

我假设结果的大小应该表明我用于哈希的哈希算法(具有不同的摘要大小)是否对结果有任何影响。

共有1个答案

司空温书
2023-03-14

openssl pkeyutl-sign-inkeyecprivkey.pem完全正确。

我认为对于大的my-very...-long-digest,它应该返回更大的输出(因为它应该将输入保持原样而不会缩短(散列)。

你假设错了。ECDSA签名在数学上由两个整数(r,s)组成,范围为1到曲线子组的顺序;它完全不受用作(或)输入的哈希大小的影响。建议使用大小与子组匹配的哈希 - 例如SHA256(或您的Keccak256)与P-256又名secp256r1 - 因为否则,如果哈希太大,它将被截断,或者如果太小,则会被填充并降低安全性。

DSA也是如此,主要是RSA——对于RSA,签名始终是RSA密钥的大小,并且填充小于RSA密钥的编码和填充哈希,但过大的哈希会被拒绝为错误。(这是非常罕见的,因为低于2048位的RSA密钥不再被认为是可接受的安全使用,并且没有人使用那么大的哈希。)

ECDSA 签名表示形式(或编码)的大小可能会有所不同,并且有几种不同的标准。OpenSSL 始终使用 rfc3279 2.2.3 中显示的 ASN.1 集成器序列。默认情况下,Java中的标准SunEC和BouncyCastle提供程序也是如此。ASN.1编码的长度通常仅取决于两个整数的值,正如您正确指出的那样,这两个整数由随机值(k)控制,因此有效地伪随机数本身。请参阅(已添加)长度不一致的 Java ECDSAwithSHA256 签名和(交叉)https://crypto.stackexchange.com/questions/33095/shouldnt-a-signature-using-ecdsa-be-exactly-96-bytes-not-102-or-103 和 https://crypto.stackexchange.com/questions/44988/length-of-ecdsa-signature

Bouncy provider还支持“{hash}和{PLAIN-}CVC-}ECDSA}算法,这些算法具有相同的数学签名,但使用P1363定义的更简单的表示,即两个固定大小(等于子组顺序大小)的(无符号双端)整数串联。编辑:自Java 9以来的SunEC提供程序使用了不同的名称“{hash}”,使用ECDSainp1363format(不知何故,我在第一次编写时错过了这个)。JWS也使用这种表示。最后,您展示的Bouncy LWAPI返回或获取<code>BigInteger[]——数学值,并将编码和解码留给您。

 类似资料:
  • 我有一个关于计算PDF文档摘要以用于数字签名的快速问题(与我前面的一个问题有点相关,我试图弄清楚为什么您需要知道客户的证书以创建正确的摘要)。在Adobe关于PDF格式的文档中,指定了以下内容: 字节范围摘要应在文件中的一个字节范围内计算,该范围应由签名字典中的字节范围条目指示。这个范围应该是整个文件,包括签名字典,但不包括签名值本身(内容条目)。 因此,在这一点上,事情似乎相当简单,只需消化除/

  • 我正在尝试为PDF签名执行以下设置,将其分解为客户端和服务器之间的异步步骤: null 我所做的基本上是将该摘要发送给客户机进行签名,然后在服务器上重做上述步骤并设置客户机签名: 此设置最终导致文件完整性被破坏,因为在服务器上嵌入后,我要创建一个新的PDSignature。有没有一种方法可以序列化调用addSignature后创建的PDDocument,这样我以后就可以在服务器上反序列化它并添加客

  • literal标签可以防止模板标签被解析,所有想原样输出的代码都可以使用这个标签包裹起来,如: <literal> 这里是原样输出的内容{$name} </literal> 如果 js 代码有和模板引擎有冲突的地方也可以使用literal标签包裹起来,防止被解析。

  • 请参考:http://www.kancloud.cn/manual/thinkphp/1820

  • literal标签可以防止模板标签被解析,所有想原样输出的代码都可以使用这个标签包裹起来,如: <literal> 这里是原样输出的内容{$name} </literal> 如果 js 代码有和模板引擎有冲突的地方也可以使用literal标签包裹起来,防止被解析。

  • 可以使用literal标签来防止模板标签被解析,例如: {literal} Hello,{$name}! {/literal} 上面的{$name}标签被literal标签包含,因此并不会被模板引擎解析,而是保持原样输出。 literal标签还可以用于页面的JS代码外层,确保JS代码中的某些用法和模板引擎不产生混淆。 总之,所有可能和内置模板引擎的解析规则冲突的地方都可以使用literal