129
TLS, HTTP/2演習 IIJ 大津 繁樹 2015年12月12~13日 セキュリティ・ミニキャンプ in 北海道 2015

TLS, HTTP/2演習

Embed Size (px)

Citation preview

TLS, HTTP/2演習IIJ 大津 繁樹

2015年12月12~13日 セキュリティ・ミニキャンプ in 北海道 2015

自己紹介• 大津 繁樹

• 株式会社インターネットイニシアティブ(IIJ)

• Node.js Core Technical Committee メンバー

• IETF httpbis WGでHTTP/2相互接続試験など使用策定に参画

• ブログ: http://d.hatena.ne.jp/jovi0608/

本講義・演習の目的• 2日間の講義・演習を通じてTLS, HTTP/2の仕組みを学んで頂きます。

• 演習は、できるだけプログラミングを行う要素をなくし、Wireshark、Linux上のコマンドやファイル編集で収まるようにしています。

• TLS, HTTP/2ともに幅広く深い技術です。2日間で完全に理解するのは難しいでしょう。でも基本的な部分をおさえて将来の理解に役立ててください。

本講義・演習の内容(TLS)• 講義:TLS概要

• 講義:TLSを理解する準備(暗号技術など)

• 講義:事前学習解説(サーバ証明書取得までのPKIの仕組み)

• 講義:TLSの仕組みの理解 (Wiresharkの画面を見つつ)

• 演習:nginxでTLSサーバを構築

• 演習:SSLLabでA+を目指す

• 演習:RSA鍵を解読してTLSを破る(FREAK攻撃)

本講義・演習の内容(HTTP/2)

• 講義: HTTP/2が必要になった背景

• 講義: HTTP/2の仕組み解説

• 演習: nginxサーバをHTTP/2対応に

• 講義・演習: HTTP/2のTLS制限について

• 演習:HTTP/2によるHTTP Head of Blockingの解消

謝辞

• 本演習では、さくらインターネット株式会社様より参加者全員にクラウドサーバをご提供いただきました。厚く御礼申し上げます。

演習課題の手順書

https://gist.github.com/shigeki/fb40645dfe0ce343565e

できるだけコピペ作業は止めよう。

TLSの概要

インターネットの脅威 盗聴

パスワードやクレジットカード番号を盗み見

インターネットの脅威 改ざん

通信途中でデータを書き換え

インターネットの脅威 なりすまし

ユーザになりすまして通信を行う

インターネットの脅威 否認

そんな通信してませんとキャンセル

インターネットの脅威から守るセキュリティ対策

盗聴

改ざん 成りすまし

否認

暗号化

完全性チェック 認証

署名

各レイヤーにおけるセキュリティ通信

WPA

IPsec

TLS,DTLS,SSH

S/MIME, PGP

無線LAN

IP

TCP, UDP

データ

TLSの目的

• TLSプロトコルの最重要なゴールは、通信する2つのアプリケーションの間でプライバシーとデータの完全性を提供することです。

RFC5246: The Transport Layer Security (TLS) Protocol Version 1.2

1. Introduction The primary goal of the TLS protocol is to provide privacy and data integrity between two communicating applications.

アプリ アプリ

完全性

プライバシー

TLSの簡単な歴史

• SSL 1.0未発表

• 1994年 SSL 2.0

• 1995年 SSL 3.0

• 1996年 IETF TLS WGスタート

• 1999年 TLS 1.0

• 2006年 TLS 1.1

• 2008年 TLS 1.2

• 2013年 TLS 1.3検討スタート

SSLは、旧ネットスケープ社の私的プロトコル

TLSと名前を変えて標準化

SSL3.0と基本設計は大きく変えず、内部バージョンは TLS1.0 =SSL 3.1

現在の利用推奨

様々な拡張仕様の追加

TLSを理解する準備

TLSの要素技術

X509証明書

PKI

対称 暗号

暗号モード

公開鍵暗号

デジタル署名

メッセージ認証

乱数 生成

TLS鍵交換

一方向ハッシュ

TLSプロトコルは、これらの要素技術を組み合わせてアプリ間のセキュア通信を確立する手順を決める

TLS要素技術の依存性

X509証明書

PKI

対称 暗号

暗号モード

公開鍵暗号

デジタル署名 メッセージ認証

乱数 生成

鍵交換 一方向ハッシュ

本来はこの一つ一つをきちんと理解することが必要

TLS要素技術はどこで使われる?

ClientHello

ServerHelloDone

ChangeCipherSpec Finished

ChangeCipherSpec Finished

Application Data

Application Data

乱数生成

対称暗号・暗号モード・一方向ハッシュ・乱数生成

PKI・X509証明書・デジタル署名

乱数生成

ServerHello

Certificate

ClientKeyExchange

ServerKeyExchange(*)

乱数生成・鍵交換・ 公開鍵暗号・デジタル署名

メッセージ認証 対称暗号・暗号モード

メッセージ認証 対称暗号・暗号モード

乱数生成・鍵交換 デジタル署名

(* オプションで必須ではない)

TLS要素技術はどこで使われる?

乱数生成 Client/ServerHelloのNonce, 鍵ペアの生成 データ暗号化のIV

PKI CAによるサーバ証明書の署名と発行

X509証明書 Certificateによるサーバ・クライアントの認証・公開鍵の取得

電子署名 証明書の署名・鍵交換で交換する公開鍵の署名

鍵交換 Server/ClientKeyExchangeによる(EC)DH公開鍵の交換

