WebCrypto产生一个64字节的ECDSA签名字符串。我需要使用javascript将其转换为DER编码的字符串。我该怎么办?
到目前为止,我只发现了nodejs和c实现。
答案 0 :(得分:0)
我将在下面描述将静态大小的“平坦”签名格式转换为DER结构的DER的一般方法。您需要能够对字节和字节缓冲区执行操作才能做到这一点。
R和S分量(每个32个字节用于256位曲线的签名)(例如,用于BitCoin的P-256或secpk256r1)是两个数字,均被编码为静态大小的无符号大端整数。
您需要的是一个包含两个INTEGER值的ASN.1 SEQUENCE结构。这些结构使用DER编码进行编码,DER编码是TLV(标签,长度,值)编码。
SEQUENCE编码只是设置为字节值30
的标签,然后是长度编码,然后是两个INTEGER结构的串联。 DER的INTEGER编码由02
标签组成,该标签又是值的长度编码,然后是 signed ,最小尺寸的编码数字的大端编码。
由于您不知道整数的大小-毕竟使用最少的编码-最好首先为这些小型结构构建较小的组件;我们将使用自下而上的过程。创建一个函数,该函数创建给定无符号数字的DER编码。该过程很简单:删除所有最左(最重要)的00
值字节。如果下一个字节为128(或十六进制00
)或更高,则在左侧添加一个80
。其余两种编码都是大端优先的。
现在将长度编码添加到整数。如果长度小于大小的128(或十六进制80
),则长度仅为一个字节。如果它更大,则为两个字节:一个字节设置为81
,这表示后面将是一个长度字节,而另一个字节则包含实际值。如果它在[256,65536)范围内,则编码为3个字节:将1个字节设置为82
,表示将跟随两个长度的字节,并且对长度进行1个2字节的大端编码。
在R和S的长度和数字编码之前添加INTEGER标签02
。
太好了,现在您应该有两个ASN.1 / DER编码的R和S整数。您需要将这两个连接起来以获得SEQUENCE的值。按照对整数值说明的相同长度编码,计算SEQUENCE的长度。在其前面添加SEQUENCE标签30
,然后进行DER编码。
优化:
一个实用的程序员会注意到,对于64字节的结构和一些开销,这些优化是完全多余的,只需遵循上述过程即可-除非(当然)该功能的一部分已经在其他地方出现了。
不熟悉问题分解的程序员所需的方法:
convertToX9_63(flatSignature)
之后
createDERInteger(staticSizedInteger)
toDERIntegerEncoding(staticSizedInteger)
当然,
createDERSequence(value)
和实用程序功能
createDER(tag, value)
createDERLength(valueSize)
编程愉快。