SSL/TLS:開発における主要概念とプロトコル

著者: IT Sectr 公開日: 2026-03-09 読了時間: 9 分

SSL/TLSは、モバイルアプリケーションとサーバー間のデータを暗号化し、トラフィックの機密性と完全性を保証する暗号プロトコルです。Apple(2026)によると、App Transport SecurityはすべてのiOSデバイスでデフォルトでTLS 1.2未満の接続をブロックします。TLS 1.3はTLS 1.2と比較してハンドシェイク時間を2倍短縮し、モバイルアプリケーションのUXを向上させます。

要点

  • TLSは最新の暗号プロトコルであり、セキュリティが向上した旧式のSSLの後継です。
  • TLS 1.3はTLS 1.2の2 RTTに対して1 RTTでハンドシェイクを実行し、読み込みを高速化します。
  • App Transport SecurityはAppleのメカニズムで、iOSでTLS 1.2+のHTTPSを要求します。
  • Network Security ConfigはXML設定によるAndroid向けHTTPS構成です。
  • Certificate Pinningはコードに証明書フィンガープリントを固定してMitM攻撃を防ぎます。

SSL/TLSとは?

SSL(Secure Sockets Layer)とTLS(Transport Layer Security)は、ネットワーク上での安全なデータ転送を保証する暗号プロトコルです。1990年代にNetscapeによって開発されたSSLは、POODLEやBEASTの脆弱性によりバージョン3.0以降、旧式と見なされています。その後継であるTLSは、バージョン1.0、1.1、1.2、1.3を経ており、現在はTLS 1.2とTLS 1.3のみが有効と見なされています。すべての最新モバイルプラットフォームはネットワーク接続にTLSを要求し、App StoreとGoogle Playはレビュー時にこれを確認します。

モバイルアプリケーションにTLSが必要な理由

TLSなしでは、アプリケーションとサーバー間のトラフィックは平文で送信されます。同じWi-Fiネットワーク上の誰でも、Wiresharkやtcpdumpを使用してログイン、パスワード、トークン、ユーザーの個人データを傍受できます。TLSは送信されるすべてのデータを暗号化し(トランスポート層暗号化)、X.509証明書のチェーンを通じてサーバーの正当性を検証します。IETF(2018)によると、TLS 1.3は最新のAEAD暗号(AES-GCM、ChaCha20-Poly1305)のみを使用し、RC4や3DESなどの旧式アルゴリズムを除外しています。

HTTPSとTLS

HTTPS(HTTP Secure)はTLS上のHTTPです。モバイルアプリケーションがhttps://でリクエストを行うと、最初にサーバーとのTLS接続を確立し、その後暗号化チャネルを介してHTTPヘッダーとリクエスト本文を送信します。HTTPSなしでは、まともなAPIは動作すべきではありません — これは基本的なセキュリティ衛生です。OWASP(2026)によると、安全でない接続はモバイルアプリケーションの脆弱性トップ3に入っています。

TLSハンドシェイクの仕組み

TLSハンドシェイクは、クライアントとサーバー間の安全な接続を確立するプロセスです。両者はプロトコルバージョンをネゴシエーションし、暗号スイートを選択し、非対称暗号方式で鍵を交換し、証明書を検証します。TLS 1.2では、ハンドシェイクに2ラウンドトリップタイム(2 RTT)が必要です:クライアント→サーバー(ClientHello)、サーバー→クライアント(ServerHelloとCertificate)、そして最終的なFinishedメッセージ。TLS 1.3はこのプロセスを1 RTTに短縮します。

TLS 1.2ハンドシェイクの詳細な段階

第1段階:ClientHello — クライアントがサポートするTLSバージョン、暗号スイートのリスト、ランダム数を送信します。サーバーはServerHelloで応答し、バージョンと暗号スイートを選択し、X.509証明書(Certificate)とServerHelloDoneメッセージを送信します。クライアントは信頼できる認証局(CA)のチェーンを通じて証明書を検証し、pre-master secretを生成し、証明書の公開鍵で暗号化してClientKeyExchangeでサーバーに送信します。その後、両者はセッション鍵を生成し、ChangeCipherSpecとFinishedメッセージを交換します。この時点以降、すべてのデータは対称暗号化されます。

swift
import Security

let url = URL(string: "https://api.example.com")!
let session = URLSession(configuration: .default,
                           delegate: self,
                           delegateQueue: nil)

func urlSession(
    _ session: URLSession,
    didReceive challenge: URLAuthenticationChallenge,
    completionHandler: @escaping (URLSession.AuthChallengeDisposition,
                                    URLCredential?) -> Void
) {
    let trust = challenge.protectionSpace.serverTrust
    guard let trust else {
        completionHandler(.cancelAuthenticationChallenge, nil)
        return
    }
    completionHandler(.useCredential, URLCredential(trust: trust))
}