公開鍵暗号 RSA鍵交換時にPreMasterSecretの暗号送信

一方向ハッシュ CBCなどの暗号モード利用時にアプリデータのMAC生成

メッセージ認証 MasterSecretの生成、Finishedによるハンドシェイクデータの完全性検証

対称暗号・暗号モード ChangeCipherSpec以降のハンドシェイクとアプリケーションデータの暗号化

(注:他にも細かいところで使われています。)

今回使うTLS要素技術

GCM AES

DHE ECDHE RSA

SHA256

HMAC

X509証明書

PKI

対称 暗号

暗号モード

公開鍵暗号

デジタル署名 メッセージ認証

乱数 生成

鍵交換 一方向ハッシュ

WoSign Free DV Cert

手入力??

セットメニュー化されたTLSの要素技術TLS CipherSuites

TLS_RSA_WITH_AES_128_GCM_SHA256 = {0x00,0x9C}

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256= {0xC0,0x2F};

対称 暗号

暗号モード

デジタル署名

メッセージ認証(ハッシュ)

鍵交換TLS _ _ _WITH_ _ 鍵長 _ _

鍵交換・デジタル署名にRSA

対称暗号に128bit鍵長のAES

暗号モードにGCM

ハッシュにSHA256

鍵交換にECDHE

デジタル署名にRSA

対称暗号に128bit鍵長のAES

暗号モードにGCM

ハッシュにSHA256

番号として 0xC0,0x2Fを割り当て

対称暗号暗号文平文

共通鍵 共通鍵

平文

ストリーム暗号:データを逐次暗号化(RC4, Chacha20)

ブロック暗号:データをブロック毎に暗号化(DES, AES)

幾つかの暗号では既に危殆化: DES: 2005年 NIST FPS46-3規格の廃止(2030年までは許容)

RC4: RFC7455: Prohibiting RC4 Cipher Suites

暗号化 復号化

対称暗号 AES• 1997年よりプロジェクト開始、2000年選定、2001年仕様発行

• ブロックサイズ 128bit

• 鍵長: 128bits, 192bits, 256bits の3種類

• Intel/AMDのCPUでハードウェア処理のサポート (AES-NI)

暗号モード• ブロック暗号は同じデータを同じ鍵で暗号化すると毎回同一の暗号文になる。

• ブロック長より長いデータを暗号化する場合に暗号モードを利用して繰り返しを避ける。

• CBC:「(平文 XOR ベクトル) を暗号化」を続ける

• CTR: 「カウンターを暗号化 XOR 平文」を続ける実際にTLSで利用するには改ざん検知のためのMAC(メッセージ認証)との組み合わせる(AEAD)。

これまでの主流

これからの主流に(GCM後述)

認証タグ

AEAD(認証付き暗号)暗号化しないけど改ざん• • • • • • • • • • •

防止が必要なデータ • • • • • • • • •

(ヘッダ等)• • • •

暗号化する平文

AEAD 暗号化

暗号文

共通鍵

初期ベクトル

AEAD(認証付き暗号)

平文

AEAD 復号化

改ざんチェック

暗号化しないけど改ざん防止が必要なデータ

(ヘッダ等)暗号文 認証タグ

共通鍵

初期ベクトル

GCM• GCM (Galois Counter Mode: ガロアカウンターモード)

• CTRとGHASHを組み合わせたAEAD

• ハードウェア処理で高速化が可能

• AESと組み合わせて AES-GCMとして利用

一方向ハッシュデータ 一方向

ハッシュ関数 ハッシュ値

ハッシュ値を比較することでデータの改ざんをチェックすることができる。

一方向ハッシュ

• md5 • SHA-1 • SHA-2(SHA-256など6種)

• SHA-3(SHA3-256など6種)

2018年ぐらいには現実的なコストで衝突データを探せる見込み(*2)

既に現実的な攻撃手法が存在

(*2) Cryptanalysis of SHA-1 https://www.schneier.com/blog/archives/2005/02/cryptanalysis_o.html

(*1) how to Break MD5 and Other Hash Functions http://merlot.usc.edu/csac-f06/papers/Wang05a.pdf

8/5にNISTより正式公開

メッセージ認証(HMAC)

• 事前に共通鍵を共有

• 共通鍵とデータを組み合わせたハッシュ値を作成

• データの完全性とハッシュ作成者を認証する

データ 一方向 ハッシュ関数 ハッシュ値

共通鍵

公開鍵暗号

512bit RSAの危険性 FREAK https://freakattack.com/

• 解を求めるのが困難な数学的問題を利用して暗号を生成。

• 公開鍵と秘密鍵のペアを生成。公開鍵はさらして大丈夫。

• 公開鍵で暗号化し秘密鍵で復号化。

• RSA 素因数分解

• ECC(楕円曲線暗号)楕円曲線上の離散対数問題

公開鍵 秘密鍵暗号化 復号化

鍵交換

• 2者間で安全に鍵を共有する仕組み

• 互いに公開鍵を交換しあい、共有鍵を生成する。

• 通信経路上で共有鍵のやり取りがない。

• DH (Diffie-Hellman) • ECDH(楕円曲線DH)脆弱性:DH Logjam https://weakdh.org/

公開鍵公開鍵 秘密鍵秘密鍵

デジタル署名

• データの完全性のチェックが可能となる。

• データの送信元の認証が可能となる。

• 公開鍵の信頼性の範囲で否認防止が可能となる。

• RSA • DSA,ECDSA

公開鍵秘密鍵 データ+デジタル署名

