OpenSSLのi2d_RSAPublicKey()とi2d_RSA_PUBKEY()の違い

OpenSSL(正確にはlibeay32/libcrypto)のi2d_RSAPublicKey()とi2d_RSA_PUBKEY()の違いについて日本語のページが見つからなかったので、分かったことをまとめておきます。

i2d_RSAPublicKey()とi2d_RSA_PUBKEY()の違い

i2d_RSAPublicKey()とi2d_RSA_PUBKEY()は両方ともRSA構造体をDER形式の公開鍵に変換する関数です。

では、この2つがどう違うのか?いろいろ調べてこのページを見つけました。

marc.info

簡単に説明するとこんな感じです。

i2d_RSAPublicKey()はRFC 3447で定義されるRSAPublicKey structure形式に変換される
RFC 3447 - Public-Key Cryptography Standards (PKCS) #1: RSA Cryptography Specifications Version 2.1

i2d_RSA_PUBKEY()はRFC 5280で定義されるSubjectPublicKeyInfo structure形式に変換される
RFC 5280 - Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile

後者はX.509証明書内の公開鍵の形式で、OpenSSLのrsaコマンドなどは後者のフォーマットを使用します。

つまり、OpenSSLで使用できる公開鍵を生成するには、i2d_RSA_PUBKEY()を使う必要があるということです。

秘密鍵(鍵ペア)をDER形式に変換するにはi2d_RSAPrivateKey()を使うので、ついついi2d_RSAPublicKey()を使ってしまいそうになりますが違うんですね。

ちなみに、i2d_RSA_PUBKEY()やi2d_RSAPrivateKey()は以下のように使います。

int len;
unsigned char* buf;
unsigned char* next;

//
// keyはRSA構造体で鍵情報が入っているとする
//

// 公開鍵
len = i2d_RSA_PUBKEY(key, NULL);
buf = next = (unsigned char*)malloc(len);
i2d_RSA_PUBKEY(key, &next);    // bufに公開鍵がDER形式で展開される
free(buf);

// 秘密鍵
len = i2d_RSAPrivateKey(key, NULL);
buf = next = (unsigned char*)malloc(len);
i2d_RSAPrivateKey(key, &next);  // bufに秘密鍵がDER形式で展開される
free(buf);