目次
概要
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つのフェーズに大別できる。
- 第一フェーズ
サーバ・クライアント間で通信に必要な情報を共有する。 - 第二フェーズ
サーバからクライアントに対して鍵共有に必要な情報を送る。 - 第三フェーズ
クライアントからサーバに対して鍵共有に必要な情報を送る。 - 第四フェーズ
必要なら用いている暗号方式やハッシュ関数等のアルゴリズムを変更を通知し、終了メッセージを送る。
フェーズ | 通信 | 方向 | 説明 |
第一フェーズ | ClientHello | CL → SV | ClientHelloで送信する情報は、TLSのバージョン、乱数、セッションID、通信に用いる暗号方式やハッシュアルゴリズムのリスト (cipher_suites)、 通信内容の圧縮方法、および拡張領域の6つからなる。 乱数は鍵共有におけるリプレイ攻撃を防ぐためのものである。 |
ServerHello | CL ← SV | ServerHelloもClientHelloと同様の6つからなっている(名称は一部異なる)。 ServerHelloの主な目的は、ClientHelloで提示された選択肢の中でサーバにとって好ましいものを選択する事で、 例えばClientHelloで提示されたcipher_suitesの中から、サーバが通信に使いたいcipher_suiteを一組選ぶ。 乱数はClientHelloとは独立して選ぶ。 これもリプレイ攻撃を回避するためである。セッションIDは特に問題がなければClientHelloと同一のものを返す。 | |
第二フェーズ | Certificate | CL ← SV | Certificateは鍵共有で用いる公開鍵とその証明書で、別途取り決めがない限りX.509v3のフォーマットに従う。 |
ServerKeyExchange | CL ← SV | 鍵共有プロトコルに依存して送るデータが異なる。 DH_anonであれば、gx mod pという形のデータを送る。ここでxはサーバの秘密の乱数である。 鍵共有プロトコルがDHE_DSS、DHE_RSA、DH_anonでは何らかのserver_key_exchangeを送るが、RSA、DH_DSS、DH_RSAでは何も送らない。 | |
CertificateRequest | CL ← SV | クライアントの公開鍵とその証明書を送ることを要求するためのもので、サーバが許容できる証明書の種別、ハッシュと署名方式、および認証局のリストからなっている。 | |
ServerHelloDone | CL ← SV | 最後にサーバ側からのメッセージ送信が終わった事を示す。 | |
第三フェーズ | Certificate | CL → SV | Certificateは鍵共有で用いるクライアントの公開鍵とその証明書である。 証明書はサーバから送られてきたCertificateRequestの条件を満たさねばならない。 |
ClientKeyExchange | CL → SV | 鍵共有プロトコルに依存して送るデータが異なる。 DH_anonであれば、gy mod pという形のデータを送る。ここでyはクライアントの秘密の乱数である。 ここまでのプロトコルにより、サーバとクライアントの間でpremaster secretが共有された事になる。 DH_anonであればpremaster secretはgxy mod pである。 premaster secretを鍵にした擬似ランダム関数にServerHelloとClientHelloの乱数などを並べたものを入力した結果得られたものがmaster secretである。 | |
CertificateVerify | CL → SV | クライアントが署名能力を持っていることを証明するためにこれまでTLSハンドシェイクプロトコルで送受信された全メッセージに対し、 共有されたmaster secret で署名したものである。 | |
第四フェーズ | Change Cipher Spec | CL → SV | 必要なら送る。用いている暗号方式やハッシュ関数等のアルゴリズムを変更する。 |
Finished | CL → SV | 終了を意味する。 | |
Change Cipher Spec | CL ← SV | 必要なら送る。用いている暗号方式やハッシュ関数等のアルゴリズムを変更する。 | |
Finished | CL ← SV | 終了を意味する。 |
TLSレコードプロトコル
TLSレコードプロトコルはアプリケーション層から受け取った通信内容を214バイト以下のブロックに分解 (fragmentation) し、各ブロックを圧縮 (compress) し、圧縮されたブロックを認証暗号で暗号化するレコード Payload 防護を施した上で、通信内容を通信相手に送信する。
認証暗号で用いる共通鍵はTLSハンドシェイクプロトコルで共有されたmaster secretを用いる。
サーバ証明書
クライアント証明書
リンク集
重複を恐れないリンク集。
SSL/TLS・HTTPS
- HTTPS - Wikipedia
- Transport Layer Security - Wikipedia
- HTTPS(HTTP over SSL/TLS)とは - IT用語辞典 e-Words
- SSL/TLSってなんだろう?|SSL/TLS-総合解説サイト
- SSLとTLSの違いについて|GMOグローバルサイン【公式】
- HTTPS と SSL と TLS:その違いを5分でわかりやすく解説! | キュービストブログ
- TLS 1.3を採用しSSL 3.0を禁止に IPAが「TLS暗号設定ガイドライン」の第3版を公開:「順守項目だが設定が難しいサーバ」のために「推奨項目」を追加 - @IT
- httpsとは?httpとの違いとSSL暗号化通信の仕組み
- httpsにすると何がいいの?SSL通信とは | セキュリティ対策 | CyberSecurityTIMES
- 第1回 HTTPS(HTTP over SSL/TLS)とは:超入門HTTPS - @IT
- TLS暗号設定ガイドライン~安全なウェブサイトのために(暗号設定対策編)~:IPA 独立行政法人 情報処理推進機構
- 【図解】https(SSL/TLS)の仕組みとシーケンス,パケット構造 ~暗号化の範囲, Encrypted Alert, ヘッダやレイヤについて~ | SEの道標
- 【図解】よく分かるデジタル証明書(SSL証明書)の仕組み ~https通信フロー,発行手順,CSR,自己署名(オレオレ)証明書,ルート証明書,中間証明書の必要性や扱いについて~ | SEの道標
- SSL/TLSとは
- SSL/TLSネゴシエーション
- SSL を理解するための基礎ネゴシエーション
- 第3回 SSL証明書ビギナー歓迎! httpsから始まるURLの役割と仕組みを0から学ぼう:Webデザイナーなら知っておくべき サーバ知識相談室|gihyo.jp … 技術評論社
- SSL化の基礎からWordPressサイトに適用するまで徹底解説 | CodeCampus
- SSL証明書の取得方法 | HTTPからHTTPSへ移行 - Qiita
- 「SSL」とか「HTTPS」、「常時SSL」ってそもそも何??その種類や導入タイミングは?
- SSL/TLS 20年の歩みと動向~ - JPNIC
- まだhttpで消耗してるの?https(常時SSL化)のメリット・デメリットまとめ | たいしょんブログ
- SSL/TLSの仕組みを知っていますか?
- 共通鍵暗号と公開鍵暗号とは
- ここが違うよSSHとSSL! - Qiita
- SSL/TLSの見落とされがちな「認証」という基本機能 - Qiita
- 2つの公開鍵暗号(公開鍵暗号の基礎知識) - Qiita
- SSL/TLSの基本 - Qiita
- 電子署名の基礎知識 - Qiita
- そろそろ暗号方式やらデジタル署名やらを理解する - Qiita
- RSA署名で使われる「公開鍵暗号は秘密鍵で暗号化し公開鍵で復号化できる」表現についての議論 | エンジニアの何でもメモ帳
- SSL/TLS(SSL3.0~TLS1.2)のハンドシェイクを復習する - Qiita
- X.509証明書の検証手順とありがちな脆弱性 - Qiita
- Forward Secrecy 入門
- SSLサーバ証明書とは:ハンドシェイク |DigiCert(デジサート)正規代理店
- HTTPS入門:SSL/TLS サーバ証明書 |DigiCert(デジサート)正規代理店
- 理解してるつもりの SSL/TLS でも、もっと理解したら面白かった話 · けんごのお屋敷
- ざっくりSSL/TLS | せろとにんぱわー.
- SSLのはなし|Wireless・のおと|サイレックス・テクノロジー株式会社
- あと数年で量子コンピューターにSSL通信が解読される?SSL/TLSの未来を担うPQCとは? | さくらのSSL
- 組み込み技術者向けTLS1.3基礎解説(前編):まずはSSL/TLSについて知ろう:IoTセキュリティ基礎解説(1/3 ページ) - MONOist
- 連載「入門 HTTP」(2) TLSとHTTP - TLSの概要 | Honai's Blog
- Forward secrecy - Wikipedia
- ディフィー・ヘルマン鍵共有 - Wikipedia
- 【Net】暗号スイート (cipher suite) とは | ねこまるの AD フリーク
- HTTPS通信の暗号化方式 | DevelopersIO
SSL証明書
- SSL/TLSサーバ証明書とは | DigiCert
- SSLの種類と利用用途|GMOグローバルサイン【公式】
- いまさら聞けない、SSLサーバ証明書とルート証明書の関係
- クライアント証明書とサーバ証明書の違いとは? | DigiCert
- サーバー証明書/中間CA証明書/ルート証明書の違いとは? | さくらのSSL
- オレオレ証明書を使いたがる人を例を用いて説得する - Qiita
JavaでのSSL通信
- OkHttpで認証・SSL通信・クッキー管理するTips - Qiita
- 自己署名証明書のサーバにJavaでHTTPS接続する - Qiita
- 「Java」 HttpsURLConnection で HTTPS 通信する ( サーバ認証あり ) - プログラム日記
- Javaでhttps通信時の証明書検証について - 闘うITエンジニアの覚え書き
- JavaでHTTPS通信時のSSL証明書の失効チェックを有効にする - kdnakt blog
- JavaによるSSL接続検証 | SIOS Tech. Lab
- 改造する人のためのJSSE - Qiita
書籍
- 食べる!SSL! ―HTTPS環境構築から始めるSSL入門
- SSL/TLS徹底入門: わかりやすい図解解説
- SSL/TLSを理解する ~共通鍵暗号・公開鍵暗号・ハッシュ関数・電子署名・証明書~
- SSLをはじめよう ~「なんとなく」から「ちゃんとわかる!」へ~ はじめようシリーズ
- プロフェッショナルSSL/TLS
- 暗号技術入門 第3版 秘密の国のアリス
- 暗号技術のすべて
- セキュリティプロトコル 最強の指南書
- パケットキャプチャの教科書