データハッシュ値を暗号化しデジタル署名を生成

デジタル署名を復号化。データハッシュ値と比較し検証する

事前課題の解説・復習演習で利用するTLSサーバ証明書(DV)を取得するまでの一連の手続きを行う

1.乱数データの生成

2.秘密鍵(RSA)の生成・確認・保護

3.CSRの生成・確認・提出

4.CAに申請・サーバ証明書発行

5.サーバ証明書の取得・確認https://gist.github.com/shigeki/102cd71b34627c5bf330

openssl genrsa, openssl rsa

openssl req

openssl x509

乱数生成利用用途: • 暗号鍵(対称暗号:秘密鍵、公開鍵暗号:鍵ペア)の生成

• 暗号モードの初期ベクトルやNonce(*)の生成

• MAC(メッセージ認証)用鍵

求められる機能:

無作為性: 偏りがなく等しい数である。

予測不可能性: 次の乱数が予想できない。

制限負可能性: 同じ乱数列を再現できない。

(* Nonce(number used once)一度だけ使い捨て用に使われる数字)

乱数生成• 実際の利用は、疑似乱数生成。seedが必要。

• OppenSSLのdefault built-inでは、seedはLinuxの/dev/urandom+pid+uid+timeを利用。WindowsではOSのAPIのCryptGenRandomだけでなく画面スクリーンのビットマップハッシュやヒープメモリも利用。

脆弱性:

• CVE-2008-0166: DebianやUbuntuのOpenSSLに予測可能な乱数を生成してしまう脆弱性

• SSH公開鍵にブルートフォース攻撃

Linuxのエントロピー• /dev/urandom

• ブロックしない

• 外部デバイス(キーボードやディスクなど)の割り込みをエントロピーソースにして溜める。加工したデータのハッシュ値を取る。

• エントロピーが十分溜まっているかが重要(特にインストール直後)

• /proc/sys/kernel/random/entropy_avail で値を確認できる。(Max 4k) 1k以下だったらエントロピーの追加を検討。

• findなどでDisk I/Oを人為的に増やしたり、rng-tools, Virtio_RNG, Haveged 等ツールを使う

演習1.1: エントロピーの確認• サーバに入り、プールしているエントロピーを確認します。

• cat /proc/sys/kernel/random/entropy_avail

• Disk I/Oを発生させます。

• find / > /dev/null

• エントロピーが変わったかどうか確認します。

• /dev/urandom からデータを読み込みます。その後エントロピープールが減ったことを確認します。

• head -10 /dev/urandom > /dev/null

事前学習の復習• 事前学習で作成したファイルの中身を見てみる

秘密鍵

$ openssl rsa -text -in private.key -noout

CSR

$ openssl req -text -in server.csr -noout

サーバ証明書

$ openssl x509 -text -in server.crt -noout

ASN.1, DER, PEM

PEM: DER形式をBase64に変換してBEGINヘッダ~ENDフッタをつけたテキスト

ASN.1: データ構造を表す書式

DER: ASN.1のデータ構造をタグ+長さ+データでエンコードしたバイナリ

秘密鍵(RSA)• 公開鍵暗号やデジタル署名で利用する鍵データ。実際は公開鍵と秘密鍵の鍵ペアを生成している。

• TLS通信のセキュリティを確保する要の一つ。厳重に管理。

• 秘密鍵が漏洩するなど危殆化するとTLS通信のセキュリティは確保できなくなる。

• PKCS#1(RFC3447)で規定

• 秘密鍵は暗号化してPKCS#5形式で保管する、パスワードで復号化。

RSA秘密鍵の中身Private-Key: (2048 bit)

modulus:

publicExponent:

privateExponent:

prime1:

prime2:

exponent1:

exponent2:

coefficient:

鍵長N=PxQ (素数P,Qの積)公開値

E 暗号化する指数 通常2^16+1 公開値D=1/E mod((P-1)(Q-1)) 復号化する指数 秘密値

素数P 秘密値

素数Q 秘密値

中国剰余定理で計算するための値 秘密値 D, P, Qから計算できる

CSR• Certificate Signing Request(証明書署名要求)

• PKCS#10(RFC2986)で規定

• サーバ証明書の識別子(サーバ名など)と公開鍵を含んだもの。CA(認証局)にCSRを申請してサーバ証明書を発行してもらう。

CSRの中身• Version: バージョン 0x0

• Subject: 証明書を発行してもらうサーバの識別名

Subject: C=JP, ST=Hokkaido, O=Security Camp, CN=server21.hokkaido.koulayer.com

• 公開鍵:アルゴリズムや公開鍵のデータ

• 署名:上記データの署名

CN: Common Name サーバ名が入る

PKI概要CA

(Certificate Authority) VA (Validation Authority)RA

(Registration Authority)

CRL/OCSP

CSR

鍵ペア

実在確認サーバ証明書

https://~

失効確認

論理的に複数の役割に分かれているが物理的に1つでもよい

Root証明書

OS・ブラウザベンダー

サーバ証明書(X509)• TLS通信の信頼性を担保する要

• ビルトインのルート証明書からサーバ証明書まで証明書チェーンの署名検証

• オンライン以外で信頼性を担保(PKI)

ビルトインの ルート証明書

サーバ証明書

中間証明書

ビルトインの ルート証明書

サーバ証明書

中間証明書

トラストアンカー

証明書の種類EV証明書(Extended Validation)

CA共通の厳格な組織の実在証明 (物理的実在, 書面やデータ, 口座取引による実在審査・署名提出・電話確認など)

