2008年3月7日金曜日

PublicKey 情報が一致しない

先日、.pfx ファイル経由でプライベートキーを Windows の証明書ストアに登録しました。その際に、Windows の証明書マネージャで内容を確認したところ、「PublicKey」の詳細情報が CertMgr の PublicKey 情報と一致しないことに気づきました。

例えば、ある証明書の PublicKey が Windows の証明書マネージャの表示では 140 オクテットの
30 81 89 02 81 81 00 be 02 58 78 d1 4e 7f ea bd
32 aa 23 8c d6 2a 88 81 59 63 26 81 c6 0c 87 31
43 5e 9b a7 c0 9a 0d e1 cd c9 b5 c9 6a e0 0e 19
           …【中略】…
ae c7 91 f0 0c 4a 1d d1 f0 be 25 93 aa c4 f9 49
9a 35 1a f1 3c c7 11 02 03 01 00 01

となっているとします。同じ証明書を CertMgr で開き、PublicKey フィールドを読み取って得られる
-----BEGIN RSA PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+Alh40U5/6r0yqiOM1iqIgVljJoHGDIcxQ16b
                  …【中略】…
fw/rLw6xXDpnPOJjSe0hVRB50W6ux5HwDEod0fC+JZOqxPlJmjUa8TzHEQIDAQAB
-----END RSA PUBLIC KEY-----

をデコードしてみると、162 オクテットの
30 81 9f 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01
05 00 03 81 8d 00
30 81 89 02 81 81 00 c1 e5 95
15 4e 89 3c 8d 6a c4 2e 4f d5 d8 0f 28 ed 9e 3b
            …【中略】…
2d 65 94 d9 2d 2d 6e bf 45 e8 e0 d6 d9 02 03 01
00 01

というデータが格納されていました。このデータは Windows の証明書マネージャの提示する PublicKey 情報とは一致しません。よくよく見てみると、CertMgr で読み取った方には先頭に余分な 22 オクテット (薄ピンクの網掛け部分) が付加されています。その後ろに続く140オクテットは、Windows の証明書マネージャで表示される PublicKey と一致しています。

このデータは DER エンコードされた ASN.1 オブジェクトですので、その構造を解析してみると以下のようになっていました。
SEQUENCE {
SEQUENCE {
OBJECTID: 1.2.840.113549.1.1.1 (RSA Encryption)
NULL
}
BITSTRING:

30 81 89 02 81 81 00 be 02 58 78 d1 4e 7f ea bd
32 aa 23 8c d6 2a 88 81 59 63 26 81 c6 0c 87 31
 …【中略】…
ae c7 91 f0 0c 4a 1d d1 f0 be 25 93 aa c4 f9 49
9a 35 1a f1 3c c7 11 02 03 01 00 01
(unused bits: 0)
}

薄ピンクの網掛け部分が、先のデータの網掛け部分に該当しています。この部分には、鍵の暗号化アルゴリズムの情報が格納されていました。しかし、この情報は PublicKeyAlgorithm フィールドから得られるはずです。なぜこの情報を PublicKey フィールドの値に埋め込むのか開発部隊に確認してみたところ、次のような回答がありました。
  • RSA アルゴリズムの場合は PublicKeyAlgorithm で得られる情報のみで事足りるが、現在は RSA の他 DSA もサポートしている。こちらの場合、前記の ASN.1 フォーマットでは NULL となっている箇所にアルゴリズム用のパラメータを格納する必要がある。
  • しかし、現在のフィールド構成ではそのデータを取得するためのフィールドは存在していない。かといって、今後新たなアルゴリズムが追加されるたびに個別にフィールドを追加するのは大変だ。
  • 従って、PublicKey フィールドの値として返すデータにこの部分を含めることにした。実際、PublicKey として BITSTING 部分を使用する場合にはそのデータが何であるかを提示する必要があるので、この形式を PublicKey として返すことに問題はないはずだ。生の BITSTRING 部分が必要なのであれば、比較的簡単な手順で取り出すことも可能だ。

ある証明書に対し、CertMgr で得られる PublicKey が Windows (や Mozilla/Thunderbird) の提示するデータと異なるのはこういうことなのでした。

0 件のコメント: