hayashier Tech Blogs
  • hayashier Tech Blogs
  • Author's Books
    • 実践Redis入門 (日本語版)
    • 実践Redis入門 (한국어판)
  • Top Contents
    • Dive Deep Redis
    • Dive Deep Memcached
    • Kubernetes 入門
    • TCP 入門
    • TLS 入門
    • GPG 入門
    • サービス障害が発生した場合の対応方法
    • よく使うトラブルシューティング コマンド実行例 まとめ
    • コピペで使えるELBのアクセスログ解析による事象分析 (ShellScript, Athena)
  • Containers
    • Docker 入門
    • Nomad 導入
    • Dockerを利用してさっと検証環境構築
  • Kubernetes
    • Kubernetes 入門
    • Kubernetes 導入 with Amazon Linux 2
    • EKSを利用してKubernetesでSpring MVCをデプロイ (NLB + Auto Scaling)
  • Load Balancer
    • ALB 認証 導入
    • TLS extensions support with ALB
    • ELB(CLB,ALB,NLB)の種類ごとのHTTPレスポンスの違い
    • ELB(CLB) で WebSocket 通信
  • RDBMS
    • PostgreSQL DBA 入門
    • RDBMS Benchmark Get Started
    • RDBMS サンプルデータ生成 Get Started
    • RDS PostgreSQL Extensions Get Started
    • RDBMS Engine Inspection for Troubleshooting
  • Redis
    • Dive Deep Redis ~ 入門から実装の確認まで
    • Dive Deep Redis Internals ~ GETコマンド実行時の動作 ~
    • RedisのString型は今でも本当に512MBが上限か?
    • Redis 公式ドキュメント まとめ
    • Redis / Memcached Source Code Reading - Overview -
  • Memcached
    • Dive Deep Memcached ~ 入門から実装の確認まで ~
    • Dive Deep Memcached ~ SETコマンド実行時の動作 ~
    • Memcached 公式ドキュメント まとめ
    • memtier_benchmark + memcached-tool の導入
    • Redis / Memcached Source Code Reading - Overview -
  • Hadoop
    • Hadoop Get Started
  • Networking
    • TCP 入門
    • TLS 入門
    • ksnctf: HTTPS is secure, Writeup (TLS 通信解読)
    • オンプレ側ルーター(Cisco 1812J, Juniper SRX210, YAMAHA RTX 1210)から Direct Connect へ BGP 設定
  • Software
    • アルゴリズムとデータ構造 入門
    • デザインパターン 入門
    • ソフトウェアテスト 入門
  • System Admin
    • Shell Script 入門
    • サービス障害が発生した場合の対応方法
    • よく使うトラブルシューティング コマンド実行例 まとめ
    • コピペで使えるELBのアクセスログ解析による事象分析 (ShellScript, Athena)
    • GPG 入門
    • Operation Misc
  • Development
    • ローカル環境のプログラミング言語のバージョンを切り替え macOS
    • /usr/local/Cellar/pyenv/1.2.21/libexec/pyenv: No such file or directoryのエラーの対処方法
  • AWS
    • AWS Misc
    • AWS CLI, AWS SDKのリトライ処理の実装について
    • AWS CLI バージョンアップでエラー発生を解消
    • Elastic Beanstalkで稼働しているアプリケーション(Ruby, Sinatra)をAmazon Linux AMIからAmazon Linux2へ移行
    • Elastic Beanstalkでインスタンス入れ替え後にnginxのデフォルトの画面が表示されてしまう問題の対応
    • Amazon Lightsail に SSL 証明書設置 with Let's Encrypt (自動更新)
    • Amazon Lightsailで10分で作るお手軽Markdownで書く独自ドメインのブログサイト構築
    • Lambdaをローカルでテスト(with Docker)
    • ECS + ALB でダウンタイムなしでデプロイ
    • `Repository packages-microsoft-com-prod is listed more than once in the configuration`のメッセージの解消方法
  • Others
    • Pandoc 導入
    • textlint + prh による文章校正
    • 紙書籍をPDFに変換
    • Sphinx 導入
    • さくっとPocketのブックマークをはてなブックマークに移行
    • Macが突然起動しなくなった話
    • Macでターミナルが開かない (zsh編)
    • ホスト型 IDS Tripwire とネットワーク型 IDS Snort の導入 with CentOS 6
    • JMeter 導入
    • Squid 導入 with Amazon Linux AMI
    • Spring MVCを導入 (+ MySQL, Redis)
    • 外資系企業で働いている場合の確定申告方法 (RSU考慮)
Powered by GitBook
On this page
  • TLS 入門
  • SSL/TLS
  • TLSハンドシェイク
  • SSL証明書
  • 自己証明書
  • クロス証明書
  • Topics
  • Topics
  • Slide 22
  • Slide 29 TLS 1.3 – Hello Retry Request
  • Slide 30 TLS 1.3 – Adapt new way about Session Resumption
  • Links
  • Javaにおけるルート証明書
  1. Networking

TLS 入門

TLS 入門

TLSは安全に通信するためのプロトコルです。OSI参照モデルのトランスポート層での通信のために使用されます。すなわち、アプリケーションレイヤーを含む、トランスポート層よりも上のレイヤーを暗号化対象とします。

TLSで実現するものとしては、大きく以下の2点が挙げられます。

  • 通信相手の認証

  • 通信の暗号化

少し別の観点で見ると、TLSでは以下の内容を実現します。

  • 機密性(Confidentiality)

  • 完全性(integrity)

  • 真正性(authenticity)

機密性については、暗号化に対応します。データが知らないうちに変わると困ります。完全性については、このようなことがないことを保証します。真正性について、これは認証に対応します。 すなわち、それぞれのリスク対策として、機密性は通信内容が他社に漏れないこと、完全性は通信内容に改ざんがあればそれに気付けること、真正性としては、通信相手、すなわち、Webサイトの運用者になりすましがあれば、すぐに気付けることが挙げられます。

SSL/TLS

そもそも、TLSはSSLとセットで語られることも多く、SSL/TLSなどと表記されることがあります。

SSLとTLSの端的な違いは、例えば、以下のことが挙げられます。

  • SSL

    • Netscape社が開発

    • POODLE攻撃の脆弱性を受ける

  • TLS

    • IETFが策定

    • よりセキュア

    • TLS拡張

      • SNI

      • NPN

      • ALPN

      • セッションチケット

      • OCSPステープリング

      • TLS False Start

SSLとTLSをそれぞれバージョンごとに特徴を挙げると以下のようになります。

  • SSL

    • SSL 1.0

      • Netscape社が商用トランザクションのセキュリティのためにの開発を始めたが、リリースされなかった

    • SSL 2.0

      • Netscape Navigator 1.1という当時支配的だったブラウザに実装

      • ただし、重大な脆弱性があり、SSL 3.0の開発を始める

    • SSL 3.0

      • スクラッチで開発。TLSの各バージョンにも受け継がれる設計を確立

      • POODLE攻撃の脆弱性を受け、TLSの利用が推進され始める

  • TLS

    • TLS 1.0

      • 標準化されたHMACによってPRFが規定

      • マスターシークレットが独自構成ではなく、PRFで生成

      • verifay_dataの値が独自構成ではなく、PRFで生成

      • 完全性の検証(MAC)で標準化されたHMACを利用

      • パディングのフォーマット変更

      • 暗号スイートからFORTEZZAを除外

    • TLS 1.1

      • CBC暗号化利用モードで、各TLSレコードに明示的なIVを利用

      • パディング攻撃対策として、bad_record_macアラートを返すことを要求。decryption_failedアラートを廃止

      • TLS拡張

    • TLS 1.2

      • AEADのサポート

      • HMAC-SHA256暗号スイートのサポート

      • IDEAおよびDES暗号スイートを除外

      • TLS拡張が主要なプロトコルの使用に組み込み

      • クライアントが新しい拡張signature_algorithmを使って受け入れを希望するハッシュと署名のアルゴリズムを通知可能

      • PRFでMD5とSHA1を組み合わせていた部分をSHA256に置き換え

      • 暗号スイートで独自のPRFを指定可能

      • デジタル署名でMD5とSHA1を組み合わせていた部分をデフォルトでSHA256に置き換え。ただし、暗号スイートでハッシュ関数を指定可能

      • Finishedメッセージのverify_data要素の長さを暗号スイートで明示的に指定可能

    • TLS 1.3

      • セキュリティ強度の高い暗号アルゴリズムを要求

      • セッションのリネゴシエーションや再開に関する脆弱性のある方式を廃止し、セッション再開については新たな方式を採用

      • ネゴシエーション (handshake) シーケンスの大幅な変更

以降は、基本的にTLS 1.2をベースとした内容で説明します。

  • References

TLSハンドシェイク

TCPの3ウェイハンドシェイクによりTCPコネクションを確立後に、TLSハンドシェイクが行われます。

接続方法のネゴシエーションが行われることについて言及しましたが、これはクライアントとサーバーがそれぞれ可能な処理内容を暗号スイートを通してやりとりします。

暗号スイートにはTLSの目的を実現する手段と、その手段を実現するにあたっての情報の交換方法が書かれています。 クライアント側は自身が対応している暗号スイートを優先度順にしてリストを送ります。通常は、サーバー側は自身で対応している暗号スイートの中で、クライアントから提示されたリストの上から選択します。Server Order Preference等の設定が行われている場合は、サーバー側のリストの上から選択します。 このようにネゴシエーションが行われて、どのようにTLS通信が行われるかが決まります。

すなわち、TLSハンドシェイクは様々な方法でも実現可能な仕組みのフレームワークのようなものです。

  • References

暗号スイート

暗号スイートは例えば、以下のような文字列で表します。

ECDHE-ECDSA-AES128-SHA256

上記は大きく4つの要素からなり、それぞれ以下の内容を実現する方法を表しています。

  • ECDHE : 鍵交換

  • ECDSA : 認証

  • AES128 : 暗号

  • SHA256 : データ完全性

もう少し掘り下げると、それぞれ以下のとおりです。

  • 鍵交換(Key Exchange)

    • TLSハンドシェイク内で具体的にどういった方法で鍵交換を行うかの取り決め

    • TLSハンドシェイクの説明を聞くと、このRSAの説明のみをイメージしてしまっている人も多いという印象

  • 認証(Authentication)

    • 認証はTLSの目的の一つ。大事な機能で忘れちゃだめ。

  • 暗号(Cipher)

    • 機密性はTLSの目的の一つ。これが一番みんながイメージが湧きやすいところか。

  • データ完全性(Data Integrity)

    • 完全性はTLSの目的の一つ。データが改ざんされていれば気付けるようにしておくために、ハッシュ関数を使用する

    • message authentication algorithm のことを指していて、メッセージの認証に使用。OpenSSLだとMacという記載からも分かる

一般的な名称とOpenSSLでの名称

例えば、以下のようなフォーマットで先程説明したものとは異なる表記のものを見かけることもあるでしょう。

AES128-SHA256

OpenSSLで以下のようなコマンドを実行すると、利用可能な暗号スイートのリストが見られます。ここに含まれていることが確認できます。その横に詳細が書かれていますが、上記暗号スイートは、TLS 1.2で、鍵交換はRSA、認証はRSA、暗号化はAES 128bit、MACはSHA256で実行することを記載したものであることがわかります。

$ openssl ciphers -v
TLS_AES_256_GCM_SHA384  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any      Au=any  Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(128) Mac=AEAD
:
AES128-SHA256           TLSv1.2 Kx=RSA      Au=RSA  Enc=AES(128)  Mac=SHA256
:
PSK-AES128-CBC-SHA256   TLSv1 Kx=PSK      Au=PSK  Enc=AES(128)  Mac=SHA256
PSK-AES128-CBC-SHA      SSLv3 Kx=PSK      Au=PSK  Enc=AES(128)  Mac=SHA1

鍵交換

RSA鍵交換

クライアントが、プリマスターシークレットの値として48バイトの乱数を生成して、サーバーの公開鍵で暗号化してClientKeyExchangeメッセージに入れて送信します。サーバー側は自身の秘密鍵で復号することで、プリマスターシークレットの値を入手できます。