URLSessionDelegateを介したiOSでのURLAuthenticationChallengeの処理例。このメソッドは各TLSハンドシェイク中に呼び出され、アプリケーションがサーバー証明書をカスタム検証できるようにします。本番環境では、SecTrustEvaluateWithErrorによる証明書検証を追加し、事前に保存したフィンガープリントと比較してからuseCredentialを呼び出してください。

TLS 1.2 vs TLS 1.3

TLS 1.3(RFC 8446、2018)は10年ぶりの主要なプロトコルアップデートです。主な改善点:ハンドシェイクを1 RTTに短縮(再接続時は0 RTT)、旧式の暗号スイートを削除(RSA鍵交換、CBCモード)、Perfect Forward Secrecy(PFS)を必須化、signed transcriptによるダウングレード攻撃からの保護。Qualys SSL Labs(2026)によると、TLS 1.3はPFSのおかげで長期サーバー鍵が侵害された場合でも保護を提供します。

特性TLS 1.2TLS 1.3
ハンドシェイク2 RTT(完全)1 RTT(PSKで0 RTT)
暗号スイート30以上の組み合わせ(RSA、DH、ECDH)5つのAEADスイート(AES-GCM、ChaCha20)
Forward Secrecyオプション(DHE、ECDHE)必須(すべてのスイート)
iOSサポートiOS 5+iOS 12+
AndroidサポートAndroid 4.0+Android 10+
旧式アルゴリズムRSA、CBC、RC4、3DES完全に削除

0-RTT(ゼロラウンドトリップタイム)はTLS 1.3の機能で、PSK(事前共有鍵)による再接続時にClientHelloとともにデータを即座に送信できます。これにより、特に同じサーバーへの頻繁なリクエストがある場合、モバイルアプリケーションの後続画面の読み込みが高速化します。ただし、0-RTTデータはリプレイ攻撃から保護されていません — 傍受されて再送される可能性があります。0-RTTは副作用のないべき等リクエスト(GET、PUT)にのみ使用してください。

iOSのTLS:App Transport Security

App Transport Security(ATS)はAppleのメカニズムで、TLS 1.2以上でのHTTPS接続を要求し、iOS 9からデフォルトで有効です。ATSはすべてのHTTP接続およびTLS 1.2未満のHTTPSをブロックします。開発者は特定のドメインに対してNSAppTransportSecurityを介してInfo.plistに例外を設定できますが、Appleは例外を最小限に抑え、どこでもHTTPSを使用することを推奨しています。ATS要件の違反は、App Storeレビューでのアプリ拒否の理由となります。

xml
<!-- Info.plist — App Transport Security -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <false/>
    <key>NSExceptionDomains</key>
    <dict>
        <key>cdn.example.com</key>
        <dict>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
        </dict>
    </dict>
    <key>NSAllowsLocalNetworking</key>
    <true/>
</dict>

Info.plistでのATS設定。NSAllowsArbitraryLoadsはfalseに設定されています — すべての接続はHTTPSを使用する必要があります。ドメインcdn.example.comには最小TLSバージョン1.2が指定され、NSAllowsLocalNetworking=trueはローカルネットワークのHTTPを許可します(開発サーバーに便利)。AppleはNSExceptionDomainsなしでNSAllowsArbitraryLoadsを有効にしないことを強く推奨しています — これは一般ルールではなく例外であるべきです。

AndroidのTLS:Network Security Config

Network Security Configは、Java/Kotlinコードを変更せずにHTTPSとTLSを設定するAndroidのメカニズムです。設定はnetwork_security_config.xmlファイルで指定され、android:networkSecurityConfig属性を介してAndroidManifestで接続されます。信頼できる証明書(ユーザーCAとシステムCA)、Certificate Pinning、平文HTTPの無効化、デバッグオーバーライド、トラフィックリダイレクトの設定をサポートしています。

xml
<!-- res/xml/network_security_config.xml -->
<network-security-config>
    <base-config cleartextTrafficPermitted="false">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
    <domain-config cleartextTrafficPermitted="false">
        <domain includeSubdomains="true">api.example.com</domain>
        <pin-set expiration="2027-01-01">
            <pin digest="SHA-256">
                47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
            </pin>
        </pin-set>
    </domain-config>
</network-security-config>

Android用Network Security Config。base-configは平文トラフィックをブロックし、システムCA証明書のみを信頼します(ユーザー証明書はなし — ユーザーによるMitM証明書インストールからの保護)。api.example.comのdomain-configにはSHA-256証明書フィンガープリントのpin-setが含まれています。指定された有効期限前にサーバー証明書が変更されると、接続は拒否されます — これはCertificate Pinningの厳格な形式です。

Certificate Pinningとセキュリティ