アドレスバーが緑色

OV証明書(Organization Validation)

各CAポリシー(CPS)に従った組織の実在証明 (書面やデータ審査・電話確認など)

DV証明書(Domain Validation)

各CAポリシー(CPS)に従ったドメイン保持証明 (メールの到達性確認など)

今回利用

ネットワーク以外の実在証明

サーバ証明書の中身

バージョン、シリアル番号、発行者情報、有効期限、サーバ識別子、公開鍵情報、拡張情報(利用用途、別名や失効情報・ポリシー参照先)、デジタル署名

サーバ証明書の確認サーバ証明書と秘密鍵の対応が間違っていたらTLSサーバは起動しない。なのでサーバ証明書と秘密鍵の公開鍵が一致するか必ずチェックする。

サーバ証明書

秘密鍵

openssl x509 -pubkey -inserver.crt -noout > server_pubkey.pem

openssl rsa -pubout -in private.key -out private_pubkey.pem

公開鍵

公開鍵

TLSのセキュリティ

TLSの セキュリティ

乱数生成

PKI秘密鍵の管理

暗号技術

エントロピー不足

不正発行

漏洩

アルゴリズム・強度の危殆化

TLSは、この4つの外部要素の上でインターネットで安全な通信を提供する仕組みである。

TLSの仕組みまずは TLS_RSA_WITH_AES_128_GCM_SHA256 の時から

演習1.2https://html5.ohtsu.org/seccamp_hokkaido_2015/exam.pcapから pcap データをダウンロードして Wiresharkで開く

Wiresharkのデータを見比べながらTLSハンドシェイクを解説します。

TLSハンドシェイク(full handshake)

ClientHelloServerHello Certificate ServerHelloDone

ClientKeyExchange ChangeCipherSpec Finished

ChangeCipherSpec Finished

Application Data

Application Data

(赤文字はハンドシェイク)

ClientHelloとServerHelloのやり取りで双方が利用するTLSバージョンや暗号化方式などを合意する。

TLSハンドシェイク(resumption)

ClientHelloServerHello ChangeCipherSpec Finished

ChangeCipherSpec Finished

Application Data

Application Data

(赤文字はハンドシェイク)

SessionIDによるTLSセッションの再開。 鍵交換や証明書送付をスキップ。

今回は演習の対象外です

TLSハンドシェイクの意味ClientHello/ServerHello/ServerHelloDone

TLSのための情報交換 バージョン・乱数・暗号方式・拡張情報

Certificate 公開鍵情報の送付

エンドポイントの認証

ClientKeyExchange/ServerKeyExchange 共有鍵交換

ChangeCipherSpec 暗号開始の合図

Finished ハンドシェイクデータの改ざんチェック

TLS1.2の構造I P ヘ ッ ダ

T C P ヘッダ

TLS Record Layer (5バイト)

タイプ (4種類)

(1byte)

バージョン (2byte)

長さ (2byte)

Handshake (タイプ:0x16)

msgタイプ (10種類)

長さ

(3バイト長)ハンドシェイクデータ

Alert (タイプ:0x15)

レベル 理由

ChangeCipherSpec (タイプ:0x14)

タイプ

Application Data (タイプ:0x17)

暗号化されたデータ

msgタイプ ハンドシェイクデータの種類

0x00 HelloRequest0x01 ClientHello0x02 ServerHello0x0b Certificate0x0c ServerKeyExchange0x0d CertificateRequest0x0e ServerHelloDone0x0f CertificateVerify0x10 ClientKeyExchange0x14 Finished

TLS Record Layerデータに続いて、次の4種類のTLSデータのいずれかが続く。

TLS Handshakeは、この10種類に分かれる。

ClientHello項目 要素 サイズ 先頭の長さ情

報client_version uint8 major, uint8 minor 2 N/A

random uint32 gmt_unix_time, opaque random_bytes[28]

4 + 28 N/A

session_id opaque SessionID <0..32> 1バイト分cipher_suites uint8 CipherSuite[2] <2..2^16-2> 2バイト分

compression_methods

null(0) <1..2^8-1> 1バイト分

extensions extension_type(65535), extension_data<0..2^16-1>

<0..2^16-1> 2バイト分

0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1type デー

タ長データ type デー

タ長データ type デー

タ長データ

Extension長 Extensionsデータ例

ClientHello

Record Layer Handshake (ClientHello)

type protocol version

length (2byte

)

msg type

length (3byte)

client version

random session id

cipher suite

compression

Extension

major

minor

major minor

0x16 0x03 0x01 ?? ?? 0x01 ?? ?? ?? 0x03 0x03 32 byte 可変 可変 可変 可変

Version 0x03,0x00 = SSLv3 0x03,0x01= TLSv1.0 0x03,0x02=TLSv1.1 0x03,0x03=TLSv1.2

クライアントが利用できる最高のTLSバージョンを指定、サーバがどのバージョンを使うか選択する

ServerHello項目 要素 サイズ 先頭の長さ情報

server_version uint8 major, uint8 minor 2 N/A

random uint32 gmt_unix_time, opaque random_bytes[28]

4 + 28 N/A

session_id opaque SessionID <0..32> 1

cipher_suite uint8 CipherSuite[2] 2 N/A

compression_method null(0) 1 N/A

extensions extension_type, extension_data<0..2^16-1>

<0..2^16-1> 2バイト分

Record Layer(5bytes) Handshake (ServerHello)

type protocol version

