如何DER编码ecdsa签名

时间:2019-02-16 00:37:23

标签: javascript cryptography

WebCrypto产生一个64字节的ECDSA签名字符串。我需要使用javascript将其转换为DER编码的字符串。我该怎么办?

到目前为止,我只发现了nodejs和c实现。

1 个答案:

答案 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编码。


优化:

  • 一个好的程序员将能够优化整数的最小尺寸;
  • 优秀的程序员会构建一棵ASN.1对象树,并让它们返回DER编码的大小,以便从左到右对整个结构进行编码;
  • 专业的程序员将构建一个ASN.1编译器,该编译器将创建源代码来为他执行此操作;
  • Wizz会考虑在运行时进行所有操作。

一个实用的程序员会注意到,对于64字节的结构和一些开销,这些优化是完全多余的,只需遵循上述过程即可-除非(当然)该功能的一部分已经在其他地方出现了。


不熟悉问题分解的程序员所需的方法:

convertToX9_63(flatSignature)

之后

createDERInteger(staticSizedInteger)
toDERIntegerEncoding(staticSizedInteger)

当然,

createDERSequence(value)

和实用程序功能

createDER(tag, value)
createDERLength(valueSize)

编程愉快。