HTTPSは安全なのか？

# いきなり追記 2024-01-09
- この記事にはまともな結論がありませんし論点も定まっていません
- この記事には批判が多いので、こちらの素敵な記事をぜひお読みください。
    - [Free Wi-Fi(00000JAPAN)は安全なのか？
](https://qiita.com/ngkwtys/items/3756edcd690d5b6221cb)
- コメントで不愉快とされたところを削除しました。
    - 徳丸さんのツイート
    - 猫の写真
    - 素人というエクスキューズ
    - （編集履歴はqiitaの機能で見れると思います）
- 信頼できるサービスであれば Free Wi-Fi に限らず被害に遭う可能性はとても低いと思います。気にせず使ってください。
- 気分を害された方にお詫び申し上げます。




# ここから元記事
お正月休みは卒業した大学の記事を書く予定でしたが、ちまたで話題の「httpsなら安全」について攻撃的なツイートを散見どころかめっちゃ見たのでこの記事を書いています。httpsを盲信されるならまだしも、無知の斧で攻撃を振るう方に悲しみを覚えたので、正しい知識を持ち攻撃的なツイートを控える人間性を持ってほしいと言う思いで書きます。

# 結論
- 確率論の話をするあなたは正しい。 **Free Wi-Fi は 安全** です。
- 技術的な話をするあなたは正しい。 **Free Wi-Fi は 危険** です。
- **https だから安全** というあなたは間違っています。
- この議論に「完全に安全」「完全に危険」いずれの答えも存在しません。「**安全でもあり危険でもある**」が答えです。その前提で議論をしましょう。
- 攻撃的な言葉は慎みましょう。
- httpsに関係ない話題は書きません(フィッシングとかショルダーハッキングとか)

# Free Wi-Fi が安全なあなたへ

MITM(中間者攻撃) を受ける可能性は低いですよね。だから安全です。これで満足したら、酒のつまみとして次の話を読んでほしいです。

## https が MITM を防げない理由

httpsは暗号化されてるので安全です。問題は **誰と誰の間が暗号化されているのか** です。安全なシーンでは、暗号化されているのは「あなたと対象サーバ」の間です。下の図で **あなたとexample.comは機密情報を見ることができている**点に注目してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/7c3d54e4-db7a-4a82-9db2-4a41cf266f6e.png)




MITMでは、暗号化されているのは 「**あなたと攻撃者の間**」 と 「攻撃者と対象サーバの間」になります。**攻撃者が機密情報を見れている**点に注目してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/15d06e59-f3e8-25a0-c221-5fe991732248.png)

これは攻撃のための技術に限らず、一般的なproxyでもよく利用される仕組みです。残念ながら「https|暗号化は安全」を信じている方はこの時点で暗号化が世の中でどのように利用されているかをご存知ないと言わざるを得ません。これを機に覚えましょう。

気にするべきは **誰と誰の間で暗号化されているのか** です。暗号化が安全であるかを確認する最初のステップです。

*話をややこしくするのが **「https」という単なるプロトコルを表す文字列** に「ブラウザの機能」「App storeの審査」などそれ以外の概念を混ぜて語る人たちです。ここまでは、**単なるプロトコル** として話していることに留意してください。



# Free Wi-Fi が危険なあなたへ

極論言えば危険ですよね。どんな時に危険なのかまとめてみましょう。

## MITMって防げますよね

ここからは、https 通信をするソフトウェアを client を呼びます。Client の代表例は Chrome, Safariなどのブラウザです。client は MITM を防ぐために様々な努力を重ねてきました。その代表例がサーバ証明書です。

MITM の一番の問題は、あなたの client が攻撃者のサーバを本物だと勘違いすることです。赤線で囲った部分を何とかして防ぐ必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/e51e1d89-5f52-f84d-7877-74eac4badf23.png)


### MITM: 証明書を偽造された場合

すぐ思いつくのは、攻撃者が `example.com` が使っているサーバ証明書を偽造することです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/901f11a6-e4cc-8bda-0afd-ebb40a42fdf6.png)

これはなかなか成功しません。なぜなら、 **偽物のサーバ証明書を作るのが難しい** からです。

#### Trust Store: Client がサーバ証明書を信じる方法

Clientはどうやって偽物を見分けるのでしょうか？ Clientは、「信頼できるルート証明書」を自分自身（またはOS）の中に持っています。対象の証明書が、信頼できるルート証明書が署名した証明書かどうかを **検証** して見分けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/97ea15b9-6988-1443-721f-a6281daaec0f.png)

このルート証明書のリストを「トラストストア」と呼びます。代表的なものを適当に貼っておきます。