length (2bytes)

msg type

length (3byte)

server version

random 32bytes

session id cipher suite

2bytes

compression

major

minor major minor

0x16 0x03 0x03 ? + 4 0x01 ? 0x03 0x03 ? 長さ1byte 0x00,0x9c 長さ2bytes

Certificate

項目 要素 サイズcertificate_list ASN.1Cert<2^24-1> <0..2^24-1>

全証明書長 証明書#1長 証明書データ#1 証明書#2長 証明書データ#2

複数の証明書データを送付

最初は必ずサーバ証明書 2つ目以降は中間証明書など

ServerHelloDone

handshake type

handshake長

0x0e 0x00 0x00 0x00

ServerHelloの終了の合図 ハンドシェイクヘッダのみ

ClientKeyExchange (RSA鍵交換の場合)

Record Layer(5bytes) Handshake(ClientKeyExchange)type protocol

versionlength

(2bytes)msg type

length (3byte)

Encrypted PreMasterSecret

major minor

0x16 0x03 0x03 ? + 4 0x10 ? 長さ2バイト ?

PreMasterSecretclient version random 46bytes

major minor

TLSの鍵生成の流れpre master secret

(任意のバイト数:鍵交換による) サーバ・クライアント間の鍵交換方式で生成し、秘密的に共有する

master secret (48 bytes)

PRF(pre_master_secret, "master secret", client_random+server_random)

keyblock (任意のバイト数:利用暗号方式による)

PRF(master_secret, "key expansion", server_random+client_random)

client_write_MAC server_write_MAC client_write_key server_write_key client_write_IV server_write_IV

PreMasterSecret/MasterSecret

• TLSで利用するIV(初期ベクトル)、共有鍵、MAC鍵のデータ元

• MasterSecretは48バイト長。PreMasterSecretの長さは鍵交換方式に依存する。

• MasterSecretは、PreMasterSecret、ClientRandom、ServerRandom、固定ラベルから生成する。

• Clinet/ServerRandomは全て丸見え。PreMasterSecretは、必ず死守して守らないといけない。これが漏えいするとTLSの安全性は全ておじゃん。

Freak/Logjam

ChangeCipherSpec

送信元が暗号開始を宣言。これを送信した後は暗号通信を行う。

Record Layer ChangeCipherSpec

ContentType

Version length (2byte)major minor

0x14 0x03 0x03 0x00 0x01 0x01

Finishedstruct { opaque verify_data[verify_data_length]; } Finished;

verify_data = PRF(master_secret, finished_label, Hash(handshake_messages))[0..11];

finished_label: クライアントは、"client finished"、サーバは"server finished"

12バイト固定

これまでのハンドシェイクデータ(ただし自分は除く)のハッシュを計算 TLS1.2では SHA256を使う

Finishedを受信すると、これまで送受信したハンドシェイクデータから計算した値と比較。

ハンドシェイクデータが改ざんされてないことを確認する。

Forward SecretTLS_DHE_RSA_WITH_AES_128_GCM_SHA256 とTLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 を使う

Forward Secret

• 前方秘匿性 (PFS: Perfect Forward Secrecyとも書かれることも) • セッション毎に一時的な公開鍵を使う。• 証明書の秘密鍵は、一時的な公開鍵への署名に利用する。 • ハンドシェイクを含む全暗号データを取得されているような状況でも、将来的な証明書の秘密鍵漏洩などのリスクに対応する。

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

Ephemeral:一時的な 鍵交換手法

接続ごとに公開鍵を変更する

DHE vs ECDHE• DH: Diffe-Hellman 離散対数問題を利用した鍵交換

((g^x) mod P)^y mod P = ((g^y) mod P)^x mod P = g^(xy) mod P

素数P, ジェネレータ g, 公開鍵(赤字、青字)などの情報を交換。ECDHEより計算量が多い。

• ECDHE: 楕円関数上での離散対数演算を利用した鍵交換

楕円関数のパラメータ・基点を名前で規定(secp256等)、公開鍵(楕円曲線上の点)を交換。DHより鍵長・計算量が少なくてすむ。

DHEのハンドシェイク

ClientHello ServerHello

Certificate ServerKeyExchange ServerHelloDone

ClientKeyExchange ChangeCipherSpec Finished ChangeCipherSpec

FinishedApplication Data

(赤文字が追加変更されるところ)

Clientの公開鍵を送付

TLS_DHE_RSA_WITH_AES_128_GCM_SHA256

P,G,サーバ公開鍵を署名して送付

公開鍵は毎回ランダムに生成されます

https://html5.ohtsu.org/seccamp_hokkaido_2015/dhe.pcap

ECDHEのハンドシェイク

ClientHello + elliptic_curves + ec_point_formats

ServerHello + ec_point_formats Certificate ServerKeyExchange ServerHelloDone

ClientKeyExchange ChangeCipherSpec Finished ChangeCipherSpec

FinishedApplication Data

(赤文字が追加変更されるところ)

ClientHello拡張を追加

ServerHello拡張を追加

楕円曲線名とServerの公開鍵を署名付きで送付

Clientの公開鍵を送付

楕円点の書式を合意使える楕円曲線名と楕円点書式を通知

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256

公開鍵は毎回ランダムに生成されます

https://html5.ohtsu.org/seccamp_hokkaido_2015/ ecdhe.pcap

TLSサーバを作る目指せ SSLlab A+判定

演習1.3:nginxの構築

https://gist.github.com/shigeki/b70bd5433e95722b5fa3

