CSRデコードツール

ブラウザ内でデコードされ、送信されることはありません。CSRは秘密鍵と隣り合わせのものなので、アップロードを伴うページに貼り付けるべきではありません。このツールは送信せず、秘密鍵を求めることもありません。

入力した内容が保存・記録・共有されることはありません。

CSR(証明書署名要求)またはX.509証明書を貼り付けると、サブジェクト、代替名、鍵のアルゴリズムとサイズ、有効期間、拡張、フィンガープリントを読み取れます。処理はすべてブラウザ内で行われ、内容が送信されることはありません。

使い方

  1. BEGIN行とEND行を含め、PEMブロック全体を貼り付けます。
  2. サブジェクト、SAN、鍵、有効期間、拡張などのデコード結果を確認します。
  3. フィンガープリントをコピーし、サーバーやコンソールの表示と照合します。

CSRに含まれるもの、含まれないもの

証明書署名要求(CSR)に含まれるのは3つです。証明書に記載してほしいサブジェクト、鍵ペアの公開鍵、そして要求する拡張、中でも最も重要なサブジェクト代替名(SAN)です。CSRは自分の秘密鍵で署名されており、認証局(CA)に対して、証明を求めている鍵を実際に持っていることを証明します。

秘密鍵は含まれず、CSRのどこからも秘密鍵を導き出すことはできません。だからこそCSRは鍵のような秘密情報ではなく、ツールに貼り付けても差し支えないのです。とはいえ無害とも言い切れません。ホスト名や組織名、ときには社内の命名規則まで記載されているため、使っているデコーダーがそれをどこかへ送信していないかは知っておくべきです。デコーダーの多くは証明書を販売する企業が運営しており、実際に送信しているものも少なくありません。

CSRの内容がどれほど少ししか残らないかも知っておく価値があります。CAは名前を検証したうえで、自らのシリアル番号、有効期間、発行者、そしてどの拡張を含めるべきかという自らの判断に基づいて証明書を発行します。組織や所在地のフィールドは、入力した内容ではなくCAが検証した記録から取られます。実際に引き継がれるのは、公開鍵と名前の部分です。

コモンネームは時代遅れ、重要なのはSAN

歴史的な経緯から、サブジェクトのコモンネーム(CN)はサイト名を示すフィールドのように見えますが、何年も前からその役割を果たしていません。Chromeは2017年にCNの参照をやめ、他のブラウザも追随しました。CA/Browser Forumは、証明書が対象とするすべての名前をSAN拡張に記載するよう義務づけています。CNがあってもSANのない証明書は、CNに何が書かれていても現在のすべてのクライアントで拒否されます。

したがって最初に読むべきフィールドはSANの一覧で、証明書が対応すべきホスト名をすべて含んでいる必要があります。www付きとあわせてwwwなしのドメインでも配信するなら、その名前も必要です。ワイルドカードがカバーするのはちょうど1ラベル分なので、*.example.comはwww.example.comに一致しますが、example.comやa.b.example.comには一致しません。

CSRではSANを見落としやすく、実際に見落とすデコーダーも多数あります。発行済みの証明書ではSANは最上位の拡張ですが、要求ではextensionRequest属性の中、2階層深い場所に入れ子になっています。このツールは正しい場所を見るので、ここで一覧が空なら、そのCSRには本当にSANが含まれていません。提出する前に直しておく価値があります。

証明書の読み方

サブジェクトと有効期間以外にも、証明書に何が許されているかを決めるいくつかの拡張があり、知りたい答えはたいていそこにあります。

Basic Constraintsは、それがCA証明書かどうかを示します。末端(リーフ)証明書にCA:TRUEがあるのは深刻な誤発行で、サーバー証明書ならCA:FALSEであるべきです。Key UsageとExtended Key Usageは鍵の用途を絞り込みます。TLSサーバーならserverAuth、相互TLSならclientAuthです。クライアントが期待する用途が欠けている証明書は、ほかがすべて正しくても拒否されます。

Authority Information Accessには、発行元証明書のURL(一部のクライアントは不完全なチェーンをこれで補います)とOCSPレスポンダーのURLが含まれます。Certificate Transparencyのタイムスタンプは、証明書が公開ログに登録されたことを示し、現在のブラウザはこれを必須としています。Authority Key IdentifierとSubject Key Identifierは、チェーン構築で実際に照合される値であり、発行者名とサブジェクト名を目で比べるより確実です。

フィンガープリントはSHA-256を使いましょう。SHA-1は、多くの管理画面やピン留め設定が今も表示しているために併記しているだけです。どちらもDERエンコーディングに対して計算しており、opensslの出力と一致します。

チェーンの問題

証明書に関する失敗で最も多いのは、証明書そのものではなくチェーンの問題です。デスクトップのブラウザでは動くのに、curlやモバイルアプリ、JVMのクライアントでは失敗するサーバーがその典型です。

