TLS, HTTP/2演習
- 2. 自己紹介
• 大津 繁樹
• 株式会社インターネットイニシアティブ(IIJ)
• Node.js Core Technical Committee メンバー
• IETF httpbis WGでHTTP/2相互接続試験など使用
策定に参画
• ブログ: http://d.hatena.ne.jp/jovi0608/
- 16. 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
現在の利用推奨
様々な拡張仕様
の追加
- 21. TLS要素技術はどこで使われる?
乱数生成 Client/ServerHelloのNonce, ペアの生成 データ暗号化のIV
PKI CAによるサーバ証明書の署名と発行
X509証明書 Certificateによるサーバ・クライアントの認証・公開 の取得
電子署名 証明書の署名・ 交換で交換する公開 の署名
交換 Server/ClientKeyExchangeによる(EC)DH公開 の交換
公開 暗号 RSA 交換時にPreMasterSecretの暗号送信
一方向ハッシュ CBCなどの暗号モード利用時にアプリデータのMAC生成
メッセージ認証
MasterSecretの生成、Finishedによるハンドシェイクデータの完全
性検証
対称暗号・暗号モード ChangeCipherSpec以降のハンドシェイクとアプリケーションデータの暗号化
(注:他にも細かいところで使われています。)
- 26. 暗号モード
• ブロック暗号は同じデータを同じ で暗号化すると毎回同一の暗
号文になる。
• ブロック長より長いデータを暗号化する場合に暗号モードを利用
して繰り返しを避ける。
• CBC:「(平文 XOR ベクトル) を暗号化」を続ける
• CTR: 「カウンターを暗号化 XOR 平文」を続ける
実際にTLSで利用するには改ざん検知のためのMAC(メッセージ認証)との組み合わせる
(AEAD)。
これまでの
主流
これからの主流に
(GCM後述)
- 29. GCM
• GCM (Galois Counter Mode: ガロアカウンター
モード)
• CTRとGHASHを組み合わせたAEAD
• ハードウェア処理で高速化が可能
• AESと組み合わせて AES-GCMとして利用
- 31. 一方向ハッシュ
• 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より正式公開
- 33. 公開 暗号
512bit RSAの危険性 FREAK https://freakattack.com/
• 解を求めるのが困難な数学的問題を利用して暗号を生成。
• 公開 と秘密 のペアを生成。公開 はさらして大丈夫。
• 公開 で暗号化し秘密 で復号化。
• RSA 素因数分解
• ECC(楕円曲線暗号)楕円曲線上の離散対数問題
公開 秘密
暗号化 復号化
- 34. 交換
• 2者間で安全に を共有する仕組み
• 互いに公開 を交換しあい、共有 を生成する。
• 通信経路上で共有 のやり取りがない。
• DH (Diffie-Hellman)
• ECDH(楕円曲線DH)
脆弱性:DH Logjam https://weakdh.org/
公開
公開
秘密秘密
- 37. 乱数生成
利用用途:
• 暗号 (対称暗号:秘密 、公開 暗号: ペア)の生成
• 暗号モードの初期ベクトルやNonce(*)の生成
• MAC(メッセージ認証)用
求められる機能:
無作為性: 偏りがなく等しい数である。
予測不可能性: 次の乱数が予想できない。
制限負可能性: 同じ乱数列を再現できない。
(* Nonce(number used once)一度だけ使い捨て用に使われる数字)
- 38. 乱数生成
• 実際の利用は、疑似乱数生成。seedが必要。
• OppenSSLのdefault built-inでは、seedはLinuxの/dev/
urandom+pid+uid+timeを利用。WindowsではOSのAPIの
CryptGenRandomだけでなく画面スクリーンのビットマップハッ
シュやヒープメモリも利用。
脆弱性:
• CVE-2008-0166: DebianやUbuntuのOpenSSLに予測可能
な乱数を生成してしまう脆弱性
• SSH公開 にブルートフォース攻撃
- 39. Linuxのエントロピー
• /dev/urandom
• ブロックしない
• 外部デバイス(キーボードやディスクなど)の割り込みをエントロピー
ソースにして溜める。加工したデータのハッシュ値を取る。
• エントロピーが十分溜まっているかが重要(特にインストール直後)
• /proc/sys/kernel/random/entropy_avail で値を確認できる。
(Max 4k) 1k以下だったらエントロピーの追加を検討。
• findなどでDisk I/Oを人為的に増やしたり、rng-tools, Virtio_RNG,
Haveged 等ツールを使う
- 40. 演習1.1: エントロピーの確認
• サーバに入り、プールしているエントロピーを確認します。
• cat /proc/sys/kernel/random/entropy_avail
• Disk I/Oを発生させます。
• find / > /dev/null
• エントロピーが変わったかどうか確認します。
• /dev/urandom からデータを読み込みます。その後エントロピープー
ルが減ったことを確認します。
• head -10 /dev/urandom > /dev/null
- 42. ASN.1, DER, PEM
PEM: DER形式をBase64に変換し
てBEGINヘッダ∼ENDフッタをつ
けたテキスト
ASN.1: データ構造を表す書式
DER:
ASN.1のデータ構造をタグ+長さ+データでエンコードしたバイナリ
- 43. 秘密 (RSA)
• 公開 暗号やデジタル署名で利用する データ。実際は公開
と秘密 の ペアを生成している。
• TLS通信のセキュリティを確保する要の一つ。厳重に管理。
• 秘密 が漏洩するなど危殆化するとTLS通信のセキュリティは
確保できなくなる。
• PKCS#1(RFC3447)で規定
• 秘密 は暗号化してPKCS#5形式で保管する、パスワードで復
号化。
- 44. 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から計算できる
- 45. CSR
• Certificate Signing Request(証明書署名要求)
• PKCS#10(RFC2986)で規定
• サーバ証明書の識別子(サーバ名など)と公開 を
含んだもの。CA(認証局)にCSRを申請してサー
バ証明書を発行してもらう。
- 46. CSRの中身
• Version: バージョン 0x0
• Subject: 証明書を発行してもらうサーバの識別名
Subject: C=JP, ST=Hokkaido, O=Security Camp, CN=server21.hokkaido.koulayer.com
• 公開 :アルゴリズムや公開 のデータ
• 署名:上記データの署名
CN: Common Name
サーバ名が入る
- 58. 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 HelloRequest
0x01 ClientHello
0x02 ServerHello
0x0b Certificate
0x0c ServerKeyExchange
0x0d CertificateRequest
0x0e ServerHelloDone
0x0f CertificateVerify
0x10 ClientKeyExchange
0x14 Finished
TLS Record Layerデータに
続いて、次の4種類のTLSデ
ータのいずれかが続く。
TLS Handshakeは、この
10種類に分かれる。
- 59. 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 1
type デー
タ長
データ type デー
タ長
データ type デー
タ長
データ
Extension長 Extensionsデータ例
- 60. ClientHello
Record Layer Handshake (ClientHello)
type protocol
version
length
(2byte
)
msg
type
length
(3byte)
client
version
random sessi
on
id
cipher
suite
comp
ressi
on
Exte
nsion
majo
r
mino
r
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バージョンを指
定、サーバがどのバージョ
ンを使うか選択する
- 61. 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
majo
r
minor major minor
0x16 0x03 0x03 ? + 4 0x01 ? 0x03 0x03 ? 長さ1byte 0x00,0x9c 長さ2bytes
- 64. ClientKeyExchange (RSA 交換の場合)
Record Layer(5bytes) Handshake(ClientKeyExchange)
type protocol
version
length
(2bytes)
msg
type
length
(3byte)
Encrypted PreMasterSecret
major minor
0x16 0x03 0x03 ? + 4 0x10 ? 長さ2バイト ?
PreMasterSecret
client version random 46bytes
major minor
- 65. 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
- 66. PreMasterSecret/MasterSecret
• TLSで利用するIV(初期ベクトル)、共有 、MAC のデータ元
• MasterSecretは48バイト長。PreMasterSecretの長さは 交換方式に依
存する。
• MasterSecretは、PreMasterSecret、ClientRandom、
ServerRandom、固定ラベルから生成する。
• Clinet/ServerRandomは全て丸見え。PreMasterSecretは、必ず死守し
て守らないといけない。これが漏えいするとTLSの安全性は全ておじゃん。
Freak/Logjam
- 68. Finished
struct {
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を受信すると、これまで送受信したハンドシェイクデータから計算した値と比較。
ハンドシェイクデータが改ざんされてないことを確認する。
- 70. Forward Secret
• 前方秘匿性 (PFS: Perfect Forward Secrecyとも書かれることも)
• セッション毎に一時的な公開 を使う。
• 証明書の秘密 は、一時的な公開 への署名に利用する。
• ハンドシェイクを含む全暗号データを取得されているような状況でも、将
来的な証明書の秘密 漏洩などのリスクに対応する。
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Ephemeral:一時的な
交換手法
接続ごとに公開 を変更する
- 71. 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より 長・計算量が少なくてすむ。
- 73. ECDHEのハンドシェイク
ClientHello
+ elliptic_curves
+ ec_point_formats
ServerHello
+ ec_point_formats
Certificate
ServerKeyExchange
ServerHelloDone
ClientKeyExchange
ChangeCipherSpec
Finished ChangeCipherSpec
Finished
Application Data
(赤文字が追加変更されるところ)
ClientHello拡張を追加
ServerHello拡張を追加
楕円曲線名とServer
の公開 を署名付き
で送付
Clientの公開 を送付
楕円点の書式を合意
使える楕円曲線名と楕円点書式を通知
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
公開 は毎回ランダムに生成されます
https://html5.ohtsu.org/seccamp_hokkaido_2015/ ecdhe.pcap
- 78. Logjam攻撃
• DHE 交換に対する攻撃(2015年5月に公開)
• あらかじめ素数Pがわかっていれば従来より離散対数問題
を効率的に解けるようになった。
• DHでは標準素数が規定されており幾つかの実装ではそれ
を利用している。
• 512bit長の標準素数は数十秒で解ける。1024bit長も国
家予算並みのお金をかければ解読できる。2048bit長以上
の利用を推奨。
- 90. 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オクテットは何ですか?
- 95. 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
- 101. 演習: SPDY indicatorのインストール
• https://chrome.google.com/webstore/
category/extensions から検索・インストール
• HTTP/2サイトにアクセスして確認
• chrome://net-internals/#http2 でHTTP/2の
接続状況を確認
- 103. 1. HTTP Head of Line Blocking
クライアント サーバ
HTTP/1.1
1本のTCP接続
HTTP リクエスト
HTTPレスポンス待ち時間
HTTP リクエスト
- 109. 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
- 110. 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は省いています)
データの
位置・サイズ・型
が明確
- 115. 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
- 121. 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の利用条件を制限すべきかどうか大きな議論になった
が、 新しいプロトコルはよりセキュアな状態で提供すべきとの意見で合意
- 122. 演習4.1: nginx を http2対応にする
server {
listen 443 ssl http2;
・・・・
}
わずかこれだけ
- 125. もう一度HTTP/2のTLS条件を思い出せ!
• 長 (DHE 2048bit以上、ECDHE 224bit以
上)サポート必須 • PFS必須 (DHE, ECDHE)
• AEAD(GCM/CCM)以外の暗号方式をブラッ
クリストとして利用禁止
(注: openssl-1.0.2以上限定です)
これならいけるはず
- 127. 演習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秒後返す