EVP_DigestSignFinal()は、DERエンコードされた署名を私に与えます。
いくつかの例:
ECDSA-SHA-256
30 44 02 20 [..r..] 02 20 [..s..]
30 46 02 21 [..r..] 02 21 [..s..]
30 45 02 20 [..r..] 02 21 [..s..]
ECDSA-SHA-224
30 3d 02 1c [..r..] 02 1d [..s..]
30 3c 02 1c [..r..] 02 1c [..s..]
サイズは変わる可能性があるので、それらを連結したいと思います。署名が何バイトになるかを知る良い方法は何ですか?あるいは、OpenSSLにすでに実装されている機能があるのでしょうか?
ECDSAシグニチャーは、2つのSEQUENCE
値のINTEGER
である ASN.1 構造としてエンコードされます。エンコードされると、最初のバイトは0x30
(SEQUENCE
を意味します)で続き、1バイトまたは2バイトでエンコードされた長さが続きます。長さがnバイトの場合、値の1バイトとしてエンコードされますnif n≤127、または2バイトの値0x81
thenn、128≤n≤255(後者は、P-521のような「大きな」曲線を使用する場合に発生する可能性があります)。これらのnバイトは、2つのINTEGER
値を連結したもので、それぞれに独自のタグ(値のバイト0x02
)、次にその長さ(同じエンコーディング。実際には、1バイト以上。1000ビット程度の曲線が必要になるため、複数の曲線が必要になるため)、次にINTEGER
値。 INTEGER
の値は符号付きビッグエンディアンを使用します(そのため、値の先頭バイトが0x00
になる場合があります)。
ASN.1構造を適切にエンコードおよびデコードすることは難しい技術です。 OpenSSLにそのためのパブリック関数があるかどうかはわかりません。 この関数 、 別のSSLライブラリ から、ASN.1から「未加工」のECDSA署名に変換します(「未加工」とは、2つの整数値が単にビッグエンディアンでエンコードされていることを意味します)と連結され、どちらも同じエンコード長になるように調整されます)。