演習1.4:SSLLabのテストhttps://www.ssllabs.com/ssltest/index.html

default設定の結果

DHの鍵長(1024bits)が弱いです

Logjam攻撃• DHE鍵交換に対する攻撃(2015年5月に公開)

• あらかじめ素数Pがわかっていれば従来より離散対数問題を効率的に解けるようになった。

• DHでは標準素数が規定されており幾つかの実装ではそれを利用している。

• 512bit長の標準素数は数十秒で解ける。1024bit長も国家予算並みのお金をかければ解読できる。2048bit長以上の利用を推奨。

演習1.5:DHEの鍵長増加• nginxはデフォルトで1024bitの標準素数でDHEを利用している。

• 2048bit長以上にするにはユーザが独自にDHパラメータ(P,g)を生成し設定する。

$ openssl dhparam -out dhparam.pem 2048$ openssl dhparam -text -in dhparam.pem -noout

dhparamファイルを /usr/local/nginx/conf にコピーし、nginx.confにssl_dhparam dhparam.pem;を追加する。

DHEの鍵長変更後

演習1.6:目指せA+• いくつかスコアを増加させる方法はあるが、HSTSを設定してスコアを上げる。

• HSTS: HTTP Strict Transport Security

• Strict-Transport-Securityヘッダを利用すると指定した時間内はブラウザーが http:// が強制的に https:// へ接続にいく。nginx.conf に追加。

add_header Strict-Transport-Security "max-age=15768000; includeSubdomains";

HSTSの確認一度ブラウザでTLS接続してから chrome://net-internals/#hsts をあける。 Query domain にサーバ名を入力 mode が STRICT になっていれば設定OK

HSTS設定後

ブラウザーから一度httpsで接続してから、 http://~ で接続してみる。

演習2:TLSを破る FREAK攻撃

FREAK攻撃

FREAK攻撃

このRSA鍵を破るhttps://html5.ohtsu.org/seccamp_hokkaido_2015/nopfs.hokkaido.koulayer.com_sha256_en.zip

なんか変な素数の積だぞ

因数分解して秘密鍵をゲット

因数分解した答え(素数)を入力

公開鍵 PxQとE

暗号化されたPreMasterSecretを入手

バイナリーデータを直接扱えるならパケットバイトをエキ

スポートの方が楽

PreMasterSecretをゲット!$ cat > encrypted_premaster_secret.txt

0d9909953798f・・・・・721

$ xxd -p -r encrypted_premaster_secret.txt > encrypted_premaster_secret.der

$ openssl rsautl -decrypt -pkcs -inkey private.key -in encrypted_premaster_secret.der -hexdump

