IT系/インフラ系/ネットワーク/SSL

Last-modified: 2021-08-10 (火) 22:41:31

目次


概要

SSL/TLS、HTTPS通信について、覚えたこととかをまとめる。というか、リンク集。

SSLとは

  • SSL(Secure Sockets Layer)は米Netscape社が開発したインターネットなどのコンピュータネットワークにおいてセキュリティを要求される通信を行うためのプロトコル。
    主な機能として、通信相手の認証、通信内容の暗号化、改竄の検出を提供する。
    現在では、IETFによって策定されたTLS(Transport Layer Security)プロトコルに取って代わられている。
    だが、SSLという名称が広く通用しているため、「TLSのことも含めてSSLと呼ぶ」または「SSL/TLS」「TLS/SSL」のような併記で使われるようになっている。
  • SSLはバージョン3.0まで開発・使用されていたが、2014年に重大な脆弱性である「POODLE」が発見され、使用されなくなっている。
    TLSについても、TLS1.1以前のバージョンは脆弱性が発見されており、TLS1.2や、2018年リリースのTLS1.3を使用するようになってきている。
  • TLSはHTTPなどのアプリケーション層のプロトコルと組み合わせることで、HTTPSなどセキュアな通信プロトコルを実現している。

HTTPSとは

HTTPS(Hypertext Transfer Protocol Secure)は、HTTPによる通信をより安全に(セキュアに)行うためのプロトコルおよびURIスキームである。
厳密に言えば、HTTPS自体はプロトコルではなく、SSL/TLSプロトコルによって提供されるセキュアな接続の上でHTTP通信を行うことをHTTPSと呼んでいる。

ブラウザのURL欄を確認すると、「http」から始まっている場合と、「https」から始まっている場合がある。
「http」から始まっている場合は、通常のhttp通信であり、データの送信は平文で行われている。
一方、「https」から始まっている場合は、SSL/TLSプロトコルを利用した、暗号化通信が行われている。
SSL暗号化通信では、データは暗号化されてやりとりされるため、復号ができない第3者からは、内容を読みとくことができない。
個人情報や認証情報、機密情報等のやりとりが必要なサイトやページで「https」を導入することで、盗聴・なりすまし・中間者攻撃・情報漏洩等の対策として活用されている。
SSL/TSLを用いたhttps暗号化通信は、「共通鍵暗号方式」と「公開鍵暗号方式」の両方を用いた「ハイブリッド方式」とも呼ばれる仕組みで行われる(という通説は実態とは違う模様*1)。

共通鍵暗号方式

  • 暗号化する際の鍵と復号する際の鍵が両方とも同じもの(共通鍵)を利用する暗号化方式
  • 暗号化・復号ともに利用するため、共通鍵は公開されず、データの送信側と受信側のみで共有される
  • 暗号化・復号ともに同じ鍵を利用するので、「公開鍵暗号方式」と比べて処理速度が早い
  • 通信相手毎に共通鍵が必要となるため、その作成や管理が煩雑となることと、共通鍵の安全な配布が課題

公開鍵暗号方式

  • 暗号化・復号する際の鍵に、公開鍵と秘密鍵の異なる鍵を利用する暗号化方式
  • データの送信側は、受信側の公開鍵を利用して暗号化する
  • 暗号化されたデータは、受信側の秘密鍵でしか復号できないため、安全にデータの送受信が可能
  • 公開鍵は誰でも取得が可能だが、秘密鍵とのキーペアでしか利用ができないので、鍵の管理は「共通鍵暗号化方式」と比べて容易
  • 公開鍵と秘密鍵で暗号化と復号を行うと、非常に多くの時間を要してしまうため、処理速度においては「共通鍵暗号方式」に劣る

共通鍵/公開鍵ハイブリッド方式

  • 「共通鍵暗号方式」の処理速度と、「公開鍵暗号方式」の鍵管理の容易さを兼ね備えた「ハイブリッド方式」は以下の流れで行われる
    (1) SSLサーバ証明書を、サーバからクライアントに送信
    (2) クライアントは受け取ったサーバ証明書をブラウザのルート証明書で検証
    (3) クライアントは共通鍵を生成し、受け取ったサーバ証明書内の公開鍵で暗号化
    (4) 暗号化した共通鍵をクライアントからサーバに送信
    (5) サーバは受け取った暗号化済み共通鍵を、秘密鍵で復号し、以降の通信を共通鍵で暗号化・復号して行う
  • このように、共通鍵の受渡しを「公開鍵暗号方式」で行い、受渡し完了後の通信を「共通鍵暗号方式」で行う方法がhttps通信で行われている

  • という通説は実態とは異なる模様。かつてはこの説明でも簡易的な説明としては間違いではなかったが、現在では証明書に含まれる公開鍵で共通鍵を暗号化する方法は廃止されている。
  • 現在では、別の使い捨ての公開鍵・秘密鍵を使用して「鍵交換」により共通鍵のもととなる秘密情報をサーバ・クライアントで共有し、共通鍵を生成・共有するとのこと。
  • 上記の指摘は、SSL/TLSの基本 - Qiitaに書かれており、この記事によれば、SSL/TLSは鍵交換・認証・暗号化・メッセージ認証コードの4要素のハイブリッド暗号であるとのこと。
  • 鍵交換・認証は、公開鍵暗号を利用するものであり、暗号化・メッセージ認証コードは共通鍵を使った技術であるから、ざっくりとなら、共通鍵/公開鍵ハイブリッド方式と言えなくもない。
  • 公開鍵暗号を利用して共通鍵をサーバ・クライアントで共有し、暗号化通信を確立する、という主旨自体は間違いではない。

