opensslコマンドでの証明書の整合性と検証結果の確認方法・オプション解説
目次
皆様こんにちは。
寝起きの朝がこの世の終わりのように辛い、システムソリューション部所属のなかです。
今回は下記の記事に続く、opensslコマンドでSSL証明書を確認する系の第2弾な記事です。
前回の記事では、証明書で一番意識するであろう「有効期限」の確認に絞った内容でした。
証明書を「新規」・「更新」にかかわらず発行した際は「整合性」の確認が重要です。
「整合性」についてopensslコマンドで確認する方法の説明が1点
証明書を適用後、証明書が認証局での「検証」が成功しているかも確認した方がよいため、
「検証」に問題がないかをopensslコマンドで確認する方法の説明で1点
今回の記事は、上記の2点をテーマに
「opensslコマンドでの証明書の整合性と検証結果の確認方法・オプションについて解説」
「確認方法についてなぜこれで確認できるのか?という理由についても合わせて解説」
というテイストでお送りいたします。
記事のスタンスとしては「細かい確認に関してはよくわかってない方を対象に簡単めに解説」という感じです。
実行環境
- ●Linux環境
OS:AlmaLinux release 8.5 (WSL2環境)
Shell:Bash
OpenSSL 1.1.1k FIPS 25 Mar 2021 - ●Windows環境
OS:Windows11 Pro (バージョン:22H2)
言語設定を日本語に変更
前置き:証明書設置の流れ
- 証明書を作成する際、まずはRSAの秘密鍵を作ります。
- 秘密鍵から対応する公開鍵が含まれた証明書署名要求(CSR)を作ります。
- CSRを認証局(中間証明書の所有者)に送付し、
認証局の秘密鍵でデジタル署名をしてもらった物が「証明書」となります。 - デジタル署名によって効力を持った「証明書」・「認証局の証明書(中間証明書)」・「秘密鍵」
の計3個を対象環境(LBやサーバ等)設置して完了。※1
※1. Apache2.4.8以降の環境では、中間CAを指定する SSLCertificateChainFile ディレクティブ が廃止されています。
そのため証明書申請時に「証明書」と「認証局の証明書(中間CA)」が1枚に一体化した形式を申請するのが基本です。
「期限」「整合性」「検証結果」の確認について
- 証明書の更新実務としては証明書等を設置して読み込ませる前に、
これらの「期限」(証明書)や「整合性」(3ファイル共通)を確認する必要があります。 - 更に、設置した後に証明書が検証されて正しく認証(いわゆる証明書チェーンが成立)されているかどうか
「検証結果」も確認する必要あり、「整合性」「検証結果」の確認方法を説明するのが本記事です。
確認する理由ですが、間違っている物を設置すれば当然証明書としては機能しません。
そうなった際、現代のブラウザだと警告が表示されてしまいユーザーが離脱しかねないサイトになります。
●拡張子に関して
◯本記事で使用する拡張子
・証明書(.crt)
・中間CA証明書(=中間証明書)(.ca)
・秘密鍵(.key)
opensslコマンドを使って「整合性」を確認する
お待たせしました、本題の確認方法についてです。
ご存知 openssl コマンドを使って整合性の確認を行います。
「証明書と中間証明書」と「証明書と秘密鍵」とでは確認方法が異なりますが、
どちらも設置の際に行うため本番環境で実行します。
証明書と中間証明書(=中間CA証明書)の「整合性」を確認する方法
issuer_hash オプションで証明書の「issuer」(=発行者)情報のハッシュを表示
openssl x509 -issuer_hash -noout -in example.com.crt
subject_hash オプションで中間証明書の「subject」(=主体者)情報のハッシュを表示
openssl x509 -subject_hash -noout -in example.com.ca
この時、2つの値がまったく同じであれば整合性が取れていることが確認できます。
x509
SSL証明書を扱う時は「openssl」コマンドに「x509」というサブコマンドを使用します。
※「X.509」とは公開鍵証明書の標準フォーマットの名前なので関連付けておくと覚えやすいです。
-in
読み込む証明書の名前を指定する必要があるので、このオプションを用います。
-issuer_hash
証明書に記載された発行者(issuer)情報のハッシュ化して表示します
-subject_hash
証明書に記載された主体者(subject)情報のハッシュ化して表示します
●「issuer_hash」と「subject_hash」の違う項目同士で、なぜ整合性が確認できるのか
項目名が違うだけで結果的に同じもの指す情報だからです。
証明書の「issuer」……発行者は、認証局のことです。
中間証明書の「subject」……主体者というのは、認証局のことです。
そうです。つまり、
「証明書の発行元の認証局」と「中間証明書の持ち主である認証局」 が同じかを確認していたわけです。
この2つのハッシュ値が一致すれば、問題なく「証明書と中間証明書の整合性」が確認できたと言えるのです。
●Apache2.4.8以降の場合
Apache2.4.8以降の環境では、 SSLCertificateChainFile ディレクティブが廃止されました。
よってApacheのconf上では
「証明書」と「認証局の証明書(中間CA)」が一体化した1枚の証明書を指定する形になっています。
証明書申請時に Apache2.4.8 以降用として、
1枚に結合された証明書を発行してもらえるので確認作業は基本的に不要です。
※例外:Apache2.4.8 以降の環境なのに、証明書が別々な従来形式で発行してしまった際は
手動で証明書を結合する事になるのですが、その前に念のための確認として実行します。
証明書と秘密鍵の「整合性」を確認する方法
証明書と秘密鍵の「整合性」は
両方が保有する情報である「modulus(モジュラス)」が同一かどうかを確認します。
openssl x509 コマンドを使用します。
modulus オプションで証明書の modulus を表示させます、
この際 md5sum で短文のハッシュ値に変換させると比較しやすくて楽です。
openssl x509 -noout -modulus -in example.com.crt | md5sum
openssl rsa コマンドのmodulus オプションで秘密鍵の modulus を表示させます、
同様に md5sum で短文のハッシュ値に変換します。
openssl rsa -noout -modulus -in example.com.key | md5sum
この時、2つの値がまったく同じであれば整合性が取れていることが確認できます。
x509 -modulus
サブコマンドである「x509」のオプションで、証明書に含まれるmodulus(モジュラス)の値出力します。
rsa
RSA鍵を扱う時は「openssl」コマンドに「rsa」というサブコマンドを使用します。
rsa -modulus
サブコマンドである「rsa」のオプションで、鍵に含まれるmodulus(モジュラス)の値出力します。
| md5sum
ハッシュ関数「MD5」を使用した計算をするコマンドで、今回はパイプで渡した modulusの情報をハッシュ化させています。
●「modulus(モジュラス)」が同じ値だと、なぜ整合性が確認できるのか
このmodulusオプション は、RSA暗号形式で利用される数値の1つである「RSA modules」を表示させています。
解説が膨大になるのでザックリな説明となりますがRSA暗号方式では、
- 秘密鍵側だけが持つ数値
- 公開鍵も持つ数値(RSA moduleがここに含まれる)
という2種類の数値があり、
これらの数値を使って計算(HTTPSだとデジタル署名と署名検証)を行っています。
ここで重要なのが、秘密鍵は公開鍵が持つ数値も保有していることです。
つまり、両方の鍵が保有する RSA module が同一であれば「公開鍵と秘密鍵はペアである」(=整合性がある)と確認できるわけです。
●証明書は公開鍵じゃないのになんでmodulusを出力できるの?
証明書は仕組みとして公開鍵を内蔵している物だからです。
この証明書に内蔵された公開鍵を使って、HTTPSにおける暗号化通信を行うための段取りを始めます。
秘密鍵からCSRをコマンド一発で作成するので操作上では意識しにくいですが、仕組みとしてCSR(&証明書)は公開鍵を含んだ物です。
※当記事はあくまで確認方法のため、原理的な解説は割愛します。
opensslコマンドを使って認証局との「検証結果」を確認する
ルート証明書・中間証明書・証明書が正しく機能(証明書チェーンが成立)しているかの確認です。
前回の記事では openssl s_client で接続し、その際に取得した証明書の内容(有効期限)を確認する使い方でした。
今回は、通常の利用方法である「接続を実施し、通信状況のログ出力」を行い状態を診断する使い方です。
$ openssl s_client -connect beyondjapan.com:443 -showcerts < /dev/null CONNECTED(00000003) depth=2 C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root verify return:1 depth=1 C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3 verify return:1 depth=0 C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = sni.cloudflaressl.com verify return:1 --- Certificate chain 0 s:C = US, ST = California, L = San Francisco, O = "Cloudflare, Inc.", CN = sni.cloudflaressl.com i:C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3 -----BEGIN CERTIFICATE----- 省略 -----END CERTIFICATE----- 1 s:C = US, O = "Cloudflare, Inc.", CN = Cloudflare Inc ECC CA-3 i:C = IE, O = Baltimore, OU = CyberTrust, CN = Baltimore CyberTrust Root -----BEGIN CERTIFICATE----- 省略 -----END CERTIFICATE----- 大幅省略 Verify return code: 0 (ok) --- DONE
-showcerts
opensslコマンドの、SSL/TLSで通信を行うためのサブコマンド「s_client」のオプションで、サーバーから送信された証明書のリストを表示します。
このオプションを使用しなくとも下記で確認する「verify return code」等は表示されるのですが、証明書に関する情報量が増えるの使っています。
確認すべき点
ここで確認すべきなのは最下部の「Verify return code」と「depth」です。
verify return code
検証状態を表すステータスコードです。
・「verify return」が「0 (ok)」であれば問題ありません。
ただし、それ以外の場合は問題でコードの番号に合わせて検証内容が表示されます。
例えば 「21 (unable to verify the first certificate) 」(翻訳:最初の証明書を検証できません)の場合、
サーバ証明書から辿った最初の証明書である中間証明書に恐らく問題がある事がわかります。
他にも「10 (Certificate has expired) 」(翻訳:証明書の有効期限が切れています)等があり、
コードに合わせて検証内容を表示してくれるので、問題を探す際に大変便利です。
depth
証明書の階層を表しており、
0がサーバーの証明書、1が中間証明書、2がルート証明書と辿っていく順番となります。
・「depth」が「2」「1」「0」と正しく連番になっている場合は証明書の流れ的に問題ありません。
ただし、全てが「0」となっている場合は問題です。
階層構造が作られていない(=証明書チェーンが成立していない)事となり、
恐らく高い確率で中間証明書に問題があることが推測できます。
この場合、verify return code は 21 となっている事が多いはずです。
注意すべき「中間証明書の適用漏れ」
適用前に証明書と中間証明書の「整合性」を確認していれば概ね問題ないと思いますが、
Apache2.4.8 以降 だと1本化したことで「中間証明書が抜けた状態」で適用してしまう可能性が高まっています。
●すぐには気が付けない厄介な状態になる
この「中間証明書が抜けた」状態は非常に厄介です。
PCのブラウザだと「中間証明書を補完する機能」か「キャッシュにある中間証明書」が機能して「サイトが見れてしまう」場合が多い事です。
逆に、スマートフォンのブラウザだと「中間証明書の補完機能がないためにエラーが出てしまう」事が多いという、原因の切り分けに困惑する状況に陥ります。
証明書で主に確認する「有効期限」や「ドメイン名」を見ても何ら問題なく、
PCではサイトが見れてしまう事から「すぐに問題に気が付けない」非常に厄介なケースです。
実はこのケースの存在を知った事が本記事を書こうと思った最大の理由です。
「証明書は問題ないのにスマホだけおかしい」、「証明書そのものには問題ないのにエラーがでる」な場合には
上記のコマンドで、ルート証明書や中間証明書が問題なく機能しているかをまずは調べてみると良いでしょう。
最後に
証明書の確認方法は業務で非常によく利用する内容なので、覚えておくとかなり便利です。
ただ、証明書やSSL/TLSの仕組みを知らないとわかりにくい部分はあるかと思いますので
別途仕組みについても学ぶと理解が深まるかと思います。
この記事を読んだ方々に多少でも役に立つ知識となれれば幸いです。
参考資料
OpenSSL公式 のopenssl-x509に関するマニュアルページ
https://www.openssl.org/docs/manmaster/man1/openssl-x509.html
OpenSSL (ArchWiki)
https://wiki.archlinux.jp/index.php/OpenSSL