OpenSSL証明書操作/VeriSign

昨日は何でまた終電帰りかというと。某データセンタに行ってロードバランサの設定を頼まれたのでやっていたのだが(別件で行っていたのだけど、臨時で当日仕事を振られた)。
で、証明書渡されて、LBにインポートして設定しとけと。渡された証明書は VeriSign で署名してもらった物で、ファイルのテキストだけぽろっと渡されたのね。てっきり PEM 形式の証明書だと思ったのだけど、インポートしてみたら、LBで証明書が読めない(証明書だと認識されない)でやんの。なんだこれは、ということでごにょごにょやって、問題がわかるまでに時間をつぶしてしまった。

問題は何だったのか?

に基づいて証明書(hoge.txt)を表示してみようとした。

$ openssl x509 -in hoge.txt -text
unable to load certificate
5504:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1294:
5504:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:380:Type=X509_CINF
5504:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:tasn_dec.c:749:Field=cert_info, Type=X509
5504:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:pem_oth.c:83:

うごかねえ。で、エラーメッセージをいろいろ検索してたどり着いたのがこれ。

ということで、PEMじゃなくて p7b (PKCS#7) なんだとさ。

サーバ「Microsoft」で申請すると p7b になるんだそうな。前に VeriSign の証明書使ったときは Linux だったからこう言うのがなかったのか…。ってかそういうことは証明書渡すときに一緒に教えてくれよ…。

まあそれは仕方がないとして、OpenSSLで変換しようかと。

$ openssl pkcs7 -inform der -in hoge.txt -out fuga.pem -print_certs
unable to load PKCS7 object
3968:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1294:
3968:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:380:Type=PKCS7

あれ?
どうも inform はつけないでよいみたい。あ、DER ってバイナリか? (ファイル形式をよく理解していない)

$ openssl pkcs7 -in hoge.txt -print_certs
subject=/C=JP/ST=****/L=****/O=****/OU=****/OU=****/OU=Authenticated by VeriSign Japan K.K./OU=Member, VeriSign Trust Network/CN=****
issuer=/O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign
-----BEGIN CERTIFICATE-----
(省略)
-----END CERTIFICATE-----

subject=/O=VeriSign Trust Network/OU=VeriSign, Inc./OU=VeriSign International Server CA - Class 3/OU=www.verisign.com/CPS Incorp.by Ref. LIABILITY LTD.(c)97 VeriSign
issuer=/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
-----BEGIN CERTIFICATE-----
MIIDgzCCAuygAwIBAgIQRvzrurTQLw+SYJgjP5MHjzANBgkqhkiG9w0BAQUFADBf
(中略)
6UlIE0uDihtIeyT3ON5vQVS4q1drBt/HotSp9vE2YoCI8ot11oBx
-----END CERTIFICATE-----

こんな感じになる。下のはVeriSignの中間証明書だ。上のが署名してもらったサーバ証明書なので、BEGIN/END CERTIFICATE のところがPEM形式の証明書になっている。

ちなみに上のコマンドに -text をつけると細かい内容確認ができるので、この辺のコマンドを試しつつ証明書の形式確認はちゃんとやろうね、ということかな。まあそもそも、最初に x509 -text で確認しようとしたときにエラーが出たのだけど、

CERTIFICATE と書かれている場合には内容は X.509 で、CERTIFICATE の部分に PKCS7 と書かれている場合には PKCS#7 です。
OpenSSL を使ってこの形式の証明書ファイルの情報を見るには以下のようにします。
X.509 の場合:
$ openssl x509 -in ファイル名 -text

PKCS#7 の場合:
$ openssl pkcs7 -in ファイル名 -text

に従って pkcs7 -text やってみればよかったんだよね。

$ openssl pkcs7 -in hoge.txt -text
-----BEGIN PKCS7-----
(省略)
-----END PKCS7-----
$ openssl pkcs7 -in hoge.txt -print_certs -text
Certificate:
    Data:
        Version: 3 (0x2)
(省略)

いやもう、証明書関係はややこしいよ!

あ、OpenSSLじゃなくて、Windowsでも p7b→PEM 変換ができる。

Vistaの例

  • 拡張子 p7b のファイルをダブルクリック。"Windows 管理コンソール"が起動
  • 左ペインでツリーを展開し、"証明書"をクリック
  • 右ペイン、"発行先"で対象の CN を右クリック→すべてのタスク→エクスポート
  • "証明書のエクスポートウィザード"が起動。[次へ]
  • "エクスポートファイルの形式" で "Base 64 encoded X.509 (CER)" を選択して[次へ]
  • ファイル名を入力/保存先を選択して保存(拡張子 cer → PEM形式)
  • [完了]