SSL/TLSプロトコル概要

TLSの主なプロトコルとして以下のものがある。

  • 暗号通信に必要な鍵 (master secret) を鍵共有してセッションを確立するTLSハンドシェイクプロトコル
  • master secretを用いて暗号通信することで確立されたセッションにおけるコネクションをセキュアにするTLSレコードプロトコル
    その他、以下のプロトコルも存在する。
  • 用いている暗号方式やハッシュ関数等のアルゴリズムを変更する Change Cipher Spec プロトコル
  • 通信相手からの通信終了要求や何らかのエラーを通知する アラートプロトコル

TLSハンドシェイクプロトコル

TLSハンドシェイクプロトコルは4つのフェーズに大別できる。

  • 第一フェーズ
    サーバ・クライアント間で通信に必要な情報を共有する。
  • 第二フェーズ
    サーバからクライアントに対して鍵共有に必要な情報を送る。
  • 第三フェーズ
    クライアントからサーバに対して鍵共有に必要な情報を送る。
  • 第四フェーズ
    必要なら用いている暗号方式やハッシュ関数等のアルゴリズムを変更を通知し、終了メッセージを送る。
フェーズ通信方向説明
第一フェーズClientHelloCL → SVClientHelloで送信する情報は、TLSのバージョン、乱数、セッションID、通信に用いる暗号方式やハッシュアルゴリズムのリスト (cipher_suites)、
通信内容の圧縮方法、および拡張領域の6つからなる。
乱数は鍵共有におけるリプレイ攻撃を防ぐためのものである。
ServerHelloCL ← SVServerHelloもClientHelloと同様の6つからなっている(名称は一部異なる)。
ServerHelloの主な目的は、ClientHelloで提示された選択肢の中でサーバにとって好ましいものを選択する事で、
例えばClientHelloで提示されたcipher_suitesの中から、サーバが通信に使いたいcipher_suiteを一組選ぶ。
乱数はClientHelloとは独立して選ぶ。
これもリプレイ攻撃を回避するためである。セッションIDは特に問題がなければClientHelloと同一のものを返す。
第二フェーズCertificateCL ← SVCertificateは鍵共有で用いる公開鍵とその証明書で、別途取り決めがない限りX.509v3のフォーマットに従う。
ServerKeyExchangeCL ← SV鍵共有プロトコルに依存して送るデータが異なる。
DH_anonであれば、gx mod pという形のデータを送る。ここでxはサーバの秘密の乱数である。
鍵共有プロトコルがDHE_DSS、DHE_RSA、DH_anonでは何らかのserver_key_exchangeを送るが、RSA、DH_DSS、DH_RSAでは何も送らない。
CertificateRequestCL ← SVクライアントの公開鍵とその証明書を送ることを要求するためのもので、サーバが許容できる証明書の種別、ハッシュと署名方式、および認証局のリストからなっている。
ServerHelloDoneCL ← SV最後にサーバ側からのメッセージ送信が終わった事を示す。
第三フェーズCertificateCL → SVCertificateは鍵共有で用いるクライアントの公開鍵とその証明書である。
証明書はサーバから送られてきたCertificateRequestの条件を満たさねばならない。
ClientKeyExchangeCL → SV鍵共有プロトコルに依存して送るデータが異なる。
DH_anonであれば、gy mod pという形のデータを送る。ここでyはクライアントの秘密の乱数である。
ここまでのプロトコルにより、サーバとクライアントの間でpremaster secretが共有された事になる。
DH_anonであればpremaster secretはgxy mod pである。
premaster secretを鍵にした擬似ランダム関数にServerHelloとClientHelloの乱数などを並べたものを入力した結果得られたものがmaster secretである。
CertificateVerifyCL → SVクライアントが署名能力を持っていることを証明するためにこれまでTLSハンドシェイクプロトコルで送受信された全メッセージに対し、
共有されたmaster secret で署名したものである。
第四フェーズChange Cipher SpecCL → SV必要なら送る。用いている暗号方式やハッシュ関数等のアルゴリズムを変更する。
FinishedCL → SV終了を意味する。
Change Cipher SpecCL ← SV必要なら送る。用いている暗号方式やハッシュ関数等のアルゴリズムを変更する。
FinishedCL ← SV終了を意味する。

TLSレコードプロトコル

TLSレコードプロトコルはアプリケーション層から受け取った通信内容を214バイト以下のブロックに分解 (fragmentation) し、各ブロックを圧縮 (compress) し、圧縮されたブロックを認証暗号で暗号化するレコード Payload 防護を施した上で、通信内容を通信相手に送信する。
認証暗号で用いる共通鍵はTLSハンドシェイクプロトコルで共有されたmaster secretを用いる。

サーバ証明書

クライアント証明書

リンク集

重複を恐れないリンク集。

SSL/TLS・HTTPS

SSL証明書

JavaでのSSL通信

書籍



*1 SSL/TLSの基本 - QiitaでSSL/TLSは鍵交換・認証・暗号化・メッセージ認証コードの4要素のハイブリッド暗号であり、公開鍵暗号と共通鍵暗号のハイブリッドではない旨述べられている