SSL(Secure Sockets Layer)とTLS(Transport Layer Security)は、ネットワークを介したクライアントとサーバー間の安全なデータ送信を確保する暗号化プロトコルです。これらはすべてのトラフィックを暗号化し、攻撃者によるデータの傍受や改ざんを防ぎます。Google Transparency Report(2025)によると、世界のモバイルトラフィックの95%以上がTLS暗号化を使用しています。このプロトコルがないと、オープンWi-Fiやモバイルネットワークを介して送信された情報は第三者に読み取られる可能性があります。 Cloudflare, 2024
重要なポイント
SSL(Secure Sockets Layer)は、1995年にNetscapeがウェブトラフィックを保護するために開発したプロトコルです。最初のバージョンSSL 1.0は公開されることはなく、SSL 2.0(1995)とSSL 3.0(1996)は2000年代初頭まで使用されましたが、深刻な脆弱性を含んでいました。SSLの後継としてTLS(Transport Layer Security)が登場しました。これはIETFによって標準化された改良版です。TLS 1.0(1999)はSSL 3.0に基づいていましたが、その後のバージョンTLS 1.1(2006)、TLS 1.2(2008)、TLS 1.3(2018)は徐々に元のアーキテクチャから離れ、新しい暗号化アルゴリズムを追加し、脆弱性を修正しました。現在、SSLは時代遅れと見なされており、すべての最新システムはTLSを使用していますが、両方のプロトコルは慣例としてSSL/TLSと一緒に言及されることがよくあります。
SSL/TLSの歴史は、初期のウェブにおける安全なデータ送信の必要性から始まりました。1994年、Netscapeは自社のブラウザNavigator用にSSL 1.0を開発しましたが、深刻なセキュリティ問題のため公開されることはありませんでした。SSL 2.0は1995年にリリースされ実用的に使用されましたが、多くの脆弱性を含んでいました。中間者攻撃に対する保護の欠如、弱い暗号化アルゴリズム、トランケーション攻撃への脆弱性などです。SSL 3.0(1996)はほとんどの問題を修正しましたが、2014年までにPOODLE脆弱性が発見され、その後IETFはすべてのSSLバージョンを正式に時代遅れと宣言しました。TLS 1.0〜1.3は、暗号強度、パフォーマンス、プライバシーを段階的に改善し、TLS 1.3ではハンドシェイクを2ラウンドトリップから1ラウンドトリップに削減しました。これは不安定な接続のモバイルアプリケーションにとって極めて重要です。
ハンドシェイクは、クライアントとサーバー間で安全な接続を確立するプロセスです。これは、両者がプロトコルバージョンに同意し、暗号化アルゴリズムを選択し、キーを交換し、相互に認証するといういくつかの連続したステップで構成されます。TLS 1.3では、ハンドシェイクは1回のネットワークラウンドトリップ(1-RTT)のみで済みますが、TLS 1.2では2回(2-RTT)必要でした。
最初のステップは、クライアントがClientHelloを送信することです。これは、サポートされているTLSバージョン、暗号スイート、および乱数を含むメッセージです。サーバーは、選択されたバージョンと暗号、X.509証明書、およびデジタル署名を含むServerHelloで応答します。クライアントは証明書を認証局(CA)チェーンを通じて検証し、セッションキーを生成して、証明書から取得したサーバーの公開鍵で暗号化して送信します。サーバーによる確認後、安全なデータ送信が開始されます。ハンドシェイク全体は最新のデバイスで1〜3ミリ秒かかり、ユーザーには認識されません。
TLS認証の基盤は、X.509形式の証明書に基づく公開鍵基盤(PKI)です。各証明書には、ドメイン名(Common NameまたはSubject Alternative Name)、サーバーの公開鍵、発行者の名前(認証局)、有効期限、およびCAのデジタル署名が含まれます。クライアントは、信頼の連鎖に沿ってサーバーの証明書を検証します。サーバー証明書からルートCAまで、その証明書はオペレーティングシステムに組み込まれています。Androidデバイスでは、ルート証明書はシステムキーストアに保存され、Google Play Servicesを介して更新されます。iOSでは、iOSアップデートを介して更新されます。チェーンのいずれかのリンクが壊れた場合(証明書の期限切れ、ドメインの不一致、不明なCA)、クライアントは接続を終了します。自己署名証明書(開発で使用)の場合は、明示的な信頼が必要です。AndroidではNetwork Security Configを介して、iOSではInfo.plistのNSExceptionDomainsを介して行います。証明書チェーンの検証プロセスには、CRL(証明書失効リスト)またはOCSP(オンライン証明書ステータスプロトコル)による失効ステータスの確認も含まれますが、モバイルデバイスでは接続を高速化するためにOCSPリクエストがスキップされることがよくあります。これは、アーキテクトが考慮すべきセキュリティとパフォーマンスのトレードオフです。
SSLとTLSという用語はしばしば同じ意味で使用されますが、両者にはモバイルアプリケーションのセキュリティとパフォーマンスに影響を与える基本的な技術的違いがあります。
| 特性 | SSL 3.0 | TLS 1.2 | TLS 1.3 |
|---|---|---|---|
| リリース年 | 1996 | 2008 | 2018 |
| ステータス | 時代遅れ(RFC 7568) | 現行(推奨) | 最新(最良) |
| ラウンドトリップ | 2 | 2 | 1 |
| 鍵交換アルゴリズム | RSA | RSA、ECDHE | ECDHE(のみ) |
| 認証付き暗号化 | なし | GCM、CCM | AEAD必須 |
| 完全前方秘匿性(PFS) | なし | オプション | 必須 |
TLS 1.3とその前身との主な違いは、ECDHEプロトコルによる完全前方秘匿性(PFS)の必須使用です。これは、攻撃者がサーバーの秘密鍵にアクセスできたとしても、以前に傍受したトラフィックを復号化できないことを意味します。サーバーの侵害が現実的な脅威であるモバイルアプリケーションにとって、PFSを備えたTLS 1.3は必須のセキュリティ要件です。
古いバージョンのSSLとTLSには、本番環境での使用に適さない文書化された脆弱性があります。POODLE(CVE-2014-3566)はパディングオラクルを介してSSL 3.0を攻撃し、256リクエストでセッションクッキーを復号化できます。BEAST(CVE-2011-3389)は予測可能なIVを介してTLS 1.0のCBCモードの脆弱性を悪用します。Heartbleed(CVE-2014-0160)はプロトコルの脆弱性ではなく、OpenSSL実装のバグであり、サーバーメモリの読み取りを可能にします。Netcraftによると、2014年には50万台以上のサーバーが脆弱でした。Android 10(API 29)とiOS 13以降、これらのプロトコルはすべてシステムレベルで無効になっています。それでも、開発者はアプリケーションをリリースする前に、SSL Labs Test(qualys.com)でサーバー構成を確認し、時代遅れの暗号スイートがなく、TLS 1.3がサポートされていることを確認する必要があります。
モバイルアプリケーションでは、TLSは3つのレベルでデータを保護します。コンテンツの暗号化(サーバー以外はデータを読み取れない)、整合性の検証(データは転送中に変更できない)、およびサーバー認証(クライアントが正しいサーバーに接続していることを確認)です。認証は特に重要です。これがないと、攻撃者はDNSスプーフィングや偽のWi-Fiアクセスポイントを介してサーバーになりすますことができます。
Google Play Protect(2024)の調査によると、Androidアプリケーションの76%が証明書検証とともにTLSを正しく使用しています。残りの24%は、テストのために証明書検証を無効にし(本番環境で再有効化するのを忘れる)、検証なしで自己署名証明書を使用し、またはSSL 3.0やTLS 1.0などの時代遅れのプロトコルを許可するという間違いを犯しています。iOSのApple App Transport Security(ATS)は2017年から最低TLS 1.2を要求しており、iOS 15以降はすべてのネットワークリクエストでデフォルトでTLS 1.3を使用しています。追加の保護として、Certificate Pinning(特定のサーバー証明書へのバインド)を実装することも推奨されます。
AndroidでOkHttp(最も人気のあるネットワーキングライブラリの1つ)を使用して安全なHTTPS接続を構成する例を見てみましょう。適切な構成には、TLS 1.3の使用を強制し、証明書を検証することが含まれます。
val client = OkHttpClient.Builder()
.connectionSpecs(
listOf(
ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
.tlsVersions(TlsVersion.TLS_1_3, TlsVersion.TLS_1_2)
.cipherSuites(
CipherSuite.TLS_AES_128_GCM_SHA256,
CipherSuite.TLS_AES_256_GCM_SHA384,
CipherSuite.TLS_CHACHA20_POLY1305_SHA256
)
.build()
)
)
.hostnameVerifier { hostname, session ->
SSLSession.DefaultHostnameVerifier.verify(hostname, session)
}
.build()
この例では、サポートされるTLSバージョンのセットを1.3と1.2のみに制限し、時代遅れのTLS 1.0/1.1を除外しています。暗号スイートは、AEADモードと必須の完全前方秘匿性を備えた最新のアルゴリズムから選択されます。HostnameVerifierは、ホスト名が証明書と一致することを確認します。iOSでは、tlsMinimumSupportedProtocolVersionパラメーターを.TLSv13に設定してURLSession構成を介して同様の構成を行います。さらに、iOSではtlsMaximumSupportedProtocolVersionを設定して上位バージョンを制限できます。これは、まだTLS 1.3に移行していないレガシーサーバーとの互換性に役立ちます。このような構成により、モバイルアプリケーションでのデータ送信の最大レベルのセキュリティが保証されます。
よくある質問
TLSはプロトコルのより新しく安全なバージョンです。SSLは時代遅れであり、使用すべきではありません(RFC 7568)。実際には、両方の用語はHTTPS暗号化を指しますが、技術的にはすべての最新システムはTLS 1.2または1.3で動作しています。
Burp SuiteやCharles Proxyなどのプロキシツールをインストールし、アプリのトラフィックを傍受します。接続がHTTPSを使用し、証明書が有効な場合、アプリはTLSを使用しています。トラフィックがHTTPで送信されている場合、暗号化はありません。
本番ビルドではTLS 1.2とTLS 1.3のみが許可されています。SSL 3.0、TLS 1.0、TLS 1.1はサーバーとクライアントアプリケーションの両方で無効にする必要があります。2020年以降、主要プラットフォーム(Android、iOS、ブラウザ)は最低TLS 1.2を要求しています。
はい、推奨されます。TLSは認証局のチェーンを通じて証明書を検証しますが、CAが侵害された場合(2011年のDigiNotarのように)、攻撃者は偽の証明書を発行できます。Pinningは追加の検証レイヤーを追加します。
TLS 1.3は接続確立時間を2ラウンドトリップから1ラウンドトリップに短縮し、最初の接続で30~50%の改善をもたらします。不安定な接続(地下鉄、電車)のモバイルアプリケーションでは、これはデータの読み込み速度にとって極めて重要です。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。