X.509证书中ECDSA签名的ASN.1结构

问题描述

在分析带有 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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...