この方法の欠点としては、サーバー側の秘密鍵が流出すると、プリマスターシークレットを生成し、セッションを乗っ取ることができます。リアルタイムではなく、過去のデータも遡って見ることができてしまいます。そのたえめ、PFSの性質がありません。

なお、プリマスターシークレットからマスターシークレット生成理由としては、鍵交換方法によってプリマスターシークレットの長さが異なることが理由として挙げられます。

Diffie-Hellman鍵交換 / 楕円曲線Diffie-Hellman鍵交換

Diffie-Hellman鍵交換は、安全ではない通信路で共有鍵を生成するためのアルゴリズムです。この方法では、一方向の計算は簡単で逆方向の計算が困難である数学の性質を利用します。

まず、事前準備として、公開パラメータg,pを事前に共有しておきます。また、サーバー、クライアントはそれぞれ、事前に秘密鍵に相当するx,yという値を用意しておきます。

それぞれ、公開パラメーターから自身のDH公開鍵を以下の計算式で計算します。

サーバーがDH公開鍵を以下のように計算し、クライアントに送ります。

A = g^x mod p 

クライアントも同様にDH公開鍵を以下のように計算し、サーバーに送ります。

B = g^y mod p 

クライアントはサーバーから送られてきた公開鍵を最初にgの値に対して計算した方法と同様に、サーバーはクライアントから送られてきたDH公開鍵を最初にgの値に対して計算した方法と同様に計算します。すると、以下のように共通の値を取得することができ、このように共有鍵を生成します。

K = A^y mod p = B^x mod p (= (g^x)^y mod p = (g^y)^x mod p )

Diffie-Hellman鍵交換にはEphemeral、Static、Anonymousの種類があります。Staticな方法は、サーバーおよりクライアントの証明書に静的にパラメータを埋め込んで利用する方法です。その結果、鍵交換の結果が常に同じ共有鍵になります。一方で、前回の鍵交換で使ったパラメータを利用しない方法はEphemeralな方法で、PFSがある状態になります。DHE(一時的Diffie-Hellman)と呼びます。 TLSでは基本的にStaticな方法もサポートされているが、使われることはなく、TLS 1.3では廃止されています。

DH鍵交換は受動的な攻撃には強いですが、攻撃者が相手のフリをして間に入り込む、いわゆるMan-In-The-Middle(MITM)攻撃には弱いです。そのため、認証と組み合わせて使用します。 TLSではDHの公開鍵に対してデジタル署名を付加することで、署名は相手が公開している公開鍵で検証し、その公開鍵の検証はデジタル証明書のルート証明書が信頼されていることを確認することで行います。

DHとは異なり、楕円曲線暗号を用いたものがECDHE(一時的楕円曲線Diffie-Hellman)です。DHパラメータとしてサーバー側で定義されたある楕円曲線を使用します。

  • References

非対称暗号化と対象暗号化

TLSでは非対称暗号化と対称暗号化を使い分けます。端的にそれぞれをまとめると以下のような内容になります。

  • 非対称暗号化

    • 名前からも分かる通り、暗号化側と復号側が異なるもので実現する内容です。

    • 処理のCPUコストが大きい

  • 対称暗号化

    • 事前に同意しておいた秘密鍵を、暗号化側と共通側で共通のものを使用

    • 複数のユーザーがいると、その組み合わせだけ共通鍵が必要になる。

    • キー配布を事前にどのように行うかの問題

鍵交換には暗号スイートのKey Exchangeで指定した対象暗号化の方法が使用されます。その後のデータのやり取りには対称暗号化が利用されます。

ではなぜ、非対称暗号化から対称暗号化に切り替えるか。それは、対称暗号化の処理に対するCPUコストが大きいため、計算に時間がかかり、サイズの大きい計算には不向きだからです。 そのため、最初の認証や共有鍵を相手とやりとりするときに対称暗号化の方法を利用し、その後のデータのやりとりには非対称暗号化が利用されます。

なお、TLSでは共通鍵として、新規コネクションごとにランダムなセッション鍵を使用します。これは侵入者が得ることができる暗号部分の量を減らすためです。仮にバレてもその部分のみしか盗み見られず、影響範囲を抑えることができます。

メッセージ詳細

フォーマット

TLSは、Recordプロトコルがコネkす本庄でやり取りされる低レベルのメッセージ転送をを行います。以下のような構成になっています。

------------------------------------------------------------------------------
| ヘッダー(コンテントタイプ(サブプロトコル) + バージョン + レコード長) | メッセージデータ |
------------------------------------------------------------------------------
  • メッセージ転送

    • サイズが大きい場合にはチャンクへと分割して転送

  • 暗号化および完全性の検証

    • 最初のネゴシエーションが完了後、ネゴシエーションした結果に基づいて暗号化および完全性の検証

  • 拡張性

    • データの転送や暗号化処理以外はサブプロトコルで行う。

圧縮機能はCRIME攻撃に利用されたことで、現在は利用されていません。

サブプロトコル

TLSのコアとしては以下4つのサブプロトコルが定義されています。

  • Handshakeプロトコル

  • Change Cipher Specプロトコル

  • Application Dataプロトコル

  • Alertプロトコル

Handshakeプロトコルは、実際にTLSハンドシェイクの際に、パラメーターのネゴシエーションや認証を行う際に使用されます。Handshakeプロトコルとしては以下のメッセージが定義されています。ClientKeyExchangeは実際には異なるため、カッコ書きで記載しています。

  • フルハンドシェイク

    • ClientHello

    • ServerHello

    • Certificate

    • ServerKeyExchange

    • ServerHelloDone

    • (ClientKeyExchange)

    • ChangeCipherSpec

    • Finished

  • クライアント認証

    • CertificateRequest

    • CertificateVerify

TLSハンドシェイクの一連の流れで、ChangeCipherSpecのメッセージがお互いに交換されますが、これはハンドシェイクメッセージの一部ではなく、Change Cipher Specプロトコルとして、1つだけChangeCipherSpecのメッセージというメッセージが定義されており、こちらが利用されています。そのため、ハンドシェイクの完全性検証の対象外です。

Application Dataプロトコルは、アプリケーションデータを運ぶために使用されます。これらのデータは、セキュリティのパラメータに基づいて、Recordプロトコルのレイヤーでパッケージ化、細分化、および暗号化されます。

Alertプロトコルは、もう一方の相手に例外的な状況を伝えるために使用します。エラーメッセージやclose_notifyという接続のシャットダウンに使用します。close_notifyが送られる理由としては、強制切断攻撃で、攻撃者が能動的に通信を横取りして以降のメッセージをブロックするという攻撃にさらされているのか、正常に通信が終了しているのかを明示化するためです。

RSAやDiffie-Hellmanを利用したTLSハンドシェイク

TLSハンドシェイクの方法はあくまで目的を実現するためのフレームワークのようなもので、具体的な方法は暗号化スイートを始めとするセキュリティパラメーターで決まります。

セッション再開(Session Resumption)

TLSのハンドシェイクは負荷の大きい処理です。そのため、フルハンドシェイクを実行後は、マスターシークレットの値をキャッシュして再利用する方法があります。

  • セッションID

    • クライアントとサーバーの両方でセッションのセキュリティパラメータを保持しておきます。サーバーがセッションをキャッシュしておき、クライアントからClientHelloで対応するセッションIDが提示される場合、対応するセッション識別子を返します。

  • セッションチケット

    • サーバーは、すべてのセッションデータを収集し、暗号化してから、チケットの形式でクライアントに返します。それ以降の接続では、クライアントがサーバーにそのチケットを送信します。次に、サーバーがチケットの整合性をチェックして内容を復号化し、その情報を使用してセッションを再開します。

    • このように実現することで、サーバー側ではデータを保持しておく必要がありません。

    • TLS拡張機能の一つ

ただし、TLS 1.3では、ハンドシェイク完了後にサーバはクライアントに対して新しいセッションチケットを送るようにします。このクライアントに対するチケットは、以前のセッションIDのように鍵を探すデータベースとして利用することができます。このデータは、前の接続に対応し、自身で暗号化、認証された値とすることができます。つまり、サーバは状態を持つ必要がありません。

ELBについては、種類別に以下のものに対応しています。ALBとCLBは、複数のノードで構成されますが、ノードが変わる場合にはSession Resumptionの機能がりようできず、フルハンドシェイクが行われます。

  • NLB : セッションチケット (ロードバランサーレベル)

  • ALB : セッションチケット + セッションID (ノードレベル)

  • CLB : セッションID (ノードレベル)

ALBに対して、以下のように実行することで、セッションIDおよびセッションチケットに対応していることが分かります。

$ openssl s_client -connect alb.test.hayashier.com:443 -reconnect
:
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Session-ID-ctx: 
    Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    TLS session ticket lifetime hint: 43200 (seconds)
    TLS session ticket:
    0000 - xx xx xx xx xx xx xx xx-xx xx xx xx xx xx xx xx   ....x.x.x....,..
    0010 - xx xx xx xx xx xx xx xx-xx xx xx xx xx xx xx xx   ..y...y......,..
    :
    00a0 - xx xx xx xx xx xx xx xx-xx xx xx xx xx xx xx xx   ....z.z.z....,..

-no_ticketオプションを付与して、セッションチケットを利用しない場合、セッションチケットは利用していないことが確認できます。

SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-GCM-SHA256
    Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Session-ID-ctx: 
    Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Start Time: 1638592362
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
  • References

再ネゴシエーション

  • 再ネゴシエーションは、セッションを維持したまま暗号方式を変更するために利用します。

  • 再ネゴシエーションは、既に確立しているセッションを使って、サーバからクライアントへのHelloRequestと呼ばれる要請のメッセージか、クライアントからの初期ネゴシエーションと同様のClientHelloのメッセージが送られることによって開始する。

  • 今現在は一部の特殊なユースケース等を除き、多くのユースケースでは必要とすることはないでしょう。

  • Reference

再ネゴシエーションの挙動を確認するためには、以下のコマンドを実行後、Rを入力します。

$ openssl s_client -connect alb.test.hayashier.com:443

NLB/ALBでは再ネゴシエーションが無効化されていますが、CLBでは有効化されています。そのため、無効化状態である必要がある場合には、NLB/ALBを利用する必要があります。

NLBの場合は、以下のような結果が返ってきます。

RENEGOTIATING
write:errno=54

ALBの場合は、以下のとおりです。

RENEGOTIATING
4495674988:error:140040E5:SSL routines:CONNECT_CR_SRVR_HELLO:ssl handshake failure:/AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/libressl/libressl-47.140.1/libressl-2.8/ssl/ssl_pkt.c:585:

CLBの場合は、以下のとおりです。

RENEGOTIATING
depth=4 C = US, O = "Starfield Technologies, Inc.", OU = Starfield Class 2 Certification Authority
verify return:1
depth=3 C = US, ST = Arizona, L = Scottsdale, O = "Starfield Technologies, Inc.", CN = Starfield Services Root Certificate Authority - G2
verify return:1
depth=2 C = US, O = Amazon, CN = Amazon Root CA 1
verify return:1
depth=1 C = US, O = Amazon, OU = Server CA 1B, CN = Amazon
verify return:1
depth=0 CN = *.test.hayashier.com
verify return:1

SSL証明書

SSL証明書とは

そもそもSSL証明書とは、例えば、以下の特徴が挙げられます。

  • あるエンティティ(ここでは、サーバーの運営者)が特定の公開鍵に対応する秘密鍵を保有していることを保証するためのもの

  • X.509 v3 デジタル証明書が主流のフォーマット

  • PEM 形式で扱われることが多い : バイナリ形式(DER)の証明書を Base64 エンコード+αしたもの

一つ目の特徴を実現するにあたって、PKIの仕組みを利用します。PKI(Public Key Infrastructure)とは、信頼できる第三者機関(認証局、CA)を介することで、不特定多数の相手と事前に個別の手続きを行うことなく相手の識別と認証を実現させる仕組みです。 TLSの文脈では、ユーザーがドメイン名を利用してWebサーバーにアクセスしているとき、そのWebサーバーが当該ドメイン名を管理しているエンティティにより提供されていることを認証して確かめる仕組みとなります。

ASN.1というデータ構造やオブジェクトの定義等の方法を定めたものでデータを表現し、DERの方法でエンコーディングを行い、Base64エンコーディングでASCII形式で表現したものがPEMです。

