HTTPS通信時のURLは暗号化されるか

2018/06 追記

古い記事ですがちょこちょこアクセスいただいているので更新。
最近は常時SSLIPv4枯渇、CDN導入などの理由でSNIが良く使われるようになってきていますが
この場合、ホスト名(URL全体ではない)は平文で送信されます。

client 側でキャプチャしたパケット
curl -k https://sni.example.com/hogehoge

$ sudo ngrep -d en3 -q -W byline port 443 and host 192.0.2.1
interface: en3 (192.168.6.0/255.255.255.0)
filter: (ip or ip6) and ( port 443 and host 192.0.2.1 )

T 192.168.6.108:55460 -> 192.0.2.1:443 [AP]
...........[1.K.gr8%.k...*MY.n.........SR....D...,.+.$.#.
.....0./.(.'...........k.g.9.3.......=.<.5./.
.............S.........sni.example.com.

SNIとは

追記終わり

暗号化される派と暗号化されない派に別れてて、聞かれたので。

タイトルのような問い方だと少し曖昧なので、答え方によって別れるのかな。

  • HTTPS通信中のURL情報は暗号化される
    • 盗聴されてもURLはばれない
  • web serverのログにはURLは復号されて記録される
    • ログを残すかは設定次第

(web serverって書いておきながらapacheのことしか考えていません。でもたぶん他のhttpdでも同じだと思う)


冒頭の身近な人たちには、HTTPS通信中のURLも暗号化されない派がいたので、↓の内容で説明した。

httpsのフローとしては

  1. clientがserverのtcp 443 portに接続
  2. serverは証明書と公開鍵をclientに送信
  3. clientはserverの証明書を検証
    1. 検証できたら(or 警告が出ても無視すれば)共通鍵を生成し、serverの公開鍵で暗号化してserverに送信
  4. serverは自身の秘密鍵を用いて、暗号化された共通鍵を復号
  5. client - serverで暗号化のセッションが確立し、以降共通鍵で暗号化してHTTP over SSL通信が行われる (ここでURLとHTTPヘッダ、ボディが送られる)


ということだと思うのでHTTPS通信中のURLは暗号化されると。試しにmod_sslが動いているapacheでパケットキャプチャしつつ、clientでssl接続すると暗号化されてるのがわかる。

  • http

client

$ curl -I http://192.168.0.1/hoge

server: ngrep (tcpdump) でキャプチャする。
URLだけでなくて、HTTP Request全体が平文でみえてる。

# ngrep -q -W byline dst\ port 80 and host 192.168.0.10
interface: eth0 (192.168.0.0/255.255.255.0)
filter: (ip) and ( dst port 80 and host 192.168.0.10 )

T 192.168.0.10:25007 -> 192.168.0.1:80 [AP]
HEAD /hoge HTTP/1.1. 
User-Agent: curl/7.19.7 (i486-pc-linux-gnu) libcurl/7.19.7 OpenSSL/0.9.8k zlib/1.2.3.3 libidn/1.15.
Host: 192.168.0.1.
Accept: */*.
.

client # オレオレ証明書使っているので-k を付ける

$ curl -k -I https://192.168.0.1/hoge

server: ngrep (tcpdump) でキャプチャ。暗号化されていてHTTP Request全体がテキストで見えなくなってる。

# ngrep -q -W byline dst\ port 443 and host 192.168.0.10
interface: eth0 (192.168.0.0/255.255.255.0)
filter: (ip) and ( dst port 443 and host 192.168.0.10 )

T 192.168.0.10:15168 -> 192.168.0.1:443 [AP]
....e...a..O........*3.t...!\.m=.V...(>
:t...(.9.8.5.....
.3.2./....................................192.168.0.1

T 192.168.0.10:15168 -> 192.168.0.1:443 [AP]
.............nG.n..Z.\.v..\\F..2..A.T.b....*h;.....:zk.....T.?I../..)...jVl.VW......H.)....H.Fv.V......J."......*...........g....RF..L..W............0F...k......4.....]<.@.*9d.\.&...5.k...#."6..Fe..

T 192.168.0.10:15168 -> 192.168.0.1:443 [AP]
......+..L..&.&.Tn....4JC..9..Ta
.j.{...S.p9....+A+i..J..t.Zebva~....."M....Y.@.9.X...)...eU.....sb.....]....M....b...R..W..URo.Ko]&..*^5.g.xw...{q...8..W.~h...sz......,;h...r.{T+.B

T 192.168.0.10:15168 -> 192.168.0.1:443 [AP]
.... ...r..rB.O.......;..+......H,B.+

冒頭にも書いたけど、httpsでアクセスしてもログにはURLは平文で残る。POSTデータもapacheのmod_dumpioとかアプリケーションで平文でログに残せるので、送信した情報が安全に使われるかどうかは結局サーバ側の運営次第っていう。あと当然、SSL秘密鍵を盗まれたりすると盗聴&復号されると中身はバレる。って何が言いたいのかわかんなくなってきちゃった。