为什么SM2算法签名结果不是64字节?
SM2算法正常不进行编码的签名长度为64个字节,即为R+S,各32个字节;密钥管理服务(KMS)针对签名结果使用ASN.1进行编码。
根据SM2密码算法使用规范,SM2算法签名数据格式的ASN.1定义为:
SM2Signature ::= SEQUENCE{ R INTEGER,-- 签名值的第一部分 S INTEGER -- 签名值的第二部分}
其中R和S的长度各为256位。但是在大数INTEGER做der编码时,如果首字节的第一个二进制位为1时,前面需要补00字节,所以导致der编码长度多一个字节,这种情况下SM2签名值的编码长度最大会有两个字节的差距。
其中R和S分别对应:
70个字节,R值,S值均不补00:3044+0220+32个字节R+0220+32个字节S
71个字节,(1)R值补00:3045+022100+32个字节R+0220+32个字节S (2)S值补00:3045+0220+32个字节R+022100+32个字节S
72个字节,R值,S值均补00:3046+022100 +32个字节R+022100+32个字节S
部分特殊场景会存在69字节。R或S的数据存在前导0时,在实际编码过码中,会删掉前导00的长度。但不是所有情况都会删除前导0。是否删除,取决于其后一个字节是否存在补位(即第一个字节最高位是否为1)。
ASN.1整体按照TLV三元组<Type,Length,Value>进行存储。
关于0x30和0x02,是ASN.1的tag标志域,指明数据类型,占用一个字节。BER_TYPE_INTEGER 0x02 BER_TYPE_SEQUENCE 0x30
0x44,0x45,0x46表明SEQUENCE的长度,分别对应70,71和72字节。
0x20 表明INTEGER的长度,对应32字节。