You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ZCertificate/ZCrypto签名值编码方式及与OpenSSL差异咨询

ZCertificate/ZCrypto与OpenSSL签名值差异的转换方法

问题背景

OpenSSL输出的签名值是带冒号分隔的十六进制:

ba:de:13:f9:3f:af:4b:c2:01:48:2e:33:9c:23:15:93:a1:d4:21:d8:f4:14:c0:5f:0e:53:38:f2:16:96:a8:9c:b6:ae:69:af:1c:94:27:ea:e3:71:63:03:7f:38:53:de:28:e4:ef:ab:04:dd:eb:39:2e:9f:59:1a:12:0f:f8:61:09:78:16:95:44:7f:3a:05:81:01:7a:ca:d2:38:69:5e:41:e8:aa:7d:ea:01:ba:d2:0e:d7:49:bd:8e:8e:35:d9:77:3a:3b:0b:89:97:03:b8:3c:c9:70:43:99:f9:c9:8f:95:2c:e6:2d:1a:60:9e:c6:b1:b4:d7:cf:07:78:35:ec

而ZCertificate输出的是Base64字符串:

nkarw83ve0xgkiaut9h4zicr+tiw5zkna4aph3ggml4/cl5c4f3wjb2r1fc4mlpelcjaplknuvf3qqbof+ydz1sidigzcf8masymklb17foszi2ppxmwritis/dja3nm7pwnoggq1ss6dw80dsvbnp3t7mfgnnpjetmgckwd/pe=

直接对OpenSSL的十六进制(带/不带冒号)做Base64编码完全匹配不上,核心原因是ZCrypto对签名值做了特殊处理。

关键原因:RightAlign()的作用

ZCrypto的x509库中out.Signature = in.SignatureValue.RightAlign()这句代码,是把ASN.1 DER编码的签名值转换成了去掉前导零的r+s拼接格式:

  • 标准RSA签名在ASN.1 DER里是SEQUENCE { r INTEGER, s INTEGER }的结构,每个整数可能带有前导零字节(用于保证是正数)
  • RightAlign()会分别提取r和s这两个整数,去掉它们的前导零字节,然后把两个字节数组直接拼接,最后对拼接后的结果做Base64编码,得到ZCertificate输出的字符串。

从OpenSSL签名转成ZCertificate输出的步骤

  • 清理OpenSSL输出:去掉所有冒号,得到连续的十六进制字符串:
    bade13f93faf4bc201482e339c231593a1d421d8f414c05f0e5338f21696a89cb6ae69af1c9427eae37163037f3853de28e4efab04ddeb392e9f591a120ff86109781695447f3a0581017acad238695e41e8aa7dea01bad20ed749bd8e8e35d9773a3b0b899703b83cc9704399f9c98f952ce62d1a609ec6b1b4d7cf077835ec
    
  • 解析ASN.1 DER结构:把上面的十六进制转成字节数组,解析出其中r和s两个整数的字节内容(跳过DER编码的标签、长度头部)。
  • 去除前导零:分别对r和s的字节数组去掉开头的0x00字节(如果有的话)。
  • 拼接字节数组:把处理后的r和s字节数组按顺序拼接成一个新的字节数组。
  • Base64编码:对拼接后的字节数组做标准Base64编码(非URL安全,用+和/,末尾补=),得到的就是ZCertificate输出的签名字符串。

示例验证

拿你提供的例子来说:

  • 解析OpenSSL的DER签名后,r的原始字节去掉前导零后是ba de 13 f9 3f af 4b c2 01 48 2e 33 9c 23 15 93 a1 d4 21 d8 f4 14 c0 5f 0e 53 38 f2 16 96 a8 9c b6 ae 69 af 1c 94 27 ea e3 71 63 03 7f 38 53 de 28 e4 ef ab 04 dd eb 39 2e 9f 59 1a 12 0f f8 61 09 78 16 95 44
  • s的原始字节去掉前导零后是3a 05 81 01 7a ca d2 38 69 5e 41 e8 aa 7d ea 01 ba d2 0e d7 49 bd 8e 8e 35 d9 77 3a 3b 0b 89 97 03 b8 3c c9 70 43 99 f9 c9 8f 95 2c e6 2d 1a 60 9e c6 b1 b4 d7 cf 07 78 35 ec
  • 拼接这两部分后做Base64编码,正好得到ZCertificate输出的字符串。

内容的提问来源于stack exchange,提问作者dslsmy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:47:53