サーバーは自身の証明書に加え、ルートの手前までのすべての中間証明書を提示しなければなりません。ブラウザは中間証明書が欠けていても、Authority Information AccessのURLから取得したり、別のサイトで取得したものをキャッシュから使ったりしてごまかすことが多いため、Chromeでテストしている人には問題が見えず、それ以外のすべてのクライアントでは即座に失敗します。ルート証明書まで送っても害はありませんが意味もありません。クライアントはすでに持っているか、信頼していないかのどちらかだからです。

従来のTLSチェーンでは順序が重要で、まずリーフ、次に各発行者を順に並べます。ここにチェーン全体を貼り付けると、各ブロックを指定した順に個別にデコードするので、中間証明書の欠落や順序の誤りがひと目でわかります。各証明書の発行者と次の証明書のサブジェクトを照らし合わせ、中間証明書の有効期限も確認してください。中間証明書にも期限があり、期限切れの中間証明書は完全に有効なリーフ証明書を使えなくしてしまいます。

リクエストの生成と、その裏にある鍵

CSR は必ず鍵ペアと一緒に作られ、本当に重要なのは鍵のほうです。定番のコマンドは両方を一度に生成します。openssl req -new -newkey rsa:2048 -nodes -keyout example.key -out example.csr です。-nodes フラグは鍵を暗号化せずに残します。これは Web サーバーがパスフレーズを聞かれずに起動するために必要なものであり、同時に、そのファイルをサービスアカウントだけが読めるようにしなければならない理由でもあります。

互換性の観点では、2048 ビットの RSA が今も安全な既定値です。P-256 曲線の ECDSA は、同等の安全性をはるかに小さな鍵と高速なハンドシェイクで実現し、openssl ecparam -genkey -name prime256v1 で生成できます。現行のブラウザはすべて受け入れます。ただし一部の古いミドルボックスやレガシーな Java クライアントは対応しておらず、それが RSA を選ぶ唯一の実質的な理由として残っています。

subject alternative name は、対話的なプロンプトが尋ねてこないために忘れられがちなフィールドです。設定ファイル経由か -addext フラグで与える必要があり、たとえば -addext "subjectAltName=DNS:example.com,DNS:www.example.com" のように書きます。これがないリクエストは却下されるか、さらに悪い場合、どのブラウザも受け付けない証明書が発行されてしまいます。

自動発行がワークフローを変えた

CSR を作り、ベンダーのポータルに貼り付け、待って、証明書をダウンロードし、インストールし、翌年また同じことをする。この手作業のサイクルは、いまや例外的なやり方です。Let's Encrypt が 2016 年に導入した ACME プロトコルは、このやり取り全体を自動化します。クライアントがドメインの管理権を証明し、CSR を送り、証明書を受け取る。通常は数秒で終わり、人の手は介在しません。

ドメインの管理権の証明方法は3つあります。HTTP-01 は well-known パスでトークンを配信する方式で、ポート 80 に到達できる必要があります。DNS-01 は TXT レコードを公開する方式で、ワイルドカードを発行できる唯一の方法であり、公開 Web サーバーを持たないホストで使える唯一の方法でもあります。TLS-ALPN-01 はポート 443 上で専用のハンドシェイクに応答する方式で、そのポートしか開いていない環境で役立ちます。

この方式で発行される証明書の有効期間は、設計上 90 日です。短い有効期間は鍵が漏れたときの被害を限定し、更新の手順を「覚えておく」ものではなく自動化されたものにする、という考え方に基づいています。クライアントは有効期間の3分の2あたりで更新するため、失敗しても何かが期限切れになる前に気づく時間が確保されます。

検証レベル、ワイルドカード、そして証明書が証明するもの

ドメイン検証が示すのは、証明書を要求した者がその時点でドメインを管理下に置いていたという事実だけです。組織検証と拡張検証は、その背後にある法人に対する確認を追加し、それが発行された証明書の subject フィールドに現れます。ブラウザは何年も前に EV に対する特別な UI 表示をやめているので、今日の実務上の違いは、訪問者が見て分かるものというより、契約上・手続上のものが中心です。

ワイルドカードがカバーするのはちょうど1ラベルです。*.example.com は www や api には一致しますが、example.com 自体にも a.b.example.com にも一致しません。ほとんどのワイルドカード証明書が、裸のドメインを追加の SAN として列挙しているのはこのためです。またワイルドカードはリスクを集中させます。鍵が1つ漏れればその名前の下にあるすべてのホストが影響を受けますし、DNS の管理権なしには発行できません。

以上のどれも、そのサイトが信頼できるかどうかについては何も語りません。証明書が意味するのは、通信が暗号化されていることと名前が一致することだけであり、運営者が誠実であることを意味したことは一度もありません。フィッシングサイトが有効な証明書を持っているのは当たり前のことで、だからこそブラウザの UI はそれ以上のことをほのめかすのをやめたのです。

