Xamarin.iOS のアプリ トランスポート セキュリティ
アプリ トランスポート セキュリティ (ATS) は、インターネット リソース (アプリのバックエンド サーバーなど) とアプリ間にセキュリティで保護された接続を強制します。
この記事では、アプリ トランスポート セキュリティが iOS 9 アプリに強制するセキュリティ変更と、これが Xamarin.iOS プロジェクトに何を意味するかを紹介し、ATS 構成オプションについて説明し、必要に応じて ATS をオプトアウトする方法について説明します。 ATS は既定で有効になっているため、セキュリティで保護されていないインターネット接続では、iOS 9 アプリで例外が発生します (明示的に許可した場合を除く)。
アプリ トランスポート セキュリティについて
前述のように、ATS は、iOS 9 および OS X El Capitan のすべてのインターネット通信がセキュリティで保護された接続のベスト プラクティスに準拠していることを保証し、アプリまたは使用しているライブラリを介して偶発的に直接機密情報が漏えいすることを防ぎます。
既存のアプリの場合は、可能な限り HTTPS
プロトコルを実装します。 新しい Xamarin.iOS アプリの場合は、インターネット リソースと通信するときに HTTPS
のみを使用する必要があります。 さらに、高度な API 通信は、前方秘匿性がある TLS バージョン 1.2 を使用して暗号化する必要があります。
NSUrlConnection、CFUrl、または NSUrlSession で作成された接続は、iOS 9 および OS X 10.11 (El Capitan) 用に構築されたアプリで既定で ATS を使用します。
既定の ATS の動作
iOS 9 および OS X 10.11 (El Capitan) 用に構築されたアプリでは ATS が既定で有効なため、NSUrlConnection、CFUrl、または NSUrlSession を使うすべての接続は ATS セキュリティ要件の対象となります。 接続がこれらの要件を満たしていない場合、例外が発生して失敗します。
ATS 接続の要件
ATS により、すべてのインターネット接続に次の要件が強制されます。
- すべての接続暗号は、前方秘匿性を使用する必要があります。 以下に示す、受け入れられる暗号の一覧を参照してください。
- トランスポート層セキュリティ (TLS) プロトコルは、バージョン 1.2 以上である必要があります。
- 2,048 ビット以上の RSA キーを持つ SHA256 フィンガープリント、または 256 ビット以上の楕円曲線 (ECC) キーをすべての証明書に使用する必要があります。
繰り返しますが、iOS 9 では ATS が既定で有効になっているため、これらの要件を満たさない接続を試みると、例外が発生します。
ATS 互換暗号
ATS セキュリティで保護されたインターネット通信では、次の前方秘匿性暗号の種類が受け入れられます。
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
iOS インターネット通信クラスの操作の詳細については、Apple の NSURLConnection クラス リファレンス または NSURLSession クラス リファレンスを参照してください。
Xamarin.iOS での ATS のサポート
iOS 9 および OS X El Capitan では ATS が既定で有効になっているため、Xamarin.iOS アプリまたは使用しているライブラリまたはサービスをインターネットに接続する場合は、何らかのアクションを実行する必要があります。そうしないと、接続によって例外が発生します。
既存のアプリの場合、Apple はできるだけ早く HTTPS
プロトコルをサポートするよう提案しています。 HTTPS
をサポートしていないサード パーティの Web サービスに接続しているために接続できない場合、または HTTPS
のサポートが実用的でない場合は、ATS をオプトアウトできます。 詳細については、後述する「ATS のオプトアウト」セクションを参照してください。
新しい Xamarin.iOS アプリの場合、インターネット リソースと通信するときに HTTPS
のみを使用する必要があります。 ここでも、これが不可能であり、ATS をオプトアウトする必要がある状況 (サード パーティの Web サービスの使用など) が生じる場合があります。
さらに、ATS では、前方秘匿性のある TLS バージョン 1.2 を使用して高度な API 通信に対する暗号化が強制されます。 詳細については、上記の「ATS の接続の要件」と 「ATS の互換性のある暗号」のセクションを参照してください。
TLS (トランスポート層セキュリティ) にはあまり馴染みがないかもしれませんが、これは SSL (Secure Socket Layer) の後継であり、ネットワーク接続経由でセキュリティを適用するための暗号化プロトコルのコレクションを提供します。
TLS レベルは、使用している Web サービスによって制御されるため、アプリの制御外です。 HttpClient
と ModernHttpClient
の両方で、サーバーでサポートされている最高レベルの TLS 暗号化が自動的に使用されます。
通信しているサーバー (特にサード パーティのサービスの場合) によっては、前方秘匿性を無効にするか、より低い TLS レベルを選択することが必要になる場合があります。 詳細については、後述の 「ATS オプションの構成」 セクションを参照してください。
重要
App Transport Security は、マネージド HTTPClient 実装を使用する Xamarin アプリには適用されません。 これは、CFNetwork HTTPClient 実装、または NSURLSession HTTPClient 実装を使用する接続にのみ適用されます。
HTTPClient 実装の設定
iOS アプリで使用される HTTPClient 実装を設定するには、ソリューション エクスプローラーで [プロジェクト] をダブルクリックして、[プロジェクト オプション] を開きます。 iOS ビルドに移動し、[HttpClient の実装] ドロップダウンで希望するクライアントの種類を選択します。
マネージド ハンドラー
マネージド ハンドラーは、Xamarin.iOS の以前のバージョンに付属しているフル マネージド HttpClient ハンドラーであり、既定のハンドラーです。
長所:
- これは、Microsoft .NET および以前のバージョンの Xamarin と最も互換性があります。
短所:
- iOS と完全には統合されていません (たとえば、TLS 1.0 に制限されています)。
- 通常、ネイティブ API よりもはるかに低速です。
- より多くのマネージド コードが必要になり、より大きなアプリが作成されます。
CFNetwork ハンドラー
CFNetwork ベースのハンドラーは、ネイティブ CFNetwork
フレームワークに基づいています。
長所:
- ネイティブ API を使用して、パフォーマンスを向上させ、実行可能ファイルのサイズを小さくします。
- TLS 1.2 などの新しい標準のサポートを追加します。
短所:
- iOS 6 以降が必要です。
- watchOS では使用できません。
- 一部の HttpClient の機能とオプションは使用できません。
NSUrlSession ハンドラー
NSUrlSession ベースのハンドラーは、ネイティブ NSUrlSession
API に基づいています。
長所:
- ネイティブ API を使用して、パフォーマンスを向上させ、実行可能ファイルのサイズを小さくします。
- TLS 1.2 などの新しい標準のサポートを追加します。
短所:
- iOS 7 以降が必要です。
- 一部の HttpClient の機能とオプションは使用できません。
ATS の問題の診断
iOS 9 で直接または Web ビューからインターネットに接続しようとすると、次の形式のエラーが発生するおそれがあります。
クリアテキスト HTTP (
http://www.-the-blocked-domain.com
) リソースは安全ではないため、アプリ トランスポート セキュリティにより読み込みがブロックされました。 一時的な例外は、アプリの Info.plist ファイルを使用して構成できます。
iOS 9 では、アプリ トランスポート セキュリティ (ATS) が、インターネット リソース (アプリのバックエンド サーバーなど) とアプリ間にセキュリティで保護された接続を強制します。 さらに、ATS では、HTTPS
プロトコルを使用した通信と、TLS バージョン 1.2 を使用した高度な API 通信を前方秘匿性で暗号化する必要があります。
iOS 9 と OS X 10.11 (El Capitan) 用に構築されたアプリでは ATS が既定で有効になっているため、NSURLConnection
、CFURL
、または NSURLSession
を使用するすべての接続は ATS セキュリティ要件の対象となります。 接続がこれらの要件を満たしていない場合、例外が発生して失敗します。
また、Apple は、コンパイル (または必要に応じて Xamarin と C# にトランスコード) でき、ATS/TLS の問題の診断に使用できる、TLSTool サンプル アプリも提供しています。 この問題を解決する方法については、以下の「ATS のオプトアウト」セクションを参照してください。
ATS オプションの構成
ATS のいくつかの機能を構成するには、アプリの Info.plist ファイル内の特定のキーの値を設定します。 次のキーを使用して ATS を制御できます ("入れ子になっている様子を示すためにインデントされています")。
NSAppTransportSecurity
NSAllowsArbitraryLoads
NSAllowsArbitraryLoadsInWebContent
NSExceptionDomains
<domain-name-for-exception-as-string>
NSExceptionMinimumTLSVersion
NSExceptionRequiresForwardSecrecy
NSExceptionAllowsInsecureHTTPLoads
NSRequiresCertificateTransparency
NSIncludesSubdomains
NSThirdPartyExceptionMinimumTLSVersion
NSThirdPartyExceptionRequiresForwardSecrecy
NSThirdPartyExceptionAllowsInsecureHTTPLoads
各キーの種類と意味は次のとおりです。
- NSAppTransportSecurity (
Dictionary
) - ATS のすべての設定キーと値が含まれています。 - NSAllowsArbitraryLoads (
Boolean
) -YES
の場合、ATS がNSExceptionDomains
に記載されていないすべてのドメインで無効になります。 一覧表示されているドメインでは、指定されたセキュリティ設定が使用されます。 - NSAllowsArbitraryLoadsInWebContent (
Boolean
) -YES
の場合、引き続き Apple Transport Security (ATS) 保護がアプリの他の部分で有効な状態で、Web ページが正しく読み込まれます。 - NSExceptionDomains (
Dictionary
) - ドメインのコレクションと、ATS が特定のドメインに対して使用するセキュリティ設定。 - <domain-name-for-exception-as-string> (
Dictionary
) - 特定のドメイン (例:www.xamarin.com
) の例外のコレクション。 - NSExceptionMinimumTLSVersion (
String
) -TLSv1.0
、TLSv1.1
、またはTLSv1.2
(既定値) の最小 TLS バージョン。 - NSExceptionRequiresForwardSecrecy (
Boolean
) -NO
の場合、ドメインは前方秘匿性を使って暗号を使用する必要はありません。 既定値はYES
です。 - NSExceptionAllowsInsecureHTTPLoads (
Boolean
) -NO
(既定) の場合、このドメインとの通信はすべてHTTPS
プロトコルに含まれている必要があります。 - NSRequiresCertificateTransparency (
Boolean
) -YES
の場合、ドメインの Secure Sockets Layer (SSL) に有効な透過性データを含める必要があります。 既定値はNO
です。 - NSIncludesSubdomains (
Boolean
) -YES
の場合、これらの設定が、このドメインのすべてのサブドメインをオーバーライドします。 既定値はNO
です。 - NSThirdPartyExceptionMinimumTLSVersion (
String
) - ドメインが開発者の制御外のサード パーティサービスである場合に使用される TLS バージョン。 - NSThirdPartyExceptionRequiresForwardSecrecy (
Boolean
) -YES
の場合、サード パーティドメインに前方秘匿性が必要です。 - NSThirdPartyExceptionAllowsInsecureHTTPLoads (
Boolean
) -YES
の場合、ATS はサード パーティ ドメインとのセキュリティで保護されていない通信を許可します。
ATS のオプトアウト
Apple は、HTTPS
プロトコルを使用し、インターネットベースの情報への安全な通信を使用することを強く勧めていますが、これが常に可能ではない場合があります。 たとえば、サード パーティの Web サービスと通信している場合や、アプリでインターネット配信広告を使用している場合などです。
Xamarin.iOS アプリが安全でないドメインに対して要求を行う必要がある場合、アプリの Info.plist ファイルに対して次の変更を加えると、ATS が特定のドメインに強制するセキュリティの既定値群が無効になります。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>www.the-domain-name.com</key>
<dict>
<key>NSExceptionMinimumTLSVersion</key>
<string>TLSv1.0</string>
<key>NSExceptionRequiresForwardSecrecy</key>
<false/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
<key>NSIncludesSubdomains</key>
<true/>
</dict>
</dict>
</dict>
Visual Studio for Mac 内の ソリューション エクスプローラーで、Info.plist
ファイルをダブルクリックし、ソース ビューに切り替えて、上記のキーを追加します。
アプリがセキュリティで保護されていないサイトから Web コンテンツを読み込んで表示する必要がある場合は、アプリの Info.plist ファイルに次を追加して、Apple Transport Security (ATS) 保護がアプリの残りの部分で有効な間に Web ページが正しく読み込まれるようします。
<key>NSAppTransportSecurity</key>
<dict>
<key> NSAllowsArbitraryLoadsInWebContent</key>
<true/>
</dict>
必要に応じて、アプリの Info.plist ファイルに次の変更を加えて、すべてのドメインとインターネット通信の ATS を完全に無効にすることができます。
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Visual Studio for Mac 内の ソリューション エクスプローラーで、Info.plist
ファイルをダブルクリックし、ソース ビューに切り替えて、上記のキーを追加します。
重要
アプリケーションでセキュリティ保護されていない Web サイトへの接続が必要な場合は、NSAllowsArbitraryLoads
を使用して ATS を完全にオフにするのではなく、常にNSExceptionDomains
を使って例外としてドメインを入力する必要があります。 NSAllowsArbitraryLoads
は極めて緊急の場合にのみ使用する必要があります。
ここでも、セキュリティで保護された接続への切り替えが使用できないか実用的でない場合は、ATS を無効にするのは、最後の手段としてのみ使用する必要があります。
まとめ
この記事では、アプリ トランスポート セキュリティ (ATS) について説明し、インターネットとのセキュリティで保護された通信を強制する方法について説明しました。 最初に、iOS 9 で実行されている Xamarin.iOS アプリに対して ATS に必要な変更について説明しました。 その後、ATS の機能とオプションの制御について説明しました。 最後に、Xamarin.iOS アプリでの ATS のオプトアウトについて説明しました。