- [iOS / Mac OS](https://support.apple.com/en-us/HT209143)
- [Chrome](https://www.chromium.org/Home/chromium-security/root-ca-policy/)
- [Linux / Firefox](https://wiki.mozilla.org/CA/Included_Certificates)
- [Windows](https://learn.microsoft.com/en-us/security/trusted-root/program-requirements)

**ほぼ全ての client** はルート証明書の検証を行います。

"信頼できる証明書" は 信頼できる **CA(認証局)** を騙さなければ発行できないので、この壁を越えることは難しいです。ただし例外として、数多の CA が不正な証明書を発行した歴史があることは申し添えなければいけません。CA が誤って発行すべきではない証明書を発行することもありますし、CA の脆弱性を突かれて意図しない証明書を発行されるケースもありますし、CA 自体に MITM をする意思がある場合もあります。そのためトラストストアはルート証明書を日々監視しており、怪しい CA にはトラストストアからの削除という厳しい措置が取られます。

いずれにしても、`正当なルート証明書を持つCA` が`不当な証明書を発行した` 場合に **トラストストアは無力です**。

#### Certificate Transparency: 怪しい証明書を見つける方法

誰かが勝手に `example.com` の証明書を発行したとき、それに気づく方法はあるでしょうか？ Google が提唱した Certificate Transparency(CT) はそれを可能にしました。CTLog と呼ばれるログを見てみましょう。これは `example.com` に対して取得された証明書のリストです。

https://crt.sh/?q=example.com

ここを見ていれば、誰かが勝手に証明書を発行したらすぐに気づけるようになりました。逆にいうと、ここに載っていない証明書は正当な CA が発行していない証明書である可能性も高いです。一部の Client は CT にない証明書の場合、警告を発してアクセスを中断します。以前の Chrome では `ERR_CERTIFICATE_TRANSPARENCY_REQUIRED` が表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/58b34604-10b6-3d25-af0d-146dd8016fa3.png)
> https://comodosslstore.com/resources/how-to-fix-neterr_certificate_transparency_required-error-in-google-chrome/

*ブラウザの動向は日々変わるため、現在の動作とは一致しません


### MITM: 証明書を検証しない場合

Trust store と CT があればかなりの危険性は排除できますね。しかし、それらの**対策が全て無力になる**時が存在します。それは **Clientが全ての証明書を信じてしまう** 場合です。個人的に、一連のツイートはこの可能性を排除しているように見受けられました。

大抵の client で証明書の検証を無効化するのは簡単であり、私は広く利用されていると思っています。スマホアプリでも同様で、検証を無効化するオプションは存在します。そのアプリが各社の審査を経て公開されるかどうかを専門家ではない私は知りません。しかし、件のツリーにあった iOS の仕様には確かに無効化オプションが存在し、Appleが認めれば利用できるという記述があったことは申し添えておきます。

証明書の検証自体が client の義務ではなく **取りうる選択肢の一つ** である限り、この問題は永遠に無くなりません。TLSというプロトコルが今後どうなっていくのかは非常に興味深いところです。


#### Backend はブラックボックス

*可能性を微塵も考えていない人がいそうなので「そこ関係ないだろ」と言われるためのネタを最後に書きます。


ここで伝えたいことは、**httpsで通信したその先がhttpsとは限らない**ということです。

ほとんどのスマホアプリは Hybrid app と呼ばれ、内部の Webブラウザを使って外部にあるサイトを表示しています。この時、外部サイトの後ろでどんな通信をしているかは知る由がありません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24737/661445c7-2222-1c89-f53a-5b73c16bf55a.png)


何を言いたいかというと、信頼できるサイト/アプリ自体が MITM をしている構造になっているということです。これはもう、そのサービスを信じるしかありません。

開発者は local/beta 環境の都合で証明書検証を無効にすることがあり、手違いでそのまま本番サーバに適用されてしまうこともあり得ます。（先に言っておきますが、私を馬鹿にして悦に浸ってもその可能性はこの世から消えません）

今どきの金融機関が https を使っていないわけはありませんが、（ここに書けない事例）を知っている身としては、日本を始め各国の金融機関はまだ過度に信用できる状態ではないと思ってます。ちょうど今日、こんなツイートもありましたし。

<削除>

ここは余談なんで否定の声もあるでしょうが、「httpsなら安全」は **「見えないところも全部httpsだと信じる」** おまじないみたいな側面があるところは認識してもらえたら嬉しいです。

# おわりに

言いたかったことは終わりです。きっと攻撃的なツイートが飛んでくるんでしょうが、その中の一人でもいいので「そうだったんだ」と思ってくれる人がいれば嬉しいです。**セキュリティクラスタは口が悪く説明をしない** 定説を覆したいので、良識あるセキュリティクラスタの方がいらっしゃいましたら、この記事の誤りや問題点をぜひ**優しくかつ易しい言葉で**説明していただければと思います。

よろしくお願いします。