実現したいこと
NIST公開テストベクタ(https://csrc.nist.gov/Projects/Cryptographic-Algorithm-Validation-Program/Digital-Signatures#rsa2vs)
の「FIPS 186-4」の「RSA」のボタンからテストベクタをダウンロードし、ダウンロードフォルダ内の「SigGen15_186-3.txt」に秘密鍵(d)の情報をPEM形式(.pem)の情報に変換したいです。
今回変換に使用したNIST公開テストベクタの秘密鍵(d)情報は以下です。
0997634c477c1a039d44c810b2aaa3c7862b0b88d3708272e1e15f66fc9389709f8a11f3ea6a5af7effa2d01c189c50f0d5bcbe3fa272e56cfc4a4e1d388a9dcd65df8628902556c8b6bb6a641709b5a35dd2622c73d4640bfa1359d0e76e1f219f8e33eb9bd0b59ec198eb2fccaae0346bd8b401e12e3c67cb629569c185a2e0f35a2f741644c1cca5ebb139d77a89a2953fc5e30048c0e619f07c8d21d1e56b8af07193d0fdf3f49cd49f2ef3138b5138862f1470bd2d16e34a2b9e7777a6c8c8d4cb94b4e8b5d616cd5393753e7b0f31cc7da559ba8e98d888914e334773baf498ad88d9631eb5fe32e53a4145bf0ba548bf2b0a50c63f67b14e398a34b0d
前提
(申し訳ございませんが、コードは公開できないです。)
C言語でOpenSSLのAPIを使用して、RSA秘密鍵からRSA-PSS署名を生成しようとしています。
コード上でOpenSSLのAPIである「PEM_read_RSAPrivateKey」を使用して、ローカルフォルダにあるPEMファイルの秘密鍵の情報を読みこみたいのですが、エラーメッセージが表示されてPEMファイルの情報を読み込めないです。
エラーメッセージの情報を確認すると、PEM形式になっていないようなので、NIST公開テストベクタの秘密鍵の情報をPEM形式に変換したいです。
試したこと
NIST公開テストベクタをPEM形式に変換したいため、以下の方法を試しました。
【方針】
NISTの秘密鍵をDERフォーマットに直す→Base64フォーマットする→PEMファイル化
DERの符号化のやり方が不明だったため、ChatGPTに質問してその方針通りにDERに変換しました。
DERからPEMへの変換はWebに公開されているツールから変換可能なので、DER符号化のやり方が間違えていると思っています。
##試したこと##
以下DERデータ作成のために今回使用したデータ作成の個別のデータになります。
- 各要素を個別に符号化します。
numberの整数のタグ:0x02
numberの値の長さ:0x01
number=0x05(numberは任意の値でいいので、テキトウな値にしました)
符号化したnumber = 0x02 0x01 0x05
textのUTF8文字列タグ:0x0C
textの長さ=0x0100 (=256)
text=(NISTの秘密鍵データ)
textを符号化:0x0C 0x0100 +(NISTの秘密鍵データ)
- 符号化された要素を連結します。
符号化したnumber:0x02 0x01 0x05
符号化したtext:0x0C 0x0100 +(NISTの秘密鍵データ)
符号化したnumberと符号化したtextを連結したデータ:0x02 0x01 0x05 0x0C 0x0100 +(NISTの秘密鍵データ)
- シーケンス全体を符号化します。
シーケンスのタグ:0x30
連結された要素の長さ:0x105(=符号化したnumberと符号化したtextを連結したもののバイト数が262だったので、-1して261を16進数にした)
最終的なDER符号化は、(シーケンスのタグ)+(連結された要素の長さ)+(符号化したnumberと符号化したtextを連結したデータ)なので、
0x30 0x105 0x02 0x01 0x05 0x0C 0x0100 +(NISTの秘密鍵データ)
になりました。
上記で計算した以下のデータをBase64で変換し、PEM形式で読み込みましたが状況は変わりませんでした。
(おそらくDERの符号化やり方が間違えていると思っています。)
##ここまで##
ChatGPTの回答
■DERの符号化について質問した
Distinguished Encoding Rules (DER)は、ASN.1 (Abstract Syntax Notation One)データ構造をバイナリ形式で符号化するためのルールです。DERは、X.509証明書やPKCS(Public Key Cryptography Standards)などの暗号技術で広く使用されています。
以下に、DERによる符号化の例を示します。
例として、以下のASN.1データ構造を考えます。
MyData ::= SEQUENCE {
number INTEGER,
text UTF8String
}
このデータ構造は、numberという整数とtextというUTF8文字列を含むシーケンスです。このデータ構造をDERで符号化するには、以下の手順に従います。
- 各要素を個別に符号化します。
- number: 整数のタグは 0x02 です。例えば、numberが5の場合、符号化は 0x02 0x01 0x05 となります(0x02はタグ、0x01は長さ、0x05は値)。
- text: UTF8文字列のタグは 0x0C です。例えば、textが"hello"の場合、符号化は 0x0C 0x05 0x68 0x65 0x6C 0x6C 0x6F となります(0x0Cはタグ、0x05は長さ、0x68 0x65 0x6C 0x6C 0x6Fは値)。
- 符号化された要素を連結します。
- 0x02 0x01 0x05(number)と0x0C 0x05 0x68 0x65 0x6C 0x6C 0x6F(text)を連結して、0x02 0x01 0x05 0x0C 0x05 0x68 0x65 0x6C 0x6C 0x6F を得ます。
- シーケンス全体を符号化します。
- シーケンスのタグは 0x30 です。連結された要素の長さは 0x09 です。これらを追加して、最終的なDER符号化は 0x30 0x09 0x02 0x01 0x05 0x0C 0x05 0x68 0x65 0x6C 0x6C 0x6F となります。
このように、DERではASN.1データ構造をバイナリ形式で効率的に符号化できます。また、DERは一意性が保証されているため、署名やハッシュの生成に適しています。
■「連結された要素の長さ」の意味が分からないかったので質問した
「連結された要素の長さ」とは、個別に符号化された要素(この例ではnumberとtext)を連結した後のバイナリデータの長さを指しています。
例では、numberの符号化が 0x02 0x01 0x05 で、textの符号化が 0x0C 0x05 0x68 0x65 0x6C 0x6C 0x6F です。これらを連結して 0x02 0x01 0x05 0x0C 0x05 0x68 0x65 0x6C 0x6C 0x6F を得ます。この連結されたデータの長さは9バイト(0x09)です。
シーケンス全体を符号化する際に、この連結された要素の長さ(9バイト)を使用して、最終的なDER符号化を 0x30 0x09 0x02 0x01 0x05 0x0C 0x05 0x68 0x65 0x6C 0x6C 0x6F と表現します。ここで、0x30はシーケンスのタグ、0x09は連結された要素の長さ、その後に続くバイト列は連結された要素のデータです。
発生している問題・エラーメッセージ
42949672976:error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long:crypto/asn1/asn1_lib.c:101: 42949672976:error:0D068066:asn1 encoding routines:asn1_check_tlen:bad object header:crypto/asn1/tasn_dec.c:1137: 42949672976:error:0D06C03A:asn1 encoding routines:asn1_d2i_ex_primitive:nested asn1 error:crypto/asn1/tasn_dec.c:713: 42949672976:error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error:crypto/asn1/tasn_dec.c:646:Field=version, Type=RSAPrivateKey 42949672976:error:04093004:rsa routines:old_rsa_priv_decode:RSA lib:crypto/rsa/rsa_ameth.c:142: 42949672976:error:0D07207B:asn1 encoding routines:ASN1_get_object:header too long:crypto/asn1/asn1_lib.c:101: 42949672976:error:0D068066:asn1 encoding routines:asn1_check_tlen:bad object header:crypto/asn1/tasn_dec.c:1137: 42949672976:error:0D06C03A:asn1 encoding routines:asn1_d2i_ex_primitive:nested asn1 error:crypto/asn1/tasn_dec.c:713: 42949672976:error:0D08303A:asn1 encoding routines:asn1_template_noexp_d2i:nested asn1 error:crypto/asn1/tasn_dec.c:646:Field=version, Type=PKCS8_PRIV_KEY_INFO 42949672976:error:0907B00D:PEM routines:PEM_read_bio_PrivateKey:ASN1 lib:crypto/pem/pem_pkey.c:88:
補足情報(FW/ツールのバージョンなど)
opensslのバージョン:1.1.1v

0 コメント