一.HTTP
HTTPS の出現は HTTP の欠点を補うためです:
- 通信内容が盗聴される可能性がある
HTTP は平文通信(暗号化しない)を使用するため、内容は非常に盗聴されやすく、HTTP 自体には暗号化機能がなく、通信内容を暗号化できません
暗号化しないことは元々大きな問題ではありませんでしたが、TCP/IP の仕組みにより通信回線上の任意のノードが报文を取得でき、Internet 上の任意のノードが中継站になる可能性があるため、暗号化が重要になりました
暗号化は盗聴を防ぐことはできません。盗聴者は(暗号化された)报文を簡単に持ち去ることができますが、暗号化により报文の価値を失わせることができます(一定時間内に盗聴者が復号できないことを保証できれば十分です)
- 身元が偽装される可能性がある
HTTP プロトコルには身元検証メカニズムがなく、通信双方の確認を行わないため、「偽クライアント」「偽サーバー」が存在する可能性があります。さらに、DoS(Denial of Service)攻撃が存在するのも HTTP に身元認証メカニズムがないためです
信頼できる第三者機関が提供するデジタル証明書で対応可能です。証明書はサーバーが「本物のサーバー」であることを示すためにも、クライアントが「本物のクライアント」であることを示すためにも使用でき、それぞれが各自の証明書を持てばよいのです
証明書は非常に便利ですが、普及していないのは、第三者機関が提供する*証明書は有料(1 枚数千から十数万 RMB 不等)*だからです。サーバー側は 1 枚で済むので良いですが、大量のクライアント証明書は非常に高価で、一般的なアプリケーションでは負担できず、ネットバンキングなどのアプリケーションのみがクライアント証明書のインストールを必要とします
P.S. 証明書とは何か、具体的な仕組みは何かについては、後で詳しく説明します。さらに、第三者に依存しない「自己署名」もあり、長期的には非常にコストパフォーマンスが良いですが、一般的な企業には手が出せません
- 通信内容が改ざんされる可能性がある
HTTP は报文の完全性を証明できず、报文が途中で傍受され改ざんされたかどうかを確認できないため、MITM(Man-in-the-Middle、中間者)攻撃が存在します
既存の改ざん防止方法には MD5、SHA-1 などのハッシュ値照合や、PGP(Pretty Good Privacy、完璧なプライバシー)を使用したファイルのデジタル署名などがありますが、どれも使い勝手が悪く、クライアントユーザーが自分で改ざんが発生したかどうかをチェックする必要があり、ブラウザが自動的に完了できないため非常に不便です。さらに、たとえそうしても、通信内容の改ざんを 100% 防ぐことはできません。PGP や MD5 自体が書き換えられる可能性があるからです
二.デジタル証明書とハイブリッド暗号化
###1.ハイブリッド暗号化
HTTPS を理解する前に、まずデジタル証明書が何かを理解する必要があり、その前に 3 種類の暗号化方式を知る必要があります:
- 対称暗号化(共有鍵暗号化):最もシンプルな暗号化方式で、通信双方が同じ鍵を保持
送信側が鍵で暗号化して暗号文を受信側に送信し、受信側は暗号文を受け取った後同じ鍵で復号して平文を取得します。逆も同様です
欠点:鍵を安全に相手に渡せない(ネットワーク通信では、情報の安全性は暗号化を通じてのみ保証でき、鍵を安全に送達できるなら、他の情報も安全に送達できることを意味します)
- 非対称暗号化(公開鍵暗号化):鍵はペアで使用され、公開鍵と秘密鍵に分かれる(公開鍵は公開され、秘密鍵は公開されない)
公開鍵を公開し、送信側が公開鍵で暗号化し、受信側は暗号文を受け取った後秘密鍵で復号して平文を取得します。逆方向の通信では送信側が秘密鍵で暗号化し、受信側が公開鍵で復号します
欠点:対称暗号化方式と比較して、非対称方式の暗号化復号プロセスにはより大きなオーバーヘッドがあります(暗号文 + 公開鍵から秘密鍵を推測できないように保証するには、複雑なアルゴリズムのサポートが必要です)
- ハイブリッド暗号化(上記 2 つの方式を統合):非対称方式で共有鍵を渡し、対称方式で通信
対称方式はオーバーヘッドが小さく、最大の問題は鍵が安全に送達されたことを保証できないことですが、非対称方式はまさに鍵共有の問題を解決できるため、ハイブリッド暗号化が生まれました
まず非対称方式で共有鍵を渡し、鍵が安全に送達されることを保証し、その後対称暗号化方式で通信し、非対称方式で通信するオーバーヘッドを回避します。完璧です
HTTPS が採用しているのはハイブリッド暗号化方式です
###2.デジタル証明書
デジタル証明書は実際には暗号化された公開鍵で、この証明書は証明書の所有者(デジタル証明書認証局)と公開鍵の所有者(サーバー/クライアント)の身元を同時に証明できます。具体的な原理は以下の通り:
背景:サーバー側 S が通信を暗号化し、顧客のオンライン業務処理時の情報安全性を確保することを決定
- S の公開鍵を公開する(クライアント C に伝える)
どう公開するかが問題です。C が公開鍵を受け取った後、公開鍵が本物かどうかを確認できないため(S の身元を証明できない)、万一他人が悪意を持って公開した場合は面倒なことになります。
C が 1 つの偽公開鍵を受け取っただけなら、その公開鍵でリクエストを暗号化し、S が復号できないことを発見してリクエストを拒否すればよく、リクエストをもう 1 回送信すれば問題を解決できます。しかし C が 100 個の偽公開鍵を受け取ったら?続けて 1 つずつ検証しますか?
もちろんダメです。这时就需要借助第三者デジタル証明書認証局の助けを借りる必要があります
- S がデジタル証明書認証局 CA に公開鍵の公開を依頼し、この公開鍵が本物であることを証明する(S の身元を証明)
CA は S から受け取ったチップの後、自分の秘密鍵で公開鍵を暗号化し、得られたこの暗号文がデジタル証明書です。さらにこの証明書を S に渡し、今後証明書さえ C に渡せば、C はあなたが本物だと分かると言います(P.S. 実は「証明書」は非常に適切で、S は自分の身元を証明するために CA に行って身分証明書を办理し、CA が赤いスタンプを押す、これが「証明書」です)
ちょっと待って、なぜ C は証明書を見るだけで本物かどうか分かるのか?万一証明書が偽物なら?証明書の有効性をどう証明するのか?
このような際限のない証明を避けるため、ブラウザには CA の公開鍵が内置されています。C は S から受け取った証明書を取得すると、すぐに CA の公開鍵を取り出して証明書を復号します。証明書が本物なら、C は S の公開鍵を取得できます(証明書は CA の秘密鍵で S の公開鍵を暗号化した産物で、復号すれば当然 S の公開鍵が得られます)。これは S の身元を証明するだけでなく、CA の身元も証明します
注意、ブラウザ内置 CA 公開鍵は無料です。ブラウザは市場の需要に適応するために各大手の CA の公開鍵をブラウザに内置する必要があり、CA はブラウザサプライヤーにチップを支払う必要はありません。なぜずっとお金を強調するのか?
証明書が有料で、しかも安くないことを説明するためです。前述しました:
> 証明書は非常に便利ですが、普及していないのは、第三者機関が提供する証明書は有料(1 枚数千から十数万 RMB 不等)だからです。サーバー側は 1 枚で済むので良いですが、大量のクライアント証明書は非常に高価で、一般的なアプリケーションでは負担できず、ネットバンキングなどのアプリケーションのみがクライアント証明書のインストールを必要とします
3. C が S の公開鍵を取得した後、共有鍵(Pre-master secret ランダムパスワード文字列)を暗号化して送信
- S は受け取った共有鍵を秘密鍵で復号し、共有鍵を取得し、その後高速で安全な通信を開始
上記の例はサーバー証明書で、サーバーの身元を証明するために使用されます。同様に、クライアントの身元を証明するために使用されるクライアント証明書もあり、例えばネットバンキングの U シールドなど
証明書は高価なため、ネットバンキングなどのもののみがクライアント証明書を持っています
###3.自己署名
有名な CA 機関の証明書は比較的高価なため、一部の企業は自分で証明書を搞ることを決定しました(自分が CA になる)。これがなぜ時々ウェブページを閲覧する際にブラウザがウィンドウをポップアップして、このサイトの証明書は信頼できませんが、アクセスを続行しますか……と提示する理由です。実際にはブラウザがそのサイトの公開鍵を内置していないため、結果としてブラウザは証明書を見ましたが、証明書の真偽を証明できません
したがって自己署名にはあまり意味がなく、通信の安全性を向上させることはできません。自分が CA になって有名な CA になり、公開鍵がブラウザに收藏されて初めて意味があります
自己署名の利点は証明書が安価なことで、生産条件さえ備えていれば、無限に証明書を生産でき、自由に発行できます。
しかし自分が CA になるのはそれほど簡単ではなく、CA は非常に信頼性の高い安全防護条件を備える必要があるため、有名な CA が証明書に料金を徴収するのも合理的で、証明書頒布システムの安全性を維持するためです
三.HTTPS
###1.HTTPS とは何か?
HTTPS = HTTP + 暗号化 + 認証 + 完全性保護
= HTTP + (SSL + TLS で実装された)暗号化 + (デジタル証明書で実装された)認証 + (デジタル証明書で実装された)完全性保護
HTTP = TCP + IP
HTTPS = SSL + TCP + IP
P.S.TLS は SSL を原型として開発されたプロトコルで、時には統一して SSL と呼ぶため、最後の等式には TLS がありません
注意:
- HTTPS は HTTP より 2〜100 倍遅い
一方では SSL 通信自体が遅く(SSL の伝送処理)、他方では SSL のオーバーヘッドが大きく、処理速度が遅い
根本的な解決方法はなく、SSL アクセラレータのような(専用サーバー)ハードウェアを使用して SSL 処理速度を向上させることができます
- HTTPS は常に暗号化通信を行っているわけではない
機密情報を伝送する時のみ暗号化(HTTPS を使用)し、他の時は依然として HTTP を使用し、通信速度を向上させオーバーヘッドを削減できます
###2.暗号化方式
- 通信の暗号化
HTTP には暗号化メカニズムがないため、SSL(Secure Sockets Layer)と TLS(Transport Layer Security)を導入して通信の暗号化を実現
SSL で安全通信回線を確立した後、この回線上で HTTP 通信を行う方式を HTTPS(HTTP Secure、ハイパーテキスト転送安全プロトコル)または HTTP over SSL と呼びます
- 内容の暗号化
报文本文を暗号化します。もちろん、これにはクライアント、サーバーの双方向の協力(どちらも暗号化/復号機能をサポートする必要あり)が必要です
しかも内容のみを暗号化しても安全ではありません。报文首部が暗号化されていないため、HTTP 首部注入攻撃で破られる可能性があります
###3.身元認証方式
- BASIC 認証
サーバー側が 401 レスポンスを返して身元認証を要求し、クライアントはユーザー名とパスワードを Base64 エンコードしてサーバー側に送信し、サーバー側はこの文字列に基づいて身元検証を行い、成功すれば 200 を返し、そうでなければ 401 を続けます
Base64 エンコードは暗号化ではなく、平文伝送とほとんど変わらず、HTTP 伝送は非常に安全ではないため、あまり使用されません
- DIGEST 認証
BASIC 認証が Base64 エンコードでパスワードを伝送するのが安全でないなら、パスワードを簡単に暗号化します(パスワードに MD5 演算を実行)
盗聴は防げますが、身元偽装は防げず、あまり使用されません
- SSL クライアント認証
証明書を使用すれば身元偽装を防げます。クライアントがクライアント証明書をサーバー側に送信し、サーバー側はクライアントの公開鍵を取り出し、その後 HTTPS 通信を開始
しかしクライアント証明書も有料なため、あまり使用されません
- フォームベースの認証
最も一般的なのはフォームベースの認証で、安全性は Web アプリケーションに依存
一般的に MD5 + salt(塩を加えた MD5)が使用されます。ここで説明する必要があります:
salt は実際にはサーバー側が生成したランダム文字列で、サーバーデータベースに保存されます
新規ユーザー登録時にユーザー ID に対応す��� salt 文字列を生成し、その後 salt 文字列とユーザーの平文パスワードを結合し、結合結果に MD5 を実行し、結果をユーザーテーブル内のそのユーザーのパスワード文字列とします
ログイン時にテーブルを照会してユーザーに対応する salt を取り出し、平文パスワード文字列と結合してパスワード文字列を取得し、さらにユーザーテーブルを照会してそのユーザーのパスワードを取り出して比較し、身元を検証
塩を加えるのは実際にはテーブル照会による MD5 破解を防ぐためで、塩を加えない MD5 はレインボーテーブルですぐにテーブル照会破解でき、塩を加えた後はパスワードの特徴を減らします(ユーザーテーブル内で平文パスワードが同じユーザーのパスワード文字列は異なります)
MD5 + salt については非常に良い記事があります。烏雲:加塩 hash でパスワードを保存する正しい方法 を参照してください
四.HTTPS 通信プロセス
- クライアントが Client Hello 报文を送信して SSL 通信を開始
报文にはクライアントがサポートする SSL の指定バージョン、暗号コンポーネント(Cipher Suite)リスト(サポートする暗号アルゴリズムおよび鍵長など)が含まれます
- サーバー側が SSL 通信可能な場合、Server Hello 报文で応答
クライアントと同様に、报文には SSL バージョンおよび暗号コンポーネントが含まれます。サーバー側の暗号コンポーネント内容は受信したクライアント暗号コンポーネントから筛选されたものです
- サーバー側が Certificate 报文を送信
报文には公開鍵証明書が含まれます
- サーバー側が Server Hello Done 报文を送信してクライアントに通知
初期段階の SSL ハンドシェイクネゴシエーション部分が終了
- SSL 第 1 回ハンドシェイク終了後、クライアントが Client Key Exchange 报文で応答
报文には通信暗号化で使用される Pre-master secret と呼ばれるランダムパスワード文字列が含まれます。この报文はステップ 3 の公開鍵で暗号化されています
- クライアントが引き続き Change Cipher Spec 报文を送信
この报文はサーバー側に、この报文後の通信は Pre-master secret 鍵で暗号化されることを提示
- クライアントが Finished 报文を送信
この报文には接続からこれまでの全报文の総合校验値が含まれ、このハンドシェイクネゴシエーションが成功するかどうかは、サーバー側がこの报文を正しく復号できるかどうかを判定基準とします
-
サーバー側も同様に Change Cipher Spec 报文を送信
-
サーバー側も同様に Finished 报文を送信
-
サーバー側とクライアントの Finished 报文交換完了後、SSL 接続が確立完了
もちろん、通信は SSL 保護を受け、ここからアプリケーション層プロトコルの通信、つまり HTTP リクエストを送信
- アプリケーション層プロトコル通信
HTTP リクエスト/レスポンスを送信し、MAC(Message Authentication Code)报文摘要を付加し、MAC をチェックすることで报文が改ざんされたかどうかを知り、报文の完全性を保護
- 最後にクライアントが接続を切断
close_notify 报文を送信
- TCP 接続を切断
TCP FIN 报文を送信して TCP 通信を閉じる
参考資料
- 《図解 HTTP》
コメントはまだありません