0000 - ・・・・・・ ..F.y.....)i,`.0

0010 - ・・・・・・ P......}.?C..c..

0020 - ・・・・・・ .x..Z.p..OK..ep.

テキスト形式でコピーした場合バイナリーに変換してください。

トータル何バイト長でしょうか 頭の2オクテットは何ですか?

3. 上級者向け課題https://html5.ohtsu.org/seccamp_hokkaido_2015/exam.pcap を解析して、PreMasterSecretを入手

MasterSecretを生成し、復号化用鍵を入手 暗号化されたアプリケーションデータを解読してください。 平文文字列が入手できればミッションクリア

http://www.slideshare.net/shigeki_ohtsu/security-camp2015-tlsのp76以降を参照

HTTP/2

HTTP/2演習の内容• HTTP/1.1からHTTP/2へ

• HTTP/2の仕組み概要• 演習:HTTP/2サーバを作る

• 演習:HTTP/2プロトコル解析

Ethernet

IP(v4/v6)

TCP

TLS

HTTP/2 Frame Layer

HTTP/1.1 Semantics

HTTP/1.1からHTTP/2へ

HTTPプロトコルの年表1990 1995 2000 2005 2010 2015

Webの 始まり

HTTP/0.9 HTTP/1.0 RFC1945

HTTP/1.1 RFC2068

HTTP/1.1 RFC2616

HTTP/1.1 RFC7230-5

HTTP/2 RFC7540

SPDY/2

SPDY/3

SPDY/3.1

httpbis WG

暗黒の時代

HTTP-NG 中止

HPACK RFC7541

HTTP/2サポート状況

http://caniuse.com/#feat=http2

HTTP転送サイズとリクエスト数の遷移(2012/7/1~2015/7/1)

http://httparchive.org/trends.php?s=All&minlabel=Jul+1+2012&maxlabel=Jul+1+2015#bytesTotal&reqTotal

3年で

転送サイズ: 96%増

リクエスト数:20%増

(単一Webサイトの統計平均)

回線帯域を増速していくと

HTTP経由のダウンロード

時間

[ms]

0

800

1600

2400

3200

回線帯域[MBps]

0 3 5 8 10

More Bandwidth does’nt matter よりデータ引用http://docs.google.com/a/chromium.org/viewer?

a=v&pid=sites&srcid=Y2hyb21pdW0ub3JnfGRldnxneDoxMzcyOWI1N2I4YzI3NzE2

ページの表示時間は、これ以上短縮できない。

Make the Web Faster: Google の試験

RTT(Round Trip Time)を小さくしていくと

HTTP経由のダウンロード時間

[ms]

0

1000

2000

3000

4000

RTT[ms]

0 50 100 150 200 250 300

ちゃんと下がる

More Bandwidth does’nt matter よりデータ引用http://docs.google.com/a/chromium.org/viewer?

a=v&pid=sites&srcid=Y2hyb21pdW0ub3JnfGRldnxneDoxMzcyOWI1N2I4YzI3NzE2

Webページの表示速度を速くするには、回線速度増強よりRTT(の影響)を小さくするかが重要。でも物理的な制限で難しい。

Make the Web Faster: Google の試験

SPDY(スピーディ)の登場(2009年)• RTTの影響をできるだけ避けるべくGoogleはSPDYを開発した。

• SPDYは、Webページの表示速度を速くするためのプロトコルとして当初社内プロジェクトから生まれた。

• 既に3年以上に渡りGoogleの全サービスで利用され、TwitterやFacebook、LINEなど大規模なシステムに導入されている。 ブラウザの拡張プラグイ

ン(SPDY Indicator)を使うとSPDYを使っているサイトがわかる

演習: SPDY indicatorのインストール• https://chrome.google.com/webstore/category/extensions から検索・インストール

• HTTP/2サイトにアクセスして確認

• chrome://net-internals/#http2 でHTTP/2の接続状況を確認

HTTP/1.1の問題点のおさらい1. HTTP Head of Line Blocking

2. ネットワーク通信の利用が非効率

3. 曖昧でテキスト処理が煩雑

1. HTTP Head of Line Blocking

クライアント サーバ

HTTP/1.1 1本のTCP接続

HTTP リクエスト

HTTPレスポンス待ち時間

HTTP リクエスト

HTTP/1.1ブラウザは最大同時4~6TCP接続に制限

最大同時並列6

HTTP/2100以上の同時リクエストが可能

全部同時

2. HTTP/1.1はネットワーク通信の利用が非効率

クライアント サーバ

TCP接続

TCP接続

TCP接続

TCP接続

TCP接続

TCP接続

それぞれのTCP接続が独立して輻輳制御を行う

HTTP/1.1は非効率なプロトコル

HTTP/1.1+SSLの輻輳ウィンドウサイズの変遷

輻輳ウィンドウサイズ

(mss

)

0

13

25

38

50

時間(sec)

10 18.75 27.5 36.25 45

SSL1 SSL2SSL3 SSL4SSL5 SSL6

6本のTCPがバラバラに輻輳制御。帯域を有効に使いきれてない

HTTP/2(SPDY)は効率的なプロトコル

SPDY利用時の輻輳ウィンドウサイズの変遷

輻輳ウィンドウサイズ

(mss

)

0

13

25

38

50

時間(sec)

60 68.75 77.5 86.25 95

SPDY

1本のTCPで最高速まで利用。帯域を最大限に効率的に使っている。

3. HTTP/1.1は処理が煩雑なテキストプロトコル

HTTP/1.1 200 OK Content-Type: image/jpeg Transfer-Encoding: chunked Trailer: Foo

123 {binary data} 0 Foo: bar

Status-Lineは一行目 空白は1つ

ヘッダ名は大文字・小文字区別せず

ヘッダ領域の区切りはCRLF一つ

:の後に空白を許可

CRLFで改行、複数行対応は廃止

レスポンスデータがchunkedであり、サイズはまだ不定

一番最後にFooヘッダが付与されることを宣言

続くデータが123バイトであることを宣言 データ終了の合図

Trailヘッダchunk終了合図のCRLF

HTTP/2はきっちりしたバイナリープロトコル

00 00 00 01

01 04

00 00 1a

88 5c 82 08・・・・・・

73 ff

00 00 00 01

00 00

00 00 7b

{binary data}

:status = 200 content-length = 123 content-type = image/jpeg trailer = Foo

HEADERS

DATA

フレーム長:28バイト

フレーム長:123バイト

フレームタイプ:HEADERS, END_HEADERSフラグ

ストリームID: 1

ストリームID: 1

フレームタイプ:DATA, フラグなし

(* 記載スペースの都合上Trailer HEADERSは省いています)

データの 位置・サイズ・型

が明確

HTTP/2の仕組み概要

HTTP/2の技術的な特徴• HTTP/1.1のセマンティックスを変えない。

•サーバへのTCP接続数を1つに限定

• TLSと連携してプロトコルを自動選択

•バイナリープロトコル(テキストデータの曖昧さを排除)

•全2重多重化通信

•フロー制御、優先度指定

•サーバプッシュ機能

HTTP/2の技術的な特徴• SPDYのプロトコルアーキテクチャはそのまま利用

• SPDYの無駄なヘッダフィールドやフレームタイプを統廃合し、簡略化

• SPDYの実運用で明らかとなったフロー制御・優先度制御といった課題へ対応する

• TLS利用を前提とするSPDYに対し、平文接続も利用可能にする 。

•ヘッダ圧縮脆弱性(CRIME)対策として新しくHTTPに特化したヘッダ送受信仕様(HPACK)を策定する

HTTP/2初期ニゴシエーション 3種類で2段階(その1)

あらかじめサーバがHTTP/2対応とわかっている場合、直接第2段階の接続方法を行う。 (DNSレコードや HTTPヘッダによるリダイレクト)

HTTP/1.1の接続後 Upgradeヘッダを使って、HTTP/2 に接続をアップグレードする。

TLS接続時にALPN拡張フィールドを利用してHTTP/2に接続を行う。

(1) TLS + ALPN

(2) HTTP Upgrade

(3) 事前知識に

よるDirect接続

詳細後述

WebSocketと一緒

詳細仕様 検討中

暗号化通信

平文通信

ALPN (Application Layer Protocol Negotiation)

クライアント サーバー

1. ClientHello + ALPN拡張

2. ServerHello + ALPN拡張

サーバ側でプロトコルを決定し、通知する h2

3. TLS 証明書・暗号化情報交換

プロトコルリストをサーバに送信 h2,spdy/3.1,http/1.1

HTTP/2で通信

TLSハンドシェイクhttps://html5.ohtsu.org/seccamp_hokkaido_2015/ http2.pcap

HTTP/2初期ニゴシエーション 3種類で2段階(その2)

505249202a20485454502f322e300d0a0d0a534d0d0a0d0a

PRI * HTTP/2.0\r\n \r\n SM\r\n \r\n

クライアントから謎の24byteのマジックコードをサーバに送り、初期情報(SETTINGSフレームを交換する)

SETTINGS (初期ウィンドウサイズ、ストリームの最大同時オープン数等の設定情報を含む)

間違えてHTTP/1.1 サーバに接続した場合は即切断される

HTTP/2のデータフレーム(binary)

ペイロード長(24bit)タイプ(8bit) フラグ(8bit)X ストリームID(31bit)

ペイロードデータ(ペイロード長bit)

タイプ フレーム種類 タイプ フレーム種類0x00 DATA 0x05 PUSH_PROMISE0x01 HEADERS 0x06 PING0x02 PRIORITY 0x07 GOAWAY0x03 RST_STREAM 0x08 WINDOW_UPDATE0x04 SETTINGS 0x09 CONTINUATION

デフォルトは14bit(16K),

24bit(16M)まで拡張可フレームヘッダ 9バイト

フロー制御

クライアント

サーバA

サーバB

Reverse Proxy

高速

低速

AとBからのデータを バランスよく返す

WINDOW_UPDATE

WINDOW_UPDATE

サーバは、Window Size が0になったらデータ送信を停止

Window Size を増加させる

サーバA,B へのウィンドウサイズ更新を調整

TCPコネクション、ストリーム毎にフロー制御が可能

プライオリティ

クライアントReverse Proxy

コンテンツ HTML

画像

CSS, js

HTML

CSS JS

画像1 画像2 画像3 画像4

依存性と重みを指定

weight:16 weight:16

プライオリティのユースケース

• ファイルタイプ(HTML/CSS/JS/画像)に応じた返答順序の指定

• タブ切り替えによる重みの上げ下げ • 分割されたビデオデータなど順番が明示的

に決められている場合

サーバプッシュ機能

コンテンツリクエスト

クライアント サーバ

画像のHTTPリクエストを予約

コンテンツのレスポンス

画像データキャッシュ

サーバはコンテンツの中身を判断し,あらかじめコンテンツに含まれている画像のリクエストを予約する.

予約された画像リクエストはクライアントからサーバに送らずに,クライアントはサーバ側からの画像データの送付を待つ

サーバから送信された画像データは,クライアントのキャッシュに保存

HTTP/2がTLSに求める制限

• TLSのバージョンは1.2以上

• プロトコル選択にALPN(RFC7301)を使う

• サーバ認証を共有できる接続は接続共有が可能

• クライアント認証の利用は初期接続時のみ可能

• SNI(Server Name Indicator)拡張必須

• TLS Compression禁止

• Renegotiation禁止

• 鍵長 (DHE 2048bit以上、ECDHE 224bit以上)サポート必須 • PFS必須 (DHE, ECDHE)

• AEAD(GCM/CCM)以外の暗号方式をブラックリストとして利用禁止

HTTP/2 仕様でTLSの利用条件を制限すべきかどうか大きな議論になったが、 新しいプロトコルはよりセキュアな状態で提供すべきとの意見で合意

演習4.1: nginx を http2対応にする

server { listen 443 ssl http2; ・・・・

}

わずかこれだけ

しかしエラーでつながりません

セキュリティが十分でない

比べて見よう Cipher Listnginxのデフォルト設定はサーバ側のリストを優先に選択

Chromeの Cipher List

nginxの Cipher List

サーバはECDHE_RSA_WITH_AES_256_CBC_SHAを選択 →AEAD(GCM)じゃないのでHTTP/2の条件外

RSA認証でサーバリストの上から合うのを探していくと

もう一度HTTP/2のTLS条件を思い出せ!

• 鍵長 (DHE 2048bit以上、ECDHE 224bit以上)サポート必須 • PFS必須 (DHE, ECDHE)

• AEAD(GCM/CCM)以外の暗号方式をブラックリストとして利用禁止

(注: openssl-1.0.2以上限定です)

これならいけるはず

演習4.2:nginxでHTTP/2サーバを作る

HTTP/2のTLS接続 条件クリア

HTTP/2

WiresharkでTLSハンドシェイクを取得 Client/ServerHello のALPN Extension を確認する

演習5: HTTP HoLを再現させる

$ git clone https://github.com/shigeki/seccamp-imageserver/ $ cd seccamp-imageserver/lib ~/seccamp-imageserver/lib$ node ./server.js Litening on port 8080

location / {

root /home/seccamp/seccamp-imageserver/html;

index index.html index.htm;

}

location /images {

proxy_pass http://localhost:8080;

}

nginx.confの変更

imageサーバを立ち上げ

すぐ返す

3秒後返す

HTTP/1.1の表示

Head of Line Blocking

泣き顔画像がブロック

HTTP/2の表示

泣き顔画像がブロックしない

face-xx.pngの数字が3で割り切れると泣き顔表示 自分でHTMLを変更して画像数を変えて比較してみよう