パブリックな証明書はパブリックな認証局によって運用されています。一方でプライベート証明書はプライベート認証局で管理します。

パブリック証明書による認証は、以下の2つの段階で構成されます。

  1. PKIの仕組みにより、証明書が信頼されたCAから発行されているか検証

  2. 検証が成功した証明書を使って、TLS ハンドシェイク中に Web サーバーを認証

すなわち、2つめの段階で、Web サーバーが証明書の所有者であることを確かめます。

認証局が予めルート証明書をブラウザベンダーやOSプロバイダーに発行しておきます。 そして、CAのルート証明書はブラウザのアプリケーションやOSの一部として配布されます。

Webサーバーの運営者は、証明書署名リクエストを認証局に行います。すると、認証局はWebサーバーに対して署名付きの証明書を渡します。

ここまでユーザーがWebサーバーにリクエストを送るまでに整っている必要があります。その後、ユーザーがWebサーバーに対してリクエストを送ると、TLSハンドシェイクの過程でWebサーバーはSSL証明書を渡します。その際、Webサーバー側は証明書に対応する秘密鍵で署名したデータもユーザーに送ります。ユーザーはその後、PKIによる証明書の検証後に、証明書の公開鍵で署名されたデータを検証することで認証が完了します。その後、TLSのセッションが確立します。

一言でまとめると、TLS通信を行う際にサーバー証明書とルート証明書、中間証明書は以下の箇所に保存されます。

  • ルート証明書: ローカルの信頼ストア

  • 中間証明書: Webサーバー(ロードバランサー、CDN 等)

  • サーバー証明書: Webサーバー(ロードバランサー、CDN 等)

なお、TLSネゴシエーションの際に、サーバー証明書と合わせて複数の中間証明書(証明書チェーン)が送られることもあります。このとき、TLS通信を行うクライアントでは証明書の検証にあたって複数の信頼パスを利用することが可能な状態になります。 このとき、検証でどの信頼パス、すなわち、どのルート証明書を選択するかは、Webブラウザーなどのクライアント側の実装に依存する動作になります。適切な信頼パスが選ばれない場合は、ルート証明書がインストールされているか等確認する必要があります。

証明書ストアの場所

ユーザーがWebアプリケーションにアクセスする際に参照されるルート証明書がどこに保存されているものを参照するかはブラウザ等のアプリケーションによります。

Webブラウザ

  • Chrome

    • Settings > Private and security > Securityをクリックすると、Manage certificatesを選択すると、Keychain Accessのアプリケーションが開きます。System Rootsを選択すると、MacOSにインストールされているルート証明書を確認できます。

  • Firefox

    • Settings > Private & Securityをクリックすると、Certificatesの項目でView Certificates...が選択できます。その後、Authotiesタブを選択すると、Firefoxにインストールされているルート証明書を確認できます。

OpenSSL

macOSでは/private/etc/ssl/cert.pem、Amazon Linux2では/etc/pki/tls/cert.pemに格納されます。

以下のようにOPENSSLDIRの値を参考にできます。

$ openssl version -a
LibreSSL 2.8.3
built on: date not available
platform: information not available
options:  bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx) 
compiler: information not available
OPENSSLDIR: "/private/etc/ssl"

curl

内部的にはOpenSSLなどを利用しているので、それに応じて確認する必要があります。たとえば、以下のように確認できます。

$ curl --version
curl 7.79.1 (x86_64-koji-linux-gnu) libcurl/7.79.1 OpenSSL/1.0.2k-fips zlib/1.2.7 libidn2/2.3.0 libssh2/1.4.3 nghttp2/1.41.0 OpenLDAP/2.4.44
Release-Date: 2021-09-22
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB SPNEGO SSL UnixSockets

プログラミング言語

Javaの場合は、/etc/pki/ca-trust/extracted/java/cacertsや/etc/ssl/certs/java/cacertsなどが利用されます。例えば、ルート証明書の一覧は以下のように確認します。

# keytool -v -list -keystore /etc/pki/ca-trust/extracted/java/cacerts

ルート証明書をインポートする場合は以下のように実行します。

# keytool -import -trustcacerts -alias YOUR_ALIAS -keystore /etc/pki/ca-trust/extracted/java/cacerts -file YOUR_CERTS_FILE

ルート証明書を削除する場合は以下のように実行します。

# keytool -delete -noprompt -alias YOUR_ALIAS -keystore /etc/pki/ca-trust/extracted/java/cacerts -storepass YOUR_PASSWORD
  • References

SSL証明書の中身

実際のSSL証明書は以下のようなファイルになります。

-----BEGIN CERTIFICATE-----
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END CERTIFICATE-----

証明書ファイルの中身は、大きく証明書本体と署名アルゴリズムと署名データの3つに分けられます。

証明書ファイルの中身は、大きく証明書本体と署名アルゴリズムと署名データの3つに分けられます。

証明書本体には公開鍵をはじめとする主要な情報が含まれており、TLSで認証に使用します。署名データは本体を署名アルゴリズムに従って暗号学的に生成したデータです。検証には3つすべてのデータを使用します。

先程、PEM形式とは、ASN.1というデータ構造やオブジェクトの定義等の方法を定めたものでデータを表現し、DERの方法でエンコーディングを行い、Base64エンコーディングでASCII形式で表現したものであることを説明しました。実際に、ASN.1の形式でパースすると、以下のような内容が含まれていることが分かります。最初のSEQUENCEからはしばらく証明書本体の中身に相当するものが続き、最後のSEQUENCERからは証明書アルゴリズムが続きます。最後に、BIT STRINGで署名された値になります。

$ openssl asn1parse -i -in cert.pem 
    0:d=0  hl=4 l= 932 cons: SEQUENCE          
    4:d=1  hl=4 l= 652 cons:  SEQUENCE          
    8:d=2  hl=2 l=   9 prim:   INTEGER           :CA2E336678056462
   19:d=2  hl=2 l=  13 cons:   SEQUENCE          
   21:d=3  hl=2 l=   9 prim:    OBJECT            :sha512WithRSAEncryption
   32:d=3  hl=2 l=   0 prim:    NULL              
   34:d=2  hl=3 l= 147 cons:   SEQUENCE          
   37:d=3  hl=2 l=  11 cons:    SET               
   39:d=4  hl=2 l=   9 cons:     SEQUENCE          
   41:d=5  hl=2 l=   3 prim:      OBJECT            :countryName
   46:d=5  hl=2 l=   2 prim:      PRINTABLESTRING   :JP
   50:d=3  hl=2 l=  14 cons:    SET               
   52:d=4  hl=2 l=  12 cons:     SEQUENCE          
   54:d=5  hl=2 l=   3 prim:      OBJECT            :stateOrProvinceName
   59:d=5  hl=2 l=   5 prim:      UTF8STRING        :Tokyo
   66:d=3  hl=2 l=  18 cons:    SET               
   68:d=4  hl=2 l=  16 cons:     SEQUENCE          
   70:d=5  hl=2 l=   3 prim:      OBJECT            :localityName
   75:d=5  hl=2 l=   9 prim:      UTF8STRING        :Shinagawa
   86:d=3  hl=2 l=  12 cons:    SET               
   88:d=4  hl=2 l=  10 cons:     SEQUENCE          
   90:d=5  hl=2 l=   3 prim:      OBJECT            :organizationName
   95:d=5  hl=2 l=   3 prim:      UTF8STRING        :AWS
  100:d=3  hl=2 l=  11 cons:    SET               
  102:d=4  hl=2 l=   9 cons:     SEQUENCE          
  104:d=5  hl=2 l=   3 prim:      OBJECT            :organizationalUnitName
  109:d=5  hl=2 l=   2 prim:      UTF8STRING        :SE
  113:d=3  hl=2 l=  31 cons:    SET               
  115:d=4  hl=2 l=  29 cons:     SEQUENCE          
  117:d=5  hl=2 l=   3 prim:      OBJECT            :commonName
  122:d=5  hl=2 l=  22 prim:      UTF8STRING        :alb.test.hayashier.com
  146:d=3  hl=2 l=  36 cons:    SET               
  148:d=4  hl=2 l=  34 cons:     SEQUENCE          
  150:d=5  hl=2 l=   9 prim:      OBJECT            :emailAddress
  161:d=5  hl=2 l=  21 prim:      IA5STRING         :xxxxxx@xxx.xxx
  184:d=2  hl=2 l=  30 cons:   SEQUENCE          
  186:d=3  hl=2 l=  13 prim:    UTCTIME           :211015152029Z
  201:d=3  hl=2 l=  13 prim:    UTCTIME           :211016152029Z
  216:d=2  hl=3 l= 147 cons:   SEQUENCE          
  219:d=3  hl=2 l=  11 cons:    SET               
  221:d=4  hl=2 l=   9 cons:     SEQUENCE          
  223:d=5  hl=2 l=   3 prim:      OBJECT            :countryName
  228:d=5  hl=2 l=   2 prim:      PRINTABLESTRING   :JP
  232:d=3  hl=2 l=  14 cons:    SET               
  234:d=4  hl=2 l=  12 cons:     SEQUENCE          
  236:d=5  hl=2 l=   3 prim:      OBJECT            :stateOrProvinceName
  241:d=5  hl=2 l=   5 prim:      UTF8STRING        :Tokyo
  248:d=3  hl=2 l=  18 cons:    SET               
  250:d=4  hl=2 l=  16 cons:     SEQUENCE          
  252:d=5  hl=2 l=   3 prim:      OBJECT            :localityName
  257:d=5  hl=2 l=   9 prim:      UTF8STRING        :Shinagawa
  268:d=3  hl=2 l=  12 cons:    SET               
  270:d=4  hl=2 l=  10 cons:     SEQUENCE          
  272:d=5  hl=2 l=   3 prim:      OBJECT            :organizationName
  277:d=5  hl=2 l=   3 prim:      UTF8STRING        :AWS
  282:d=3  hl=2 l=  11 cons:    SET               
  284:d=4  hl=2 l=   9 cons:     SEQUENCE          
  286:d=5  hl=2 l=   3 prim:      OBJECT            :organizationalUnitName
  291:d=5  hl=2 l=   2 prim:      UTF8STRING        :SE
  295:d=3  hl=2 l=  31 cons:    SET               
  297:d=4  hl=2 l=  29 cons:     SEQUENCE          
  299:d=5  hl=2 l=   3 prim:      OBJECT            :commonName
  304:d=5  hl=2 l=  22 prim:      UTF8STRING        :alb.test.hayashier.com
  328:d=3  hl=2 l=  36 cons:    SET               
  330:d=4  hl=2 l=  34 cons:     SEQUENCE          
  332:d=5  hl=2 l=   9 prim:      OBJECT            :emailAddress
  343:d=5  hl=2 l=  21 prim:      IA5STRING         :xxxxxx@xxx.xxx
  366:d=2  hl=4 l= 290 cons:   SEQUENCE          
  370:d=3  hl=2 l=  13 cons:    SEQUENCE          
  372:d=4  hl=2 l=   9 prim:     OBJECT            :rsaEncryption
  383:d=4  hl=2 l=   0 prim:     NULL              
  385:d=3  hl=4 l= 271 prim:    BIT STRING        
  660:d=1  hl=2 l=  13 cons:  SEQUENCE          
  662:d=2  hl=2 l=   9 prim:   OBJECT            :sha512WithRSAEncryption
  673:d=2  hl=2 l=   0 prim:   NULL              
  675:d=1  hl=4 l= 257 prim:  BIT STRING   

もっとわかりやすい形で確認していきましょう。以下のコマンドを実行することで確認できます。手元に証明書ファイルがある場合は、openssl x509 -in cert.pem -noout -textのように実行することで確認できます。

