问题描述
在分析带有 ECDSA 签名的 X.509 证书时,我发现了一个无法解释的 0x00 字节。
X.509 证书的签名应在 ASN.1 BIT STRING 结构中给出。
对于 ECDSA,签名由两个整数 (r,s) 组成,编码为两个 ASN.1 INTEGER 的 ASN.1 SEQUENCE。
在我的例子中(用 openssl 生成)我得到了这个:
ASN.1 tag for BIT STRING
| length
| |
| | ASN.1 tag for SEQEUNCE
| | | length
| | | |
| | | | ASN.1 tag for INTEGER ASN.1 tag for INTEGER
| | | | | length | length
| | | | | | | |
| | | | | | 0x21 bytes integer value | | 0x21 bytes integer value
| | | | | | ____________|____________ | | ____________|____________
v v v v v v / \ v v / \
... 03 49 00 30 46 02 21 00 D5 F4 76 43 ... A2 BD 95 02 21 00 DF 01 30 24 ... 50 12 32
^
|
why is there a 0x00 byte?
为什么在 ASN.1 SEQUENCE 标签之前有一个额外的 0x00 字节?
解决方法
ASN.1 BIT_STRING
的第一个八位字节是 Unused Bits
指示符。位串并不总是与完整的八位字节(1 字节)对齐。由于最小编码数据大小为 1 字节,Unused bits
将存储编码值中未使用的位数。例如,您的数据长度正好是 11 位。要编码 11 位长字符串,您将使用 2 个字节,16 位。但是,您必须通过将 Unused Bits
八位字节设置为 5 (16-11) 来指示您的数据长度为 11 位。 Unused Bits
八位字节的可能值为 0-7。更多详情:https://docs.microsoft.com/en-us/windows/win32/seccertenroll/about-bit-string