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

OpenSSL ECDSA签名比预期长

姬寂离
2023-03-14

我正在尝试生成“原始”的未编码ECDSA签名,用于加密芯片。目标是在主机pc上签名,然后将其发送到芯片进行验证。然而,我遇到了一个小问题。我的理解是ECDSA签名应该是64字节(对于secp256v1)。而且,当我使用芯片生成签名时,它的长度确实是64字节。然而,当我使用openssl时,签名长度为71字节。签名的开头似乎是某种前缀,但我找不到关于它的任何数据。

以下是我尝试做每件事情的方式:

生成密钥:

openssl ecparam -genkey -name secp256r1 -noout -out privkeyv1.pem

生成要签名的“消息”:

echo -n "Hello World" > test.txt

我尝试了两种签署消息的方法。两者都会导致相同的意外输出。

第一种方法 - 生成测试文件的 sha256 哈希值,然后对其进行签名:

sha256sum test.txt | cut -f 1 -d " " > hash

使用pkutil签名

openssl pkeyutl -sign -in hash -inkey privkeyv1.pem -out test_sig_meth1

方法 2: 使用 openssl dgst 签名

openssl dgst-sha256-binary-sign-privkeyv1.pem-out-test_sig_meth2测试。txt问题:这是xxd-p-c 256 test_sig_meth1的输出:3045022000A86FB146D5F8F6C15B962640BC2D1D928F5E0F96A5924E4DB2853EC8B66FB00210085431613D0A235DB1ADABC90CC1062A2246A78941972E298423F4B3D081B48C8

xxd -p -c 256 的输出 test_sig_meth230450220693732cd53d9f2ba3deae213d74cdf69a00e7325a10ddc6a4445ff2b33f95e62022100b6d2561e3afba10f95247ed05f0c59620dc0913f0d798b4148e05c4116b6384e

如您所见,这两种方法在开始时都会生成一些看起来像标头字节的字节(30450220,可能更长),但我不确定它们的用途或如何删除它们。作为参考,这是在加密芯片上生成的相同方法的签名。如果删除末尾的空字节填充,则为 64 个字节。4677AD09F2AF49D7445ED5D6AC7253ADC863EC6D5DB6D3CFBF9C6D3E221D0A7BA2561942524F46B590AEE749D827FBF80A961E884E3A7D85EC75FE48ADBC0BD000000000000000000000000000000000000000

问题:如何使用openssl生成一个64字节的原始(未编码,没有头)ECDSA签名,我可以与此方案一起使用?


共有1个答案

微生青青
2023-03-14

出于效率考虑,大多数芯片将只输出rs,作为字节数组或八位字节字符串,其中每个rs与八位字节中的字段大小(即密钥大小)相同。另一种方法是将<code>r</code>和<code>s</code>作为数字序列输出,因为归根结底,这就是<code>r</code>和<code>s

要从此类序列进行转换,您可以先使用 BER 解析器进行 BER 解码以检索整数。然后实现 I2OSP 算法(整数到八位字节流基元),该算法需要以字节/八位字节为单位的值和密钥大小作为参数。该数字应为大整数形式,但这很好,因为 ASN.1 BER 编码的整数也是大整数。基本上,如果数字太小,则必须将pad保留为零字节。然后连接数字。

我不会讨论将字节数组转换为整数的OS2IP。请注意,如果您以BER形式对其进行编码,则整数不应被零字节填充。因此,仍然需要一些技巧。

所以尽管签名改变了形式,签名仍然有效;您可以简单地在一种形式和另一种形式之间转换,签名仍然会被验证——显然,只要您使用正确的库。

 类似资料:
  • 下面是C 17形式的规则([basic.lval]/8),但它在其他标准中看起来很相似(C 98中是“lvalue”而不是“glvalue”): 8如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义: (8.4)-对应于对象动态类型的有符号或无符号类型 这条规则听起来像是“除非你做X,否则你会得到UB”,但这并不意味着如果你做了X,你就不会得到UB,正如人们所期望的那样

  • 我试图上传图像/视频使用PHP/Javascript到AWS S3 这是我的PHP代码 这是我的Java脚本代码 所有这些功能工作伟大,我想即使在执行它给我文件上传成功消息too.but当我检查s3什么都没有。 即使在控制台中,它也会像下面一样生成预签名URL。但当我尝试单击它时,它会给我SignatureDesNotMatch错误。(请单击URL)。可能是什么错误。。? https://ibra

  • 因为存在安全隐患,如果你能辅助签名过程,最好避免使用自动签名。 在一般情况下,如果你想自动加入大量的客户端,最好在 Puppetmaster 上预先生成证书,然后将其作为构建过程的一部分推送给客户端。 你可以使用 puppet cert --generate <hostname> 命令生成预签名证书(pre-signed certificate)。 操作步骤 使用如下命令为 client1.exa

  • 我需要使用特定的签名配置对产品变种进行签名。我在stackoverflow上找到了一些参考,比如这样和这样。它适用于我的版本风格,但不适用于调试版本。我在 gradle 中有这个配置: 这对于风味非常有效。但是当我使用构建配置时,我的APK没有与签名配置签名。版本已正确签名。 有人知道为什么在调试模式下签名配置没有按配置应用吗?

  • 标题说明一切。这是我的代码; 我使用节点强大的文件。 成功上传后,url变量返回s3 url,类似以下内容; 下面是我的参数 我错过了什么?

  • 如果你想把自己的资源发放给第三方用户访问,但是又不想开放Bucket的读权限,可以通过生成预签名URL的形式提供给用户一个临时的访问URL。在生成URL时,你可以指定URL过期的时间,从而限制用户长时间访问。 生成一个预签名的URL 如下代码: String bucketName = "your-bucket-name"; String key = "your-object-key"; // 设