$ openssl s_client -connect alb.test.hayashier.com:443 < /dev/null 2> /dev/null | openssl x509 -noout -text
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            0b:cc:80:45:cd:fc:74:45:ad:b3:40:28:a8:cb:ac:5c
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=US, O=Amazon, OU=Server CA 1B, CN=Amazon
        Validity
            Not Before: Dec  1 00:00:00 2021 GMT
            Not After : Dec 29 23:59:59 2022 GMT
        Subject: CN=*.test.hayashier.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:dd:db:5d:e0:d4:93:aa:f9:08:74:12:15:11:27:
                    af:7c:ee:2a:43:f7:a2:2c:5e:93:2e:50:c4:7b:3f:
                    2e:70:f8:6a:a3:9d:75:e6:ea:93:30:ec:24:8b:63:
                    d7:03:51:3e:17:80:61:ce:ed:51:2a:a8:29:b8:9f:
                    3c:c0:97:8a:b7:10:53:1d:18:dd:42:62:3e:b0:16:
                    0a:9f:6e:ba:a2:2d:f9:6f:12:16:e3:3e:72:f8:36:
                    5b:95:c4:01:a7:65:7f:64:d4:66:4c:e7:df:fd:11:
                    cd:fe:53:3c:59:41:3f:8d:a2:0c:9a:d6:86:08:4b:
                    18:86:52:01:82:22:75:a1:0b:11:8b:3c:11:33:41:
                    ef:50:f6:01:06:84:c7:79:8a:f6:24:91:67:f5:06:
                    03:6d:78:fc:e3:5f:a9:39:f1:ef:8b:f8:cb:fe:f1:
                    71:5f:3d:be:b3:93:bd:ce:d3:07:a6:24:7c:82:07:
                    5b:22:03:40:3a:cf:1a:da:b2:46:3f:e6:2a:59:4d:
                    ff:df:b8:a5:77:dc:ff:ca:b7:4a:9f:6d:d8:9a:a6:
                    c0:79:73:89:6e:70:54:1b:69:39:04:fd:59:c8:06:
                    87:40:23:0c:c9:36:ef:38:ae:d5:86:3a:e8:3b:28:
                    18:66:c8:c3:bc:55:cc:20:a6:54:12:b1:16:b2:15:
                    91:ab
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Authority Key Identifier: 
                keyid:59:A4:66:06:52:A0:7B:95:92:3C:A3:94:07:27:96:74:5B:F9:3D:D0

            X509v3 Subject Key Identifier: 
                96:04:82:AB:B4:83:C8:97:65:4F:48:9E:F1:29:3A:0C:5B:64:87:4C
            X509v3 Subject Alternative Name: 
                DNS:*.test.hayashier.com, DNS:test.hayashier.com
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 CRL Distribution Points: 

                Full Name:
                  URI:http://crl.sca1b.amazontrust.com/sca1b-1.crl

            X509v3 Certificate Policies: 
                Policy: 2.23.140.1.2.1

            Authority Information Access: 
                OCSP - URI:http://ocsp.sca1b.amazontrust.com
                CA Issuers - URI:http://crt.sca1b.amazontrust.com/sca1b.crt

            X509v3 Basic Constraints: critical
                CA:FALSE
            1.3.6.1.4.1.11129.2.4.2: 
                ...j.h.v.)y...99!.Vs.c.w..W}.`
........}sX.......G0E. '...&..!Ig'.......7."x..m...OU...!....c...3u.....*.x;......6...W..x.v.A...."FJ...:.B.^N1.....K.h..b......}sX.c.........I*.3.Q..&..!.....-.G"...;.#h@PDi..*.....?K..G
    Signature Algorithm: sha256WithRSAEncryption
         6a:b0:93:0b:79:c2:60:90:8f:a5:6e:0f:de:e0:66:63:32:6e:
         42:b9:69:6a:80:43:27:1c:d4:b5:59:81:40:c1:c8:9e:7a:4a:
         62:e8:47:4b:7c:df:f7:a0:a9:5a:02:a8:d4:61:79:00:4a:7c:
         31:da:17:94:be:b9:d3:67:e2:56:84:17:6d:5c:ae:a3:8a:91:
         ba:b8:26:ae:0c:f3:c2:f2:84:fe:0e:87:a9:8f:be:db:34:62:
         02:3f:1b:3c:55:ec:7d:d9:ea:ef:53:ae:8d:74:50:d2:99:4b:
         85:12:fa:08:61:01:51:6a:43:bf:01:40:4c:25:08:9a:20:55:
         1d:54:d1:4d:6a:c8:e1:a7:f0:d9:6e:88:d3:11:01:29:af:39:
         0c:d7:64:71:38:e8:ff:99:b8:8b:98:d5:3f:d4:4f:15:32:85:
         25:9b:6d:16:c2:a2:b4:f5:92:42:06:68:c0:11:0c:38:6b:85:
         e5:aa:52:9e:e2:f2:4a:3c:79:87:34:88:27:f6:1e:9d:52:41:
         d1:11:b2:90:f6:ca:1a:76:6b:2f:46:d3:8c:71:66:76:30:cd:
         b2:a3:2a:57:e4:03:cc:fb:27:7d:e7:0d:16:c7:f5:ef:9d:33:
         94:00:f2:99:f2:7b:26:a4:9a:a6:30:55:2d:3f:ec:cb:08:d9:
         26:1d:6b:63

自己署名証明書の情報を確認します。ここでは、拡張情報は確認できないことが分かります。

$ openssl s_client -connect alb.test.hayashier.com:443 < /dev/null 2> /dev/null | openssl x509 -noout -text
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 17654627072782306786 (0xf501d5c8d32f0de2)
    Signature Algorithm: sha512WithRSAEncryption
        Issuer: C=JP, ST=Tokyo, L=Shinagawa, O=AWS, OU=SE, CN=alb.test.hayashier.com/emailAddress=xxxxxx@xxx.xxx
        Validity
            Not Before: Oct 15 16:38:49 2021 GMT
            Not After : Oct 16 16:38:49 2021 GMT
        Subject: C=JP, ST=Tokyo, L=Shinagawa, O=AWS, OU=SE, CN=alb.test.hayashier.com/emailAddress=xxxxxx@xxx.xxx
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:c7:7f:97:df:b0:dd:a8:0d:db:b0:47:c1:7e:5c:
                    97:95:5b:7f:4b:88:0b:af:2d:5a:0a:5e:8f:87:cd:
                    29:39:18:90:f7:7a:26:c0:23:f0:1a:12:a5:e9:d9:
                    20:56:62:d2:c7:02:38:65:33:6f:ed:73:1a:2e:cc:
                    04:51:e3:27:aa:bb:e5:e0:59:8e:ea:e6:3b:fe:6b:
                    8d:07:c3:8d:7a:ab:5e:2e:2f:ea:52:3a:a8:09:3c:
                    3d:95:6c:36:f9:c0:cc:8c:25:16:65:d2:3d:79:03:
                    34:12:22:bb:2f:4d:e5:81:a4:0e:0d:9b:47:ea:f4:
                    b9:e2:65:a6:d6:a7:38:d0:26:da:4f:b9:ea:f8:9f:
                    9c:96:92:70:ba:f1:9a:c5:ce:61:60:1c:a1:c2:27:
                    9a:91:ac:48:21:39:4f:b1:17:ac:a0:3b:75:27:c8:
                    39:7a:03:cf:89:70:d9:4d:e6:1a:6a:7c:c4:db:07:
                    82:ea:aa:b2:cb:4c:3a:c2:b0:01:fe:e3:20:8c:c5:
                    13:b6:70:a4:4d:5c:b3:8e:75:bc:66:aa:af:e3:a9:
                    35:50:9f:ca:e7:f8:a7:35:fc:b9:ff:44:16:9f:23:
                    4f:d1:2f:d2:ad:83:86:39:c0:0e:1c:6b:83:cc:e1:
                    ef:ec:74:a3:e0:e3:e2:5b:76:f5:ca:b7:73:df:ac:
                    de:45
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha512WithRSAEncryption
         65:08:dc:fd:2d:8f:df:92:bf:49:07:ec:9b:8a:71:0b:78:e0:
         e2:36:6d:80:33:e1:fe:6d:ef:2b:44:5c:8f:c6:cb:7e:16:8d:
         ff:ca:5c:68:ec:af:85:f9:a4:42:4a:1a:11:d4:0d:4f:04:0c:
         fd:d9:13:fa:39:e7:94:a8:c0:d2:6a:7a:1c:4a:1d:16:e7:c8:
         99:39:59:5e:8c:80:7a:59:71:56:23:14:08:fd:33:d6:2d:bf:
         0e:4f:64:53:e8:12:7e:93:f1:f1:7f:03:9c:ee:bf:be:e7:b0:
         53:38:d6:ec:6a:a8:a7:b0:90:b0:95:30:6a:7b:05:ff:f1:e0:
         4d:e7:5a:40:d9:1d:e7:d8:45:03:4c:cb:3b:bf:90:58:58:51:
         7b:d1:28:be:60:dc:62:c5:15:f4:8f:ad:06:34:3f:d2:df:19:
         af:8d:92:34:e2:6c:ca:8e:63:ca:32:82:c9:6f:8f:68:72:18:
         11:af:16:f8:00:90:e7:d8:fe:25:88:14:75:1b:a1:96:74:29:
         3d:57:bd:7a:e9:7c:fd:6c:68:f3:a8:e8:b2:83:34:b9:d6:2b:
         02:e7:5c:45:90:f3:98:01:4f:f5:e3:86:83:b8:18:38:d5:b8:
         0e:27:89:c8:f0:22:ea:a3:71:8b:ae:29:83:6b:95:86:03:96:
         d3:a2:51:58

最初にDataという証明書本体の中身があり、最後にSignature Algorithmで証明アルゴリズムとそれを利用したデジタル署名があることが確認できます。デジタル署名の部分にはData部を認証局の秘密鍵を使って計算したものが入ります。ただし時間の短縮のため、ダイジェスト方式が用いられます。 これにより、証明書のデジタル署名の部分には、上記のDataの部分を MD5などのハッシュ関数を用いてハッシュ値(メッセージダイジェスト)を得て、それを秘密鍵で暗号化したものがデジタル署名のところに入ります。

Data以降ではしばらく証明書本体の中身が続きます。項目をまとめると以下の内容になります。

  • 基本情報

    • バージョン : Version

    • シリアル番号 : Serial Number

    • 有効期限 : Validity

    • 署名方式 : Signature

    • 発行者 : Issuer

    • 所有者 : Subject

    • 公開鍵 : Subject Public Key Info

  • 拡張情報

    • 機関鍵識別子 : Authority Key Identifier

    • 所有者鍵識別子 : Subject Key Identifier

    • 鍵用途 : Key Usage

    • 拡張鍵用途 : Extended Key Usage

    • 所有者別名 : Subject Alternative Name

    • 失効リスト配布点 : CRL Distribution Points

    • 機関情報アクセス : Authority Information Access

  • References

検証

上記、証明書本体の中身のうち、検証の段階では以下のデータを使用します。

  • 基本情報

    • 発行者 : Issuer

    • 所有者 : Subject

    • 公開鍵 : Subject Public Key Info

  • 拡張情報

    • 機関鍵識別子 : Authority Key Identifier

    • 所有者鍵識別子 : Subject Key Identifier

発行者(Issuer)には証明書を発行した認証局の名前が入ります。発行機関と証明する内容などについては、C=JP, ST=Tokyo, L=Shinagawa, O=AWS, OU=SE, CN=alb.test.hayashier.com/emailAddress=xxxxxx@xxx.xxx ように書かれていますが、これはディレクトリシステムの仕様X.500に基づいた表現です。

所有者(Subject)には証明書の所有者の名前が入ります。ACMの場合はWebサーバーが使用するドメイン名が入ります。

公開鍵は、サーバー証明書の場合、Web サーバーが使う秘密鍵と対応する公開鍵が入ります。

上位の認証局の証明書とサーバー証明書の情報は関係性を持ちます。

上位の認証局の証明書の所有者(Subject)は、サーバー証明書の発行者(Issuer)と同じ値です。 上位の認証局の証明書の所有者鍵識別子(SKI)は、サーバー証明書の機関鍵識別子(AKI)と同じ値です。

上位の認証局の証明書およびサーバー証明書の所有者鍵識別子(SKI)は、上位の認証局の証明書の公開鍵に対する一意の識別子で、通常ハッシュ値が使用されます。

サーバー証明書の署名は、上位の認証局の証明書の秘密鍵とサーバー証明書から計算します。すなわち、検証する際は、上位の認証局の証明書の公開鍵とサーバー証明書で行います。

認証

認証の段階では、証明書本体の中身のうち、公開鍵(認証局の証明書の公開鍵のみ)もしくは所有者別名(SAN)を使用します。

  • 基本情報

    • 公開鍵 : Subject Public Key Info

  • 拡張情報

    • 所有者別名 : Subject Alternative Name

認証にはデジタル署名を活用します。アクセスしている相手が、サーバー証明書の公開鍵に対応する秘密鍵を持っていることで確かめます。

有効性

証明書の有効性の確認も行われます。その際、証明書本体の中身のうち、以下の情報を利用します。

  • 基本情報

    • 有効期限 : Validity

  • 拡張情報

    • 鍵用途 : Key Usage

    • 拡張鍵用途 : Extended Key Usage

    • 失効リスト配布点 : CRL Distribution Points

    • 機関情報アクセス : Authority Information Access

CRLとOCSPは証明書の失効状況確認に使用します。実際にこちらを活用して、失効状況の確認を行うかはクライアントに依存します。

CRLとは有効期限よりも前に失効させたデジタル証明書の一覧です。例えば、証明書の誤発行や証明書の秘密鍵紛失で悪用されるのを回避するために利用されます。デジタル証明書の受け取り側は、デジタル証明書とCRLを照合することで証明書が現在も有効であるかを確認できます。CRLは認証局から定期的に最新情報が配布されます。クライアントは、Webサイトなどから受信したサーバ証明書のシリアル番号とCRLに登録された証明書のシリアル番号を照合して有効性を確認できます。

OCSPはX.509公開鍵証明書の失効状態を取得するための通信プロトコルです。CRLの手法の代替手段として策定された実装です。OCSPクライアントがOCSPサーバ(OCSPレスポンダ)に対してデジタル証明書の有効性を確認します。

サーバー証明書の種類

  • DV証明書 : ドメイン認証

    • 認証局の人は対象ドメインを管理する権限があるかのみを確認

  • OV証明書 : 企業認証

    • ドメインの管理権に加え、運営組織の実在性などを電話などにより確認

  • EV証明書

    • OV証明書と同様の確認を行うが、確認方法が国際的な認定基準に基づいて行われる

  • References

証明書の検証の仕組み

サーバー証明書発行時

サーバー証明書を発行するにあたって、以下の流れで対応します。

  1. ルート認証局と中間認証局は、それぞれ自身の証明書に対応する秘密鍵と公開鍵を持っています。

  2. ユーザーは証明書作成のために、公開鍵と秘密鍵のペアを作成します。

  3. その鍵ペアを使って、CSR(署名要求) を作成します。作成したCSRで、電子証明書の発行依頼を中間認証局に行う

  4. 中間認証局はCSRの記載事項が正しいことを確認する。

  5. 中間認証局はCSRを使って電子証明書の発行を行う

ACMの場合、秘密鍵の生成、CSR生成、証明書の発行をマネージドに提供します。3つめの証明書の正しいことの確認は、DNS検証やEメール検証をします。

信頼チェーン(Chain of Trust)

検証するにあたっては、サーバー証明書からルート証明書までの証明書パスを探します。この信頼チェーンを通して、ルート証明書は既にローカルで信頼できるものとして認識しているので、サーバー証明書を確認することで、検証が可能になります。

サーバー証明書発行時に、以下の仕組みができています。この仕組みを利用して検証します。

  1. ルート認証局の秘密鍵を使って、自身のルート証明書に署名(自己署名)することでルート認証局が自身を正しいことを保証するものとする

  2. ルート認証局の秘密鍵を使って中間証明書に署名することで中間認証局が正しいことを保証

  3. 中間認証局の秘密鍵を使ってデジタル証明書に署名することでデジタル証明書に書かれたホスト名の機器は中間認証局が正しいことを保証

これによって、検証時は以下の流れで信頼チェーンを探すことができます。

  1. 中間認証局の公開鍵を使って、サーバー証明書の電子署名を復号し、実際のデジタル証明書のハッシュ値を計算したものと比較し、正当性を確認することで検証

  2. ルート証明書の公開鍵を使って、中間証明書の電子署名を復号し、実際のデジタル証明書のハッシュ値を計算したものと比較し、正当性を確認することで検証

  3. ルート証明書の公開鍵を使って、ルート証明書の電子署名を復号し、実際のデジタル証明書のハッシュ値を計算したものと比較し、正当性を確認することで検証

証明書パスを見つけるにあたって以下の方法があります。

  • ローカルの信頼ストア

  • サーバーから送信される証明書チェーン

  • 証明書のAKI

中間証明書は、サーバー証明書をインストールする際に、サーバー証明書と中間証明書を一つのファイルとしてつなげることで、 中間証明書も一緒にインストールするのが一般的です。ルート証明書のように信頼ストアにインストールされていることも多いですが、そうではないこともよくあることが理由です。

そのため、上記理由でローカルの信頼ストアはあまり使われず、サーバーから送信される証明書チェーンが基本的に使われます。

キーペアの中身

RSAの場合におけるキーペアの確認を確認します。

公開鍵の場合は以下のような内容になります。

$ openssl rsa -in public.pem -text -noout -pubin
Public-Key: (2048 bit)
Modulus:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
    :
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
Exponent: 65537 (0x10001)

公開鍵の場合は以下のような内容になります。

$ openssl rsa -in private.pem -text -noout         
Private-Key: (2048 bit)
modulus:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
publicExponent: 65537 (0x10001)
privateExponent:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
prime1:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
prime2:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
exponent1:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
exponent2:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
coefficient:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:
    xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:

ルート認証局と中間認証局が分かれている理由

信頼されたルート証明書は一度その秘密鍵が漏れてしまうと世界中のクライアントに影響が出てしまいます。その場合は速やかにそのルート証明書を失効し、新たな証明書を生成し、クライアントに配布する必要があります。

2階層だった場合、証明書を発行した上位認証局の証明書はルート証明書であるため、こちらを無効化することになりますが、それを実行した場合、発行した全ての証明書が無効になります。これでは影響範囲が大きいため、間に中間認証局を挟み、3階層にします。

ルート認証局はオフラインで構築しておき、別途構築した複数の中間認証局へ、それぞれ中間証明書を発行します。

  • References

自己証明書

ルート認証局が証明した証明書がある一方で、自己証明証明書とは所有者自身で署名した証明書になります。

前者がパブリック向けの使用に適しているのに対して、後者はクローズドな環境のみの利用に適しています。 前者であれば、信頼ストアにルート証明書を持っている、もしくはOSの信頼ストアを利用しているブラウザで基本的に信頼されていますが、後者では公開鍵を手動でインポートするまで信頼されません。 これに伴い、ルート認証局が署名した証明書では証明書の更新や修正はブラウザ側の変更は必要ありませんが、自己署名証明では更新や修正があるごとに新しい証明書をインポートし直す必要があります。

自己署名証明書は以下のように作成できます。

$ openssl genrsa 2048 > private.pem
$ openssl req -new -x509 -key private.pem -sha512 -days 1 -out cert.pem

公開鍵を作成する場合は以下

$ openssl rsa -pubout < private.pem > public.pem

ACMにインポートする場合は、以下の手順で実行します。

$ aws acm import-certificate --certificate file://cert.pem --private-key file://private.pem
$ aws acm describe-certificate --certificate-arn arn:aws:acm:ap-northeast-1:...
  • Reference

クロス証明書

ルート証明書から発行されたサーバ証明書を別のルート証明書が設定されているクライアントでも利用できるようにする仕組みです。

サーバー証明書と合わせて複数の中間証明書(証明書チェーン)が送信される場合もあります。これにより、TLS通信を行うクライアントでは証明書の検証にあたって複数の信頼パスを利用できます。このとき、検証でどの信頼パスもしくはルート証明書を選択するかは、Webブラウザーなどのクライアントに依存します。必要なルート証明書がインストールされていない場合や、不要な証明書チェーンが含まれている場合、提供されている証明書パスを利用するように証明書チェーンを再構築していない場合などに、意図しないルート証明書を選択することもあります。

例えば、新しい認証局を立ち上げる場合やルート証明書の移行、古くからあるルート証明書しか使えないクライアントに対して証明書を利用できるようにするといった場合に使用します。

ある証明書に対して、検証先の上位の証明書が分岐している場合、その証明書のIssuerと一致するSubjectおよびAKIと一致するSKIを持つ証明書が複数あります。すなわち、それらの証明書のSubjectやSKI(もしくは公開鍵)は同じ値を持ちます。Issuerは異なります。

Topics

トラブルシューティング

以上を踏まえて、TLSハンドシェイクに失敗する理由としては、例えば以下のようなものが挙げられます。TLS接続関連の問題のトラブルシューティングの際には参考になるかもしれません。

  • ネゴシエーションエラー

    • サーバー側の暗号スイートがクライアント側になく一致しない

      • サーバー側の暗号スイートのリストが新しく、クライアント側が保持しているリストが古い場合

    • プロトコルミスマッチ

  • 証明書の問題(サーバー証明書、クライアント証明書)

    • CN、ドメインの不一致

      • 親ドメインのワイルドカード指定は、親ドメインとは一致しない

    • 失効している

    • 有効でない

      • 自己証明証明書

      • CRL

      • OCSP

    • 信頼パス

      • ルート証明書がインストールされていない

      • 中間証明書が正しくない場合

    • 間違った証明書(そもそもアップロードができないこともある)

      • 秘密鍵

        • 暗号化(パスワードやパスフレーズで保護)された秘密鍵

        • フォーマットがおかしい

      • 公開鍵

        • 無効なフォーマット

          • X.509。PEMフォーマットでない

        • 証明書チェーンが無効

          • チェーンにユーザーの公開鍵が含まれてはいけない

          • 順序が間違っている

      • 証明書、秘密鍵、証明書チェーンがPEMエンコードされていない

      • 証明書チェーンにサーバー証明書自体が含まれている

      • チェーン内の中間証明書が正しい順序

        • チェーンの最初の証明書はサーバー証明書を発行したCAの証明書でないといけない

  • SNI対応

    • クライアントがSNI未対応(ALBの場合デフォルト証明書が選ばれる)

    • openssl s_clientの-servernameオプションの未指定

  • 相互認証

    • NLB/ALB/CLBでは未サポート

  • SMTPやPostgresなどのプロトコル

    • クライアントのClientHelloの前にいくつかのプロトコル変換が行われる

    • ELBはこれに対応していない

      • TCPリスナーを使用し、バックエンドインスタンス側で対応する必要がある

  • 環境問題

    • クライアントなどのネットワークの環境が貧弱

TLS通信の解読

TLS通信解読の方法は状況に応じていくつか方法があります。いずれの場合も第三者から通信を容易に読み取られるといった類のものではなく、デバッグなどの用途に使用するものです。

SSLKKEYLOGFILE変数を用いた方法

この方法はクライアント側で準備をしておくことにより、自身が行ったTLS通信の中身を確認するものです。このとき、SSL証明書の秘密鍵等は事前に準備する必要はありません。

以下のようにSSLKEYLOGFILE環境変数でログの出力先を指定したあとに、実際に解読対象の通信を行う。すると、変数に指定したログにデータが書き込まれる。

$ export SSLKEYLOGFILE=/home/ubuntu/sslkeylog.log
# ここでたとえば下記のように対象の通信を行う。
# $ curl https://hayashier.com
$ cat sslkeylog.log 
CLIENT_RANDOM xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Wiresharkで、Preferences... > Protocols > TLS の画面を開き、(Pre)-Master-Secret log filenameで上記ファイルを指定。TLS debug fileはデバッグログ出力するログのパス。うまくキャプチャできない場合に活用できる。

すると、TLSの通信も以下のように中身が見られるようになります。

1	2021-10-15 16:47:23.601334	172.31.5.148	44.237.150.182	TCP	74	35686 → 443 [SYN] Seq=0 Win=62727 Len=0 MSS=8961 SACK_PERM=1 TSval=3293266384 TSecr=0 WS=128
2	2021-10-15 16:47:23.601709	44.237.150.182	172.31.5.148	TCP	74	443 → 35686 [SYN, ACK] Seq=0 Ack=1 Win=26847 Len=0 MSS=1460 SACK_PERM=1 TSval=2439383746 TSecr=3293266384 WS=256
3	2021-10-15 16:47:23.601722	172.31.5.148	44.237.150.182	TCP	66	35686 → 443 [ACK] Seq=1 Ack=1 Win=62848 Len=0 TSval=3293266384 TSecr=2439383746
4	2021-10-15 16:47:23.608216	172.31.5.148	44.237.150.182	TLSv1.2	583	Client Hello
5	2021-10-15 16:47:23.608509	44.237.150.182	172.31.5.148	TCP	66	443 → 35686 [ACK] Seq=1 Ack=518 Win=28160 Len=0 TSval=2439383753 TSecr=3293266391
6	2021-10-15 16:47:23.613762	44.237.150.182	172.31.5.148	TLSv1.2	2406	Server Hello, Certificate, Server Key Exchange, Server Hello Done
7	2021-10-15 16:47:23.613777	172.31.5.148	44.237.150.182	TCP	66	35686 → 443 [ACK] Seq=518 Ack=2341 Win=60544 Len=0 TSval=3293266397 TSecr=2439383758
8	2021-10-15 16:47:23.614293	172.31.5.148	44.237.150.182	TLSv1.2	192	Client Key Exchange, Change Cipher Spec, Finished
9	2021-10-15 16:47:23.615913	44.237.150.182	172.31.5.148	TLSv1.2	117	Change Cipher Spec, Finished
10	2021-10-15 16:47:23.615921	172.31.5.148	44.237.150.182	TCP	66	35686 → 443 [ACK] Seq=644 Ack=2392 Win=60544 Len=0 TSval=3293266399 TSecr=2439383760
11	2021-10-15 16:47:23.615974	44.237.150.182	172.31.5.148	HTTP2	135	SETTINGS[0], WINDOW_UPDATE[0]
12	2021-10-15 16:47:23.615976	172.31.5.148	44.237.150.182	TCP	66	35686 → 443 [ACK] Seq=644 Ack=2461 Win=60544 Len=0 TSval=3293266399 TSecr=2439383760
13	2021-10-15 16:47:23.616043	172.31.5.148	44.237.150.182	HTTP2	119	Magic
14	2021-10-15 16:47:23.616049	172.31.5.148	44.237.150.182	HTTP2	122	SETTINGS[0]
15	2021-10-15 16:47:23.616063	172.31.5.148	44.237.150.182	HTTP2	108	WINDOW_UPDATE[0]
16	2021-10-15 16:47:23.616091	172.31.5.148	44.237.150.182	HTTP2	140	HEADERS[1]: GET /
17	2021-10-15 16:47:23.616111	172.31.5.148	44.237.150.182	HTTP2	104	SETTINGS[0]
18	2021-10-15 16:47:23.616529	44.237.150.182	172.31.5.148	TCP	66	443 → 35686 [ACK] Seq=2461 Ack=907 Win=28160 Len=0 TSval=2439383761 TSecr=3293266399
19	2021-10-15 16:47:23.616696	44.237.150.182	172.31.5.148	HTTP2	104	SETTINGS[0]
20	2021-10-15 16:47:23.616698	172.31.5.148	44.237.150.182	TCP	66	35686 → 443 [ACK] Seq=907 Ack=2499 Win=60544 Len=0 TSval=3293266399 TSecr=2439383761
21	2021-10-15 16:47:23.649782	44.237.150.182	172.31.5.148	HTTP2	808	HEADERS[1]: 200 OK, DATA[1]
22	2021-10-15 16:47:23.649783	44.237.150.182	172.31.5.148	HTTP2	104	DATA[1] (text/html)
23	2021-10-15 16:47:23.649811	172.31.5.148	44.237.150.182	TCP	66	35686 → 443 [ACK] Seq=907 Ack=3241 Win=59904 Len=0 TSval=3293266433 TSecr=2439383793
24	2021-10-15 16:47:23.649816	172.31.5.148	44.237.150.182	TCP	66	35686 → 443 [ACK] Seq=907 Ack=3279 Win=59904 Len=0 TSval=3293266433 TSecr=2439383793
25	2021-10-15 16:47:23.650796	172.31.5.148	44.237.150.182	TLSv1.2	97	Alert (Level: Warning, Description: Close Notify)
26	2021-10-15 16:47:23.651117	44.237.150.182	172.31.5.148	TCP	66	443 → 35686 [FIN, ACK] Seq=3279 Ack=938 Win=28160 Len=0 TSval=2439383795 TSecr=3293266434
27	2021-10-15 16:47:23.651408	172.31.5.148	44.237.150.182	TCP	66	35686 → 443 [FIN, ACK] Seq=938 Ack=3280 Win=59904 Len=0 TSval=3293266434 TSecr=2439383795
28	2021-10-15 16:47:23.651658	44.237.150.182	172.31.5.148	TCP	66	443 → 35686 [ACK] Seq=3280 Ack=939 Win=28160 Len=0 TSval=2439383796 TSecr=3293266434

次にtsharkにおける実行方法にも触れます。

tsharkをインストールするため、Macの場合は以下のようにWireshark付属の形でインストールします。

$ brew install --cask wireshark

tsharkの場合は以下のように実行します。GUIで既に解読している場合は設定を解除しておいてください。GUIの方で設定していると特にキーログファイルを指定しなくても解読されます。

$ tshark \
    -r ./ssldecrypt.pcap \
    -o "tls.keylog_file:./sslkeylog.log" \
    -o "tls.debug_file:./tlsdebug.log"

すると、以下のように通信が見られるようになります。

    1   0.000000 172.31.5.148 → 44.237.150.182 TCP 74 35686 → 443 [SYN] Seq=0 Win=62727 Len=0 MSS=8961 SACK_PERM=1 TSval=3293266384 TSecr=0 WS=128
    2   0.000375 44.237.150.182 → 172.31.5.148 TCP 74 443 → 35686 [SYN, ACK] Seq=0 Ack=1 Win=26847 Len=0 MSS=1460 SACK_PERM=1 TSval=2439383746 TSecr=3293266384 WS=256
    3   0.000388 172.31.5.148 → 44.237.150.182 TCP 66 35686 → 443 [ACK] Seq=1 Ack=1 Win=62848 Len=0 TSval=3293266384 TSecr=2439383746
    4   0.006882 172.31.5.148 → 44.237.150.182 TLSv1 583 Client Hello
    5   0.007175 44.237.150.182 → 172.31.5.148 TCP 66 443 → 35686 [ACK] Seq=1 Ack=518 Win=28160 Len=0 TSval=2439383753 TSecr=3293266391
    6   0.012428 44.237.150.182 → 172.31.5.148 TLSv1.2 2406 Server Hello, Certificate, Server Key Exchange, Server Hello Done
    7   0.012443 172.31.5.148 → 44.237.150.182 TCP 66 35686 → 443 [ACK] Seq=518 Ack=2341 Win=60544 Len=0 TSval=3293266397 TSecr=2439383758
    8   0.012959 172.31.5.148 → 44.237.150.182 TLSv1.2 192 Client Key Exchange, Change Cipher Spec, Finished
    9   0.014579 44.237.150.182 → 172.31.5.148 TLSv1.2 117 Change Cipher Spec, Finished
   10   0.014587 172.31.5.148 → 44.237.150.182 TCP 66 35686 → 443 [ACK] Seq=644 Ack=2392 Win=60544 Len=0 TSval=3293266399 TSecr=2439383760
   11   0.014640 44.237.150.182 → 172.31.5.148 HTTP2 135 SETTINGS[0], WINDOW_UPDATE[0]
   12   0.014642 172.31.5.148 → 44.237.150.182 TCP 66 35686 → 443 [ACK] Seq=644 Ack=2461 Win=60544 Len=0 TSval=3293266399 TSecr=2439383760
   13   0.014709 172.31.5.148 → 44.237.150.182 HTTP2 119 Magic
   14   0.014715 172.31.5.148 → 44.237.150.182 HTTP2 122 SETTINGS[0]
   15   0.014729 172.31.5.148 → 44.237.150.182 HTTP2 108 WINDOW_UPDATE[0]
   16   0.014757 172.31.5.148 → 44.237.150.182 HTTP2 140 HEADERS[1]: GET /
   17   0.014777 172.31.5.148 → 44.237.150.182 HTTP2 104 SETTINGS[0]
   18   0.015195 44.237.150.182 → 172.31.5.148 TCP 66 443 → 35686 [ACK] Seq=2461 Ack=907 Win=28160 Len=0 TSval=2439383761 TSecr=3293266399
   19   0.015362 44.237.150.182 → 172.31.5.148 HTTP2 104 SETTINGS[0]
   20   0.015364 172.31.5.148 → 44.237.150.182 TCP 66 35686 → 443 [ACK] Seq=907 Ack=2499 Win=60544 Len=0 TSval=3293266399 TSecr=2439383761
   21   0.048448 44.237.150.182 → 172.31.5.148 HTTP2 808 HEADERS[1]: 200 OK, DATA[1]
   22   0.048449 44.237.150.182 → 172.31.5.148 HTTP2 104 DATA[1] (text/html)
   23   0.048477 172.31.5.148 → 44.237.150.182 TCP 66 35686 → 443 [ACK] Seq=907 Ack=3241 Win=59904 Len=0 TSval=3293266433 TSecr=2439383793
   24   0.048482 172.31.5.148 → 44.237.150.182 TCP 66 35686 → 443 [ACK] Seq=907 Ack=3279 Win=59904 Len=0 TSval=3293266433 TSecr=2439383793
   25   0.049462 172.31.5.148 → 44.237.150.182 TLSv1.2 97 Alert (Level: Warning, Description: Close Notify)
   26   0.049783 44.237.150.182 → 172.31.5.148 TCP 66 443 → 35686 [FIN, ACK] Seq=3279 Ack=938 Win=28160 Len=0 TSval=2439383795 TSecr=3293266434
   27   0.050074 172.31.5.148 → 44.237.150.182 TCP 66 35686 → 443 [FIN, ACK] Seq=938 Ack=3280 Win=59904 Len=0 TSval=3293266434 TSecr=2439383795
   28   0.050324 44.237.150.182 → 172.31.5.148 TCP 66 443 → 35686 [ACK] Seq=3280 Ack=939 Win=28160 Len=0 TSval=2439383796 TSecr=3293266434

RSA秘密鍵を登録する方法

SSL証明書の秘密鍵等は事前に準備できる場合に、利用できる方法です。

この場合もいくつか方法がありますが、たとえば、以下の3つの方法で秘密鍵を登録することができます。

  • Wireshark > Preferences... > RSA Keys を選択後、Add new keyfile...

  • Wireshark > Preferences... > Protocols > TLSを選択後、RSA Keys list

  • 対象のTLS通信のパケットを右クリック > Protocol Preferences > Transport Layer Security > RSA keys list....

以下の記事で上記3つの方法のうち、最後の方法を利用した解説をしています。

##################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################

Topics

TLS拡張

  • References

SNI

接続テスト

$ openssl s_client -connect alb.test.hayashier.com:443 -servername alb.test.hayashier.com

SNIが利用できない場合は、SANを利用したり、リスナーやロードバランサーを分ける等の対応が必要になります。

NPN

ALPN

TLS False Start

TLS 再ネゴシエーション

OCSPステープリング

セッションチケット

Certificate Transparency

Public Key Pinning

  • References

Slide 22

ssldumpのやり方は古い?うまくいかず

$ sudo apt install ssldump -y
$ ssldump -v
ssldump 1.0
Copyright (C) 1998-2001 RTFM, Inc.
All rights reserved.
Compiled with OpenSSL: decryption enabled

ダンプしても解読されない

$ sudo ssldump -d -k ~/private.pem port 443 and host alb.test.hayashier.com
New TCP connection #1: ip-172-31-5-148.us-west-2.compute.internal(58156) <-> ec2-44-240-232-112.us-west-2.compute.amazonaws.com(443)
1 1  0.0073 (0.0073)  C>S  Handshake
      ClientHello
        Version 3.3 
        resume [32]=
          52 ba 08 9f b3 3c 46 ce c1 20 25 43 ac e5 24 6f 
          f5 31 95 60 3a 2a e4 be 2e b1 0e 65 0c 11 a1 f5 
        cipher suites
        TLS_AES_256_GCM_SHA384
        TLS_CHACHA20_POLY1305_SHA256
        TLS_AES_128_GCM_SHA256
        TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
        TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
        TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
        TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
        TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
        TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256
        TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
        TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
        TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
        TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
        TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
        TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
        TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
        TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
        TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
        TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
        TLS_DHE_RSA_WITH_AES_256_CBC_SHA
        TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
        TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
        TLS_DHE_RSA_WITH_AES_128_CBC_SHA
        TLS_RSA_WITH_AES_256_GCM_SHA384
        TLS_RSA_WITH_AES_128_GCM_SHA256
        TLS_RSA_WITH_AES_256_CBC_SHA256
        TLS_RSA_WITH_AES_128_CBC_SHA256
        TLS_RSA_WITH_AES_256_CBC_SHA
        TLS_RSA_WITH_AES_128_CBC_SHA
        TLS_EMPTY_RENEGOTIATION_INFO_SCSV
        compression methods
                  NULL
        extensions
          server_name
              host_name: alb.test.hayashier.com
          next_protocol_negotiation
          application_layer_protocol_negotiation
          encrypt_then_mac
          extended_master_secret
          signature_algorithms
1 2  0.0135 (0.0062)  S>C  Handshake
      ServerHello
        Version 3.3 
        session_id[32]=
          bd 2b 71 9f 0e 32 b4 69 72 96 fd 3c 5a 05 1f 9b 
          fa 64 3d b5 71 b7 4b 2b a1 ff 95 ce c8 c1 a1 ca 
        cipherSuite         TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
        compressionMethod                   NULL
        extensions
          application_layer_protocol_negotiation
1 3  0.0135 (0.0000)  S>C  Handshake
      Certificate
1 4  0.0135 (0.0000)  S>C  Handshake
      ServerKeyExchange
Not enough data. Found 327 bytes (expecting 32767)
1 5    0.0135   (0.0000)    S>C    Handshake
        ServerHelloDone
1 6    0.0141   (0.0005)    C>S    Handshake
        ClientKeyExchange
          DiffieHellmanClientPublicValue[65]=
            04 0b a6 93 d2 b4 e8 d0 e3 74 4d 90 24 94 10 46 
            cd b7 ec 6b 94 b4 df 0e ad 41 a5 7d ea 08 c3 5f 
            c1 78 ec 23 65 95 23 5c 44 16 b4 c4 70 b4 39 ee 
            dc 10 ac 0f 9b ac 82 98 5b 98 09 dd 04 c7 5a 23 
            8d 
1 7    0.0141   (0.0000)    C>S    ChangeCipherSpec
1 8    0.0141   (0.0000)    C>S      Handshake
1 9    0.0164   (0.0022)    S>C    ChangeCipherSpec
1 10   0.0164   (0.0000)    S>C      Handshake
1 11   0.0165   (0.0001)    S>C      application_data
1 12   0.0166   (0.0000)    C>S      application_data
1 13   0.0166   (0.0000)    C>S      application_data
1 14   0.0166   (0.0000)    C>S      application_data
1 15   0.0166   (0.0000)    C>S      application_data
1 16   0.0166   (0.0000)    C>S      application_data
1 17   0.0175   (0.0008)    S>C      application_data
1 18   0.0213   (0.0037)    S>C      application_data
1 19   0.0213   (0.0000)    S>C      application_data
1 20   0.0216   (0.0002)    C>S      Alert
  1      0.0222   (0.0005)    C>S    TCP FIN
  1      0.0226   (0.0003)    S>C    TCP FIN

解読されたらこうなるはず https://fm4dd.com/openssl/https-analyzing.shtm

TLS 1.3

  • NLBではTLS 1.3対応した。ALBもTLS 1.3対応予定。Bootcampのころには対応しているかも

  • バージョン 1.2 との違いは、大きく以下の 3 つで

    1. セキュリティ強度の高い暗号アルゴリズムを要求

    2. セッションのリネゴシエーションや再開に関する脆弱性のある方式を廃止し、セッション再開については新たな方式を採用

    3. ネゴシエーション (handshake) シーケンスの大幅な変更

  • 1の暗号アルゴリズムについては、ストリーム暗号 (RC4)、CBC ブロック暗号などの問題がある古い暗号アルゴリズムを廃止し、AEAD (認証付き暗号) 方式が要求されるようになりました。

    • また、静的な公開鍵を使う鍵交換方式 (RSA による鍵交換や、Static DH) は廃止となりました。(デジタル署名としての RSA は引き続き有用な方式として利用可能です)

    • つまり鍵交換には必ず Ephemeral Diffie-Hellman (DHE) および Ephemeral Elliptic Curve Diffie-Hellman (ECDHE) のどちらかが使われることになりました。

  • 2については脆弱性のあったリネゴシエーションや圧縮、"Session ID" や "Session Ticket" を使ったセッション再開などが廃止となりました。厳密に言うと、Session Ticket は PSK (Pre Shared Key) と統合されました。

  • 3について、TLS v1.3 のシーケンスの変更は、Google が開発した SPDY や QUIC の思想に影響されたものであり、さらに QUIC との融合を果たす予定の HTTP/3 へとつなげるためのものだと考えています。これらは全てセキュアかつ高速な Web 通信を目指し、最適なプロトコルを模索したプロセスでもあります。

    • Google は SPDY を開発した 2009 年頃から、RTT (Round Trip Time: 通信の往復時間) の影響を少なくすること (具体的にはネゴシエーションによる往復を極力少なくすること) が帯域を増やすよりも重要であることを主張してきました。SPDY や QUIC の開発、今回の TLS のシーケンス変更もその流れに沿うものです。

  • TLS v1.2 と v1.3 のシーケンス, Handshake の比較

    • TLS v1.3 においてはデータ送信までのネゴシエーションの往復が 1 回減っているのが分かります。

    • Server Key ExchangeはServer Helloのkey_share Extension、Client Key ExchangeはClient Helloのkey_share Extensionにそれぞれに移動

    • また、ネゴの途中から暗号化されていること (特にサーバ証明書が (クライアント証明書も) 暗号化されていること) も大きな特徴です。

    • Application Dataは2往路目から送信される

Slide 29 TLS 1.3 – Hello Retry Request

  • key_share とは何か?

    • key_share は TLS v1.3 (RFC8446) にて定められた、鍵交換方式のための extension (拡張属性) です。

      • TLS v1.2 までは鍵交換方式は Client Hello / Server Hello の "Cipher Suite" フィールドでネゴシエーションされ、その後、DH 公開鍵などの鍵交換の元ネタを Server Key Exchange / Client Key Exchange に乗っけて送っていました。

      • TLS v1.3 以降では、Client Hello / Server Hello の Supported_Groups extension で、鍵交換方式の候補を複数提示し、key_share extension でそれら候補のうちいくつかのキー元ネタ (DH 公開鍵など) も送ってしまいます。

  • Hello Retry Request とは何か?

    • TLS 1.3 では Hello Retry Request という新たなメッセージが設けられました。

    • 今までは鍵交換は Client Hello と Server Hello のネゴシエーションの間に『方式』が決まり、その後に具体的な鍵交換が行われていましたが、1.3 からは最初の Client Hello に supported_groups と key_share で鍵交換のパラメータが入ったりします。

    • ので一発目は不発に終わる可能性もあります。その場合サーバは Hello Retry Request で受け入れられるネゴシエーション情報を送り、Client Hello は適切なパラメータに修正して再送します。

Slide 30 TLS 1.3 – Adapt new way about Session Resumption

  • New Session Ticket とは何か?

    • 『New Session Ticket』は TLS のセッションの再開を行うためのもの

      • TLS 1.2 までのセッション再開方式=SessionID/SessionTicket

        • セッション ID 方式

          • TLS 1.2 においては、セッション回復方法としてはもともと『セッション ID 方式』のみが規定されていましたが、この方式ではセッション ID を照合するためにサーバではキャッシュ情報をタイムアウトまで持ち続ける必要がありました。

        • セッションチケット方式

          • クライアントは次回コネクション時の Client Hello 内の『Extension: SessionTicket TLS』にこのチケットを提示し、サーバ側ではそれを読み込み、その内容に沿ったセッション回復を行います。

          • このとき、厳密にはサーバの認証は行われませんが、サーバが正しくないとチケットを復号できないのでセッション再開は不可です。

      • TLS 1.3 以降のセッション再開方式=PSK

        • TLS 1.3 においては、従来の『セッション ID 方式』と『セッションチケット方式』は廃止

        • 代わりにセッションチケットが PSK (Pre-Shared Key) に統合され、相互認証を行いつつ、セッションが再開されるようになりました。

        • PSK の本来の使い方は RFC 4279 で定義されており、クライアントアプリケーションとサーバアプリケーションでお互いに PSK を手動でセットし、それをもって互いが正しい通信先だと解釈し (この PSK 認証方式の場合、サーバ証明書は不要となる)、さらにそれを素に共通鍵を生成するのです。

        • 今回の改訂により、サーバはセッション中の New Session Ticket にて PSK を払い出し、次回セッション再開時にクライアントは PSK による認証をしつつ、PSK を素にしたセッション回復 (Session Resumption)を行うことができるようになりました。つまり、今まで静的な PSK しか使えなかったのが、動的な PSK にも対応するようになったのです。

  • シーケンス図

    • 通常

    • TLS v1.3 の PSK を使った 1-RTT でのセッション再開

    • TLS v1.3 の PSK を使った 0-RTT でのセッション再開

      • HTTP/3 (HTTP over QUIC) で実装されることがほぼ決まっており、TLSv1.3 作成時でこの HTTP/3 を相当意識していたものと思われます。

      • ただし、セキュリティ的にやや甘く、実装は任意になっています。

  • メリット

    1. TLSの旧版のプロトコルではクライアントがサーバーにアプリケーション・データを送出する前に2往復を必要

      • TLS1.3では1往復で済んでしまいます。

      • サーバはクライアントに対する最初のハンドシェイク・メッセージのレスポンスとしてアプリケーション・データを送ってしまうことも可能

        • これは、ネットワークの遅れがあっても、安全な接続を確立するのに要する時間への影響は少なくなるということ

    2. セッション再開

      • これまでのTLSではクライアントはサーバがキャッシュを探すためのセッションIDを持っていました。もし、マッチした場合は同じセキュリティ・パラメータを使うことになりました。これは、非常に単純ですが、サーバ間で状態を共有する必要がありました。

      • TLS1.3では、これまでのTLSのチケット・システムを再活用する形で、画期的に進歩しました。ハンドシェーク完了後にサーバはクライアントに対して新しいセッション・チケットを送るようにします。

        • この、クライアントに対するひとかたまりのデータであるチケットは、以前のセッションIDのように鍵を探すデータベースとして利用することができます。ただしこのデータは、前の接続に対応する、自身で暗号化、認証された値とすることができます。つまり、サーバは状態を持たないですむということになります

    3. 以前あったような再ネゴシエーション、プロトコル・バージョンのダウングレーディング、圧縮、 CBCやパディングに対する攻撃などは改善され、プロトコルは全体的により強い攻撃耐性を実現

  • TLS1.2 と TLS 1.3、どこが違うの?

    • TLS 1.3のリリースでは、セキュリティとスピードの向上が約束されています。しかし、TLS 1.2からTLS 1.3への変更は、これらの改善をどのように実現しているのでしょうか?

      • TLS1.3は、2017年4月のインタネット・ドラフトで定義されました。

      • 対称暗号アルゴリズムでは、全ての古いアルゴリズムは取り除かれ、TLS1.3で残っているアルゴリズムはすべて、AEAD(Authenticated Encryption with Associated Data) で認証された暗号化を使用します。

      • ゼロRTT(0-RTT)モードが追加され、一部のセキュリティ特性を犠牲にすることで一部のアプリケーションデータの接続設定では往復回数を削減できるようになりました。

      • ServerHello以後のすべてのハンドシェークメッセージは暗号化されます。

      • HMACベースのExtract-and-Expand Key Derivation Function(HKDF)をプリミティブとして使用して、鍵導出関数を再設計しました。

      • ハンドシェイク状態遷移は、より一貫性があり余分なメッセージを取り除くよう再構成されました。

      • ECCは基本仕様に入り、複数の新しい署名アルゴリズムが含まれています。楕円曲線のポイント・フォーマット・ネゴシエーションは、各楕円曲線の単一ポイント・フォーマットを使用することで削除されました。

      • 圧縮、カスタムDHEグループ、およびDSAが削除されました。RSAパディングでPSSが使用されるようになりました。

      • TLS 1.2のバージョンネゴシエーション検証メカニズムは、拡張機能のバージョンリストを使用して廃止されました。

      • セッション再開については、サーバー側の状態の有無にかかわらず旧バージョンTLSのPSKベースの暗号スイートから、1つの新しいPSK交換方式に統一されました。

  • References

  • TLS 1.3 では,暗号スイートの定義方法が変更されています.鍵交換とサーバ認証が削除され,次のような組み合わせです.TLS_[認証付暗号]_[ハッシュ]

    • その他,以下のような変更があります.

      • 共通鍵暗号アルゴリズムでは,認証付暗号 (AEAD: Authenticated Encryption with Associated Data) を用いる.

      • 鍵導出関数は,HKDF (HMAC-based Extract-and-Expand Key Derivation Function) に変更された.

      • 鍵交換方法は,Forward security を持つものに限られる.

      • 鍵交換には 3つのモード (EC)DHE,PSK-only,PSK with (EC)DHE がある.

      • 楕円曲線暗号アルゴリズムが基本仕様となった.

    • 主な暗号スイートの例です.

      • TLS_AES_128_GCM_SHA256

      • TLS_AES_256_GCM_SHA384

      • TLS_CHACHA20_POLY1305_SHA256

      • TLS_AES_128_CCM_SHA256

      • TLS_AES_128_CCM_8_SHA256

  • References

pkcs8について

$ openssl genrsa > server.key
$ openssl req -new -key server.key -out req.txt
$ openssl pkcs8 -topk8 -in server.key -out pkcs8.pem -nocrypt
$ openssl x509 -signkey server.key -req -in req.txt -days 365 > server.crt
$ aws iam upload-server-certificate --server-certificate-name ExampleCert --certificate-body file://server.crt --private-key file://pkcs8.pem

CaseID: 2119584253, 2123406113

Links

Javaにおけるルート証明書

ルート証明書のインストールが足りないと以下のようなエラーが出る。 Ref: 2188557603

Caused by: redis.clients.jedis.exceptions.JedisConnectionException: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
  • キーストアファイルは一般的に /etc/ssl/certs/java/cacerts や /etc/pki/ca-trust/extracted/java/cacerts などが利用されている

# ルート証明書の一覧
$ sudo keytool -v -list -keystore {キーストアファイル} | egrep "Amazon|Starfield"

# ルート証明書のインポート
$ sudo keytool -import -trustcacerts -alias {エイリアス名} -keystore {キーストアファイル} -file {インポート対象の証明書ファイル}

# ルート証明書の削除
$ sudo keytool -delete -noprompt -alias "starfieldservicesrootcertificateauthority-g2" -keystore /etc/pki/ca-trust/extracted/java/cacerts -storepass "changeit"

ルート証明書は、例えば、以下のようなところからダウンロードしてくる。

  • Links

$ keytool -v -list -keystore /etc/pki/ca-trust/extracted/java/cacerts
Warning: use -cacerts option to access cacerts keystore
Enter keystore password:  

*****************  WARNING WARNING WARNING  *****************
* The integrity of the information stored in your keystore  *
* has NOT been verified!  In order to verify its integrity, *
* you must provide your keystore password.                  *
*****************  WARNING WARNING WARNING  *****************

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 127 entries

Alias name: accvraiz1
Creation date: Oct 2, 2021
Entry type: trustedCertEntry

Owner: C=ES, O=ACCV, OU=PKIACCV, CN=ACCVRAIZ1
Issuer: C=ES, O=ACCV, OU=PKIACCV, CN=ACCVRAIZ1
Serial number: 5ec3b7a6437fa4e0
Valid from: Thu May 05 09:37:37 UTC 2011 until: Tue Dec 31 09:37:37 UTC 2030
Certificate fingerprints:
	 SHA1: 93:05:7A:88:15:C6:4F:CE:88:2F:FA:91:16:52:28:78:BC:53:64:17
	 SHA256: 9A:6E:C0:12:E1:A7:DA:9D:BE:34:19:4D:47:8A:D7:C0:DB:18:22:FB:07:1D:F1:29:81:49:6E:D1:04:38:41:13
Signature algorithm name: SHA1withRSA
Subject Public Key Algorithm: 4096-bit RSA key
Version: 3

Extensions: 

#1: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
  [
   accessMethod: caIssuers
   accessLocation: URIName: http://www.accv.es/fileadmin/Archivos/certificados/raizaccv1.crt
, 
   accessMethod: ocsp
   accessLocation: URIName: http://ocsp.accv.es
]
]

#2: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: D2 87 B4 E3 DF 37 27 93   55 F6 56 EA 81 E5 36 CC  .....7'.U.V...6.
0010: 8C 1E 3F BD                                        ..?.
]
]

#3: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:true
  PathLen:2147483647
]

#4: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
  [DistributionPoint:
     [URIName: http://www.accv.es/fileadmin/Archivos/certificados/raizaccv1_der.crl]
]]

#5: ObjectId: 2.5.29.32 Criticality=false
CertificatePolicies [
  [CertificatePolicyId: [2.5.29.32.0]
[PolicyQualifierInfo: [
  qualifierID: 1.3.6.1.5.5.7.2.2
  qualifier: 0000: 30 82 01 14 1E 82 01 10   00 41 00 75 00 74 00 6F  0........A.u.t.o
0010: 00 72 00 69 00 64 00 61   00 64 00 20 00 64 00 65  .r.i.d.a.d. .d.e
0020: 00 20 00 43 00 65 00 72   00 74 00 69 00 66 00 69  . .C.e.r.t.i.f.i
0030: 00 63 00 61 00 63 00 69   00 F3 00 6E 00 20 00 52  .c.a.c.i...n. .R
0040: 00 61 00 ED 00 7A 00 20   00 64 00 65 00 20 00 6C  .a...z. .d.e. .l
0050: 00 61 00 20 00 41 00 43   00 43 00 56 00 20 00 28  .a. .A.C.C.V. .(
0060: 00 41 00 67 00 65 00 6E   00 63 00 69 00 61 00 20  .A.g.e.n.c.i.a. 
0070: 00 64 00 65 00 20 00 54   00 65 00 63 00 6E 00 6F  .d.e. .T.e.c.n.o
0080: 00 6C 00 6F 00 67 00 ED   00 61 00 20 00 79 00 20  .l.o.g...a. .y. 
0090: 00 43 00 65 00 72 00 74   00 69 00 66 00 69 00 63  .C.e.r.t.i.f.i.c
00A0: 00 61 00 63 00 69 00 F3   00 6E 00 20 00 45 00 6C  .a.c.i...n. .E.l
00B0: 00 65 00 63 00 74 00 72   00 F3 00 6E 00 69 00 63  .e.c.t.r...n.i.c
00C0: 00 61 00 2C 00 20 00 43   00 49 00 46 00 20 00 51  .a.,. .C.I.F. .Q
00D0: 00 34 00 36 00 30 00 31   00 31 00 35 00 36 00 45  .4.6.0.1.1.5.6.E
00E0: 00 29 00 2E 00 20 00 43   00 50 00 53 00 20 00 65  .)... .C.P.S. .e
00F0: 00 6E 00 20 00 68 00 74   00 74 00 70 00 3A 00 2F  .n. .h.t.t.p.:./
0100: 00 2F 00 77 00 77 00 77   00 2E 00 61 00 63 00 63  ./.w.w.w...a.c.c
0110: 00 76 00 2E 00 65 00 73                            .v...e.s

], PolicyQualifierInfo: [
  qualifierID: 1.3.6.1.5.5.7.2.1
  qualifier: 0000: 16 24 68 74 74 70 3A 2F   2F 77 77 77 2E 61 63 63  .$http://www.acc
0010: 76 2E 65 73 2F 6C 65 67   69 73 6C 61 63 69 6F 6E  v.es/legislacion
0020: 5F 63 2E 68 74 6D                                  _c.htm

]]  ]
]

#6: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
  Key_CertSign
  Crl_Sign
]

#7: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  RFC822Name: accv@accv.es
]

#8: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: D2 87 B4 E3 DF 37 27 93   55 F6 56 EA 81 E5 36 CC  .....7'.U.V...6.
0010: 8C 1E 3F BD                                        ..?.
]
]



*******************************************
*******************************************
:
PreviousTCP 入門Nextksnctf: HTTPS is secure, Writeup (TLS 通信解読)

Last updated 16 days ago

!

TLSハンドシェイクの流れは例えば、TLS 1.2でのフルハンドシェイクでは以下のような流れになります(引用元: )。大きく実施している内容を分類すると、接続方法のネゴシエーション、認証およびマスターシークレットの共有、完全性検証の3つに分けられます。

OpenSSLでAES128-SHA256と呼ばれるものは一般的な名称でのTLS_RSA_WITH_AES_128_CBC_SHA256に対応付けられます。この名称だとパット見でどの方法で実現するかわかりやすいでしょう。に記載されているような対応表も参考になるでしょう。

TLSでは古くはサーバー側でランダム生成されるものを使用していましたが、でグループパラメータとして定義されています。やでも同様に事前に一覧表から利用する方法を取ります。

の記事で取り上げられているRSA鍵交換やDH鍵交換によるTLSハンドシェイクの方法が参考になるでしょう。

例えば、Firefoxでは独自の証明書ストアをブラウザ内に持っています。一方で、Chromeでは現状利用しているOSによって提供されている証明書ストアを利用します。ただし、ChromeもFirefoxに似た形で、iOS版を除いて独自のルート証明書プログラムへの移行を予定しているようです(参照: )。 ChromeやFirefoxで利用している証明書ストアはそれぞれ以下の方法で確認できます。

SSL/TLSの見落とされがちな「認証」という基本機能
プロフェッショナルSSL/TLS - ラムダノート
RFC5246
【Net】SSL/TLS ハンドシェイクをわかりやすく図解
SSL/TLS session negotiation
Wireshark で TLS ハンドシェイクの流れを見てみる
tls_cipher_suite_config_20200707.pdf
RFC 7919
IPsec
SSH
【図解】素数とDiffie-Hellman鍵交換法 わかりやすい計算例とシーケンス,RFCや種類,アルゴリズムについて
TLSとDiffie-Hellmanグループパラメータ
Keyless SSLの仕組み | Forward Secrecy
Classic Load Balancer、Application Load Balancer、および Network Load Balancer は SSL/TLS セッションの再開をサポートしていますか?
細かすぎて伝わらないSSL/TLS
ロードバランサーが SSL/TLS 再ネゴシエーションをサポートしているかどうかを確認するにはどうすればよいですか?
Chrome Root Program
Chrome will soon have its own dedicated certificate root store
GoogleがChrome独自のルート証明書プログラムを計画中
RSA 秘密鍵/公開鍵ファイルのフォーマット
RSA暗号体験入門
DV、OV、EVの 各 SSL 証明書の 違いとは?
【図解】よく分かるデジタル証明書(SSL証明書)の仕組み 〜https通信フロー,発行手順,CSR,自己署名(オレオレ)証明書,ルート証明書,中間証明書の必要性や扱いについて〜
OpenSSLで秘密鍵と公開鍵を作る
ksnctf: HTTPS is secure, Writeup (TLS 通信解読)
RFC 6066
TLS拡張
SessionTicketTLS.md
SSL/TLS 20年の歩みと動向
【図解】TLS v1.3の仕組み Handshakeシーケンス,暗号スイートをパケットキャプチャで覗いてみる
wolfSSL – TLS1.3
TLS/SSL 暗号スイート
暗号セキュリティー・プロトコル: TLS
TLS 暗号設定 暗号スイートの設定
SSL/TLSについてまとめ2018
TLSとは何ですか?平易な英語で説明されているトランスポート層セキュリティ暗号化
HTTPSコネクションの最初の数ミリ秒
【図解】https(SSL/TLS)の仕組みとシーケンス,パケット構造 〜暗号化の範囲, Encrypted Alert, ヘッダやレイヤについて~
* SSL/TLSの基本
Amazon Trust Services
AWSの自社認証局への移行に備える方法