有効期限は証明書の問題ではなく運用の問題

証明書の期限切れが引き起こした障害は、ひとつのジャンルと言えるほどよくある話です。決済ネットワーク、携帯電話事業者、クラウドの管理コンソールまでもが止まってきました。証明書は設計どおりに振る舞っただけで、壊れていたのはその周りの運用プロセスです。

監視は、失敗を検知するのではなく残り日数に対してアラートを出すべきで、しきい値は対処できるだけの余裕を持たせます。90 日の証明書なら2週間、1年の証明書なら1か月です。ファイルではなくエンドポイントを監視してください。重要なのはサーバーが実際に提示している証明書だからです。そして中間証明書も確認してください。中間証明書も期限切れになり、期限の切れた中間証明書は、何の問題もないリーフ証明書を台無しにします。

証明書透明性ログは、無料のインベントリを提供してくれます。公的に信頼されるすべての証明書はログに記録されるので、自分のドメインを検索すれば、何が存在するかが分かります。組織内の別の誰かが発行して、あなたに伝え忘れた証明書まで含めてです。

うまく動かないときにチェーンを読む

単独で最も役に立つコマンドは openssl s_client -connect host:443 -servername host です。これは設定ファイルに書かれている内容ではなく、サーバーが実際に提示しているものを見せてくれます。表示されるチェーンはリーフ証明書から始まり、その発行者が順に続くはずで、各証明書の issuer 行は次の証明書の subject 行と一致していなければなりません。

中間証明書の欠落は典型的な失敗で、デスクトップのブラウザでは見えません。ブラウザは足りない証明書を取りに行くか、他のサイトでキャッシュしているからです。curl、モバイルアプリ、JVM のクライアントはそうしません。その結果、動作確認をした本人のところでは動くのに、実トラフィックのかなりの割合で失敗する、という症状になります。

チェーンが正しく見えるのに接続が失敗する場合、次に確認すべきは鍵用途(key usage)の拡張、クライアントがそもそもそのルートを信頼しているか、そしてクライアント側の時計です。日付がずれた端末は、何の問題もない証明書を「まだ有効になっていない」として拒否します。

よくある質問

CSRをWebページに貼り付けても安全ですか?
このページなら安全です。デコードはブラウザ内で完結し、テキストが端末を離れることはありません。ただし一般論としては注意が必要です。証明書デコーダーの多くは証明書を販売する企業が運営しており、CSRを自社サーバーへ送信するものも少なくありません。CSRは秘密鍵ほど秘匿性が高いわけではありませんが、インフラの構成を記述したものではあります。自分がどちらの種類のツールを使っているかは把握しておくべきです。
証明書が有効か、信頼できるかを確認できますか?
できませんし、できるふりもしません。このツールが読み取るのは証明書が「主張している」内容だけです。署名の検証も、ルートまでのチェーン構築も、CAやOCSPへの問い合わせも行いません。この目的でブラウザが正当に参照できるトラストストアは存在しないため、「信頼済み」という緑のバッジを表示するツールは誤解を招きます。表示される有効期間は証明書に書かれた値を、お使いの端末の時計と比較したものです。
何を貼り付けられますか?
CSR、証明書、チェーン全体のいずれでも構いません。PEMブロックごとに個別にデコードして順番に表示するため、中間証明書の欠落や順序の誤りをすぐに確認できます。BEGIN行とEND行のない生のbase64も扱えます。JSONのフィールドやKubernetesのSecretからコピーした証明書はその形になるためです。秘密鍵はデコードせず拒否します。
CSRに代替名が表示されないのはなぜですか?
本当に含まれていないか、あるいは以前使ったデコーダーが見つけられなかったかのどちらかです。CSRではSANはトップレベルにはなく、extensionRequest属性の内部、完成した証明書より2階層深いところに格納されています。このツールはそこを見に行きます。ここでも表示されないのであれば、そのCSRは実際にSANなしで生成されています。最近のブラウザはコモンネームを完全に無視するため、提出前に修正する価値があります。
どのフィンガープリントを照合すべきですか?
特にSHA-1を求められていない限りSHA-256です。両方を表示しているのは、コンソールやピン留め設定、ベンダーの管理画面には今もSHA-1を表示するものが多く、目の前にある値と突き合わせられる必要があるためです。どちらもDERエンコーディングに対して計算しているため、openssl x509 -fingerprintの出力と完全に一致します。
日付が見た目以上に重要なのはなぜですか?
証明書には2種類の時刻表現があり、2050年より前の日付は2桁の年で格納されます。RFC 5280では50〜99が19xx、00〜49が20xxと定められているため、この境界を誤って実装したデコーダーは、2049年まで有効な証明書を1949年に失効したものとして表示します。このツールはRFCに従っており、それを固定するテストもあります。

最終更新:

問題を報告

操作手順、期待した結果、実際の結果を記載してください。秘密情報や個人情報は削除してください。

関連ツール