Certificate Pinningは、アプリケーションコードにサーバーの証明書または公開鍵を固定する手法です。各TLSハンドシェイク中に、クライアントはサーバー証明書を事前に保存されたフィンガープリント(SHA-256ハッシュ)と比較します。攻撃者が信頼できるCA証明書を入手したり認証局を侵害したりしても、MitM攻撃は実行できません — アプリケーションはCAチェーンではなく特定のフィンガープリントをチェックするからです。これは金融アプリケーションや機密データを扱うアプリにとって特に重要です。

Pinningのリスクと代替手段

Certificate Pinningには注意が必要です:サーバー証明書が変更されると、アプリの古いバージョンはすべて接続できなくなります。複数のバックアップフィンガープリント(プライマリ+バックアップ)を保存し、pin-setの有効期限を指定し、標準のCA検証によるフォールバックメカニズムを実装することをお勧めします。代替手段としてTrust On First Use(TOFU)があります。これはアプリが最初の接続時に証明書を記憶し、変更時にユーザーに警告するものです。OWASP(2026)によると、Certificate Pinningの欠如はモバイルアプリケーションの脆弱性トップ3(M3:安全でない通信)に入っています。

AlamofireでのPinningの実装

Alamofire 5+では、Certificate PinningはServerTrustManagerPinnedCertificatesTrustEvaluator(完全な証明書チェック)またはPublicKeysTrustEvaluator(公開鍵のみ)を介して設定されます。公開鍵の方が望ましいです — 同じCAで証明書を更新しても変更されないからです。[host: evaluator]辞書でServerTrustManagerを作成し、Sessionに渡して、保護されたAPIへのすべてのリクエストに使用します。

よくある質問

SSLとTLSの違いは何ですか?

SSLは旧式のプロトコル(バージョン2.0および3.0)で、POODLEやBEASTの脆弱性により安全ではないと見なされています。TLSはその後継で、TLS 1.0(RFC 2246、1999)から始まります。現代の“SSL証明書”はすべて、TLSプロトコルで使用されるX.509証明書です。SSL 3.0はすべての最新OSとブラウザで禁止されています。

AppleがHTTP接続をブロックする理由は?

App Transport SecurityはAppleのアプリケーションセキュリティ要件です。HTTPはデータを平文で送信するため、公衆Wi-Fiネットワークでトークンやユーザーの個人データを傍受される可能性があります。ATSはデフォルトでHTTPおよびTLS 1.2未満のHTTPSをブロックし、開発者の操作なしでもユーザーを保護します。

サーバーがTLS 1.3をサポートしているか確認する方法は?

SSL Labs(ssllabs.com/ssltest)またはコマンドラインを使用します:openssl s_client -tls1_3 -connect example.com:443。ほとんどのクラウドプラットフォーム(AWS CloudFront、Cloudflare、Nginx 1.19+、Caddy)ではTLS 1.3がデフォルトで有効です。Android 10+では、システムのConscryptプロバイダーにサポートが組み込まれています。

自己署名証明書とは何ですか?本番環境で使用できますか?

自己署名証明書は、認証局ではなく自分自身で署名された証明書です。本番環境では使用できません — モバイルOSはそのような証明書を信頼しません。ローカル開発に使用されます:MDMを介して信頼できる証明書に追加するか、検証を無効にしたデバッグビルドを使用してください。

AlamofireでPinningを設定する方法は?

ServerTrustManagerPinnedCertificatesTrustEvaluatorまたはPublicKeysTrustEvaluatorとともに作成します。前者は完全な証明書をチェックし、後者は公開鍵のみをチェックします(推奨)。マネージャーをSession(configuration: serverTrustManager:)に渡し、すべてのAPIリクエストにそのセッションを使用します。

まとめ

  • TLSは最新の暗号化プロトコルであり、旧式のSSLの後継で、すべてのモバイルアプリケーションに必須です。
  • TLS 1.3は1 RTTでハンドシェイクを実行し(TLS 1.2の2倍高速)、必須のForward SecrecyとAEAD暗号のみを使用します。
  • App Transport Security(iOS)はiOS 9+のすべてのAppleデバイスでHTTPおよびTLS 1.2未満を自動的にブロックします。
  • Network Security Config(Android)はコード変更なしでXMLを介してHTTPS、Certificate Pinning、平文禁止を設定します。
  • Certificate PinningはNetwork Security ConfigまたはServerTrustManagerでSHA-256証明書フィンガープリントを固定してMitM攻撃を防ぎます。
  • TLS 1.3は5つのAEAD暗号スイートを使用し、旧式のRSA鍵交換とCBC暗号モードを除外しています。
  • TLS設定は公開の必須ステップです:App StoreはATSをチェックし、Google PlayはNetwork Security Configを介して平文トラフィックをチェックします。

ターンキー方式のモバイルアプリケーションを開発します

IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。

プロジェクトについて相談

こちらもお読みください