Android https カスタム証明書の問題

https://my.oschina.net/AliMobileSecurity/blog/755304 から転載


要約: ユーザーの情報セキュリティを保護し、ユーザー自身の商業的利益を保護し、攻撃対象領域を減らすためには、通信チャネルのセキュリティを確保する必要があります。開発が簡単な HTTPS を使用する方が良い方法です。プライベート プロトコルを使用するよりも優れており、時間と労力を節約できます。

1. HTTPS の概要

Aliju Securityのアプリケーション脆弱性スキャナーには、APPがHTTPS通信を使用する場合にリスクが発生しやすい箇所を対象に、証明書の脆弱性検証、ホスト名の脆弱性検証、WebViewの未検証証明書の検出項目が用意されています。次に、HTTPSを安全に利用するための関連コンテンツを紹介します。

1.1 HTTPS が必要な理由

HTTPプロトコルは暗号化を行わない平文の送信プロトコルであるため、APPがHTTPを利用してデータを送信すると、送信内容が漏洩したり、仲介者に乗っ取られて送信内容が改ざんされる可能性があります。以下の図に示すように、典型的な APP HTTP 通信はオペレータによってハイジャックされ、広告を挿入するために変更されます。

上の写真は私の自宅です WiFiでアプリを開くとページ下部に赤い封筒の開封の広告が表示されます クリックするとアプリのインストールページが表示されます チャイナユニコムの4Gネットワ​​ークを使用している場合これは、コミュニティ オペレータが HTTP 通信をハイジャックし、APP の通信に独自のプロモーション コンテンツや、いくつかの低俗なプロモーション広告を追加したことを示しており、ユーザー エクスペリエンスに大きな影響を与えています。不純な動機を持つ一部の人々は、公共 WiFi を構築し、トラフィックをハイジャックし、盗聴することにより、HTTP 経由で送信される機密情報を入手する可能性があります。

ユーザーの情報セキュリティを保護し、ユーザー自身の商業的利益を保護し、攻撃対象領域を減らすためには、通信チャネルのセキュリティを確保する必要があります。開発が簡単な HTTPS を使用する方が良い方法です。プライベートプロトコルを使用するため、時間と労力を節約できます。ただし、HTTPS が不適切に使用されると、望ましい保護効果を達成することが困難になります。Wuyun 上で Android HTTPS の不適切な使用によって引き起こされるリスクの例は、wooyun-2010-079358、wooyun-2010-081966、wooyun-2010-080117 など多数あるので、興味があれば探してみてください。

1.2 HTTPS通信原理

HTTPS は HTTP over SSL/TLS、HTTP はアプリケーション層プロトコル、TCP はトランスポート層プロトコルです。アプリケーション層とトランスポート層の間に、セキュア ソケット層 SSL/TLS が追加されます。

SSL/TLS 層は、暗号化および復号化アルゴリズムのネゴシエーション、キー交換、およびクライアントとサーバー間の通信接続の確立を担当します。安全な接続を確立するプロセスは次のとおりです。

HPPTS ハンドシェイク プロトコルには多くのコンテンツがあります。分析のためにパケットをキャプチャするために Wireshark を使用することをお勧めします。スペースの制限があるため、ここではこれ以上説明しません。

2.HTTPSの使用方法

2.1 デジタル証明書、CA、HTTPS

情報セキュリティの基盤は暗号化に依存しています。暗号化にはアルゴリズムとキーが関係します。アルゴリズムは一般に公開されており、キーは適切に保護される必要があります。キーの生成、配布、使用、および回復方法には、公開キー インフラストラクチャが関係します。

公開キー基盤 (PKI) は、ハードウェア、ソフトウェア、アクター、管理ポリシーと手順で構成される一連のインフラストラクチャであり、その目的は、デジタル証明書を作成、管理、配布、使用、保存、失効させることです。公開キーはデジタル証明書に保存され、標準デジタル証明書は通常、信頼できるデジタル証明書認証局 (CA、ルート認証局) によって発行され、この証明書はユーザーの ID と公開キーを関連付けます。CA は、発行する各証明書のユーザー ID が固有であることを確認する必要があります。

リンク関係 (証明書チェーン) は、登録および発行プロセスを通じて作成されます。保証レベルに応じて、リンク関係は CA のさまざまなソフトウェアによって、または人間の監督下で完了する場合があります。リンク関係を決定する PKI の役割は、登録局 (RA、中間認証局または中間局とも呼ばれます) と呼ばれます。RA は、公開キーと個人 ID が確実にリンクされるようにするため、否認を防ぐことができます。RA が存在しない場合、CA のルート証明書が破損または漏洩し、CA が発行する他の証明書の安全性が失われるため、主流の商用デジタル認証局 CA は通常 3 レベルの証明書を提供し、ルート証明書は中間 RA によって発行される証明書、RA 証明書によって発行されるユーザーが使用する証明書。

X509 証明書チェーン。左側は CA ルート証明書、中央は RA 中間機関、右側はユーザーです。

www.google.com.hk Web サイトの証明書チェーンは次のとおりです。CA 認証局は GeoTrust Global CA、RA 局は Google Internet Authority G2、Web サイト証明書は *.google.com.hk です。

HTTPS 通信で使用される証明書は CA によって提供され、有効にするにはサーバーに設定する必要があります。さらに、当社のクライアント デバイスでは、アクセスした HTTPS Web サイトで使用される証明書が信頼できる CA ルート証明書によって発行されている限り、これらの CA がブラウザまたはオペレーティング システムのルート信頼リストに含まれていれば、直接アクセスできます。 .cn Web サイトでは、その証明書は信頼されていない CA によって提供され、独自に発行されるため、Google Chrome で開くと、「接続はプライベート接続ではありません」というメッセージが表示され、証明書は非信頼の CA によって発行されます。信頼できる CA:

したがって、12306.cn Web サイトのホームページでは、チケットの購入をスムーズに行うために、そのルート証明書をダウンロードしてインストールするように求めるプロンプトが表示されますが、オペレーティング システムがインストールされると、上の図のようなプロンプトは表示されなくなります。

2.2 独自の電子証明書の生成

HTTPS Web サイトで使用される証明書は、信頼できる CA 機関から申請できます。ただし、このカテゴリは基本的に営利組織です。証明書の申請には通常、年単位で料金が必要です。料金は CA 機関によって異なります。APP のみが HTTPS 経由でバックグラウンド サーバーと通信する場合、openssl ツールを使用して自己署名デジタル証明書を生成できます。これによりコストを節約できますが、証明書の秘密キーは適切に保護されている必要があり、漏洩したり紛失したりしてはなりません。HTTPS 通信で使用されるデジタル証明書の形式は X.509 です。

自己署名デジタル証明書の作成手順は次のとおりです。

Step1 独自の CA ルート証明書を生成する

CA 秘密鍵ファイル ca.key を生成します: openssl genrsa -out ca.key 1024

X.509 証明書署名要求ファイル ca.csr を生成します: openssl req -new -key ca_private.key -out ca.csr

ca.csr を生成する過程で、いくつかの組織情報が入力されます。

CA ルート証明書 ca_public.crt (公開鍵証明書) を X.509 形式で生成します: openssl x509 -req -in ca.csr -signkey ca_private.key -out ca_public.crt

Step2 サーバー証明書の生成

サーバー秘密鍵ファイルserver_private.keyを生成します: openssl genrsa -out server_private.key 1024

サーバーの秘密鍵に従ってサーバーの公開鍵ファイルserver_public.pemを生成します: openssl rsa -in server_private.key -pubout -out server_public.pem

サーバー側は、CA 組織からの署名証明書を申請する必要があります。署名証明書を申請する前に、独自の証明書署名要求ファイル server.csr を作成します: openssl req -new -key server_prviate.key -out server.csr

HTTPS に使用される CSR の場合、後続のホスト名検証のために共通名が Web サイトのドメイン名と一致している必要があります。

サーバーは、server.csr ファイルを使用して CA からの証明書を申請します。署名プロセスには CA の公開キー証明書と秘密キーの参加が必要で、最後に CA 署名付きのserver.crt を発行します: openssl x509 -req - CA ca_public.crt - CAkey ca_private.key -CAcreateserial -inserver.csr -outserver.crt

サーバーが引き続きクライアントの証明書を検証したい場合は、サーバー証明書を生成する形式でクライアント証明書を生成できます。

openssl を使用して証明書情報を表示します: openssl x509 -in server.crt -text -noout

web.py を使用して、単純なサーバー テストで生成された server.crt を構築します。ファイル webpytest.py は次のとおりです。

Web サーバー プログラムをローカルで実行します: python webpytest.py 1234

Safari ブラウザに https://0.0.0.0:1234 と入力すると、証明書が無効である (ホスト名が一致しない) というメッセージが表示されます。これは、サーバー側の証明書署名要求ファイル server.csr を生成するときに共通名が入力されるためです。 localhost として、0.0.0.0 と一致しません:

safari ブラウザに https://localhost:1234 と 入力すると、ホスト名が一致しないというプロンプトは表示されなくなりますが、この証明書はプライベート CA によって発行された証明書であるため、不明な機関によって署名されているというプロンプトが表示されます。 CA がブラウザまたはオペレーティング システムのルート信頼リストに存在しません。

次のコマンドを使用して Web サイトの証明書情報を表示することもできます: openssl s_client -connect localhost:1234

サーバーは正常に構築されました。次に、Android クライアントが HTTPS を介してサーバーと通信する方法について説明します。

2.3 HttpsURLConnectionを使用したHTTPS通信

Android の公式 Web サイトには、HTTPS にアクセスするために HttpsURLConnection API を使用する Web サイトの例が示されています。

この方法の特徴:

  • Android システムはサーバーの電子証明書の正当性を検証するため、信頼できる CA が発行した電子証明書を持つ Web サイトのみに正常にアクセスでき、プライベート CA が発行した電子証明書を持つ Web サイトにはアクセスできません。

  • ユーザーのデバイスに証明書をインストールする (デバイスの信頼リストに中間者サーバーの証明書を入れる) ことによって中間者攻撃を防御することはできません。このタイプの攻撃は通常、対話を分析するために使用されます。アプリケーションとサーバー間のプロトコルを変更し、アプリケーションとサーバー内の他の脆弱性を見つけます。

  • Web サイトでサイト全体の SSL (HTTPS のみを使用) または HSTS (HTTP Strict Transport Security) が有効になっていない場合、SSL ストリップ (HTTPS を HTTP にダウングレード) 攻撃や、無料 WiFi などの LAN 攻撃を防御できません。

プライベート CA によって発行された証明書を使用する場合は、検証証明書チェーン TrustManager のメソッドを書き換える必要があります。そうしないと、javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anker forcertificate path not found が発生します。現れる。しかし、多くの開発者は、TrustManger の checkServerTrusted() を書き換える際に何もしなかったので、証明書の検証が不十分になる (証明書の実際の検証が行われない) ことになります。

以下は間違った書き方です。

正しい書き方は、TrustManger の checkServerTrusted() を実際に実装するか、サーバー証明書のドメイン名の強力な検証を実行するか、HostnameVerifier の verify() メソッドを実装することです。

実際に TrustManger を実装する checkServerTrusted() のコードは次のとおりです。

このうちserverCertはAPPに組み込まれているサーバー側の公開鍵証明書で、ファイル形式の場合は以下の形式で取得できます。

サーバー証明書のドメイン名に対して強力なチェックを実行します。

HostnameVerifier の verify() メソッドを実現します。

証明書の固定を作成するもう 1 つの方法は、埋め込み証明書を直接使用して TrustManger を生成することです。プロセスは次のとおりです。

パラメーター certStream は、証明書ファイルの InputSteam ストリームです。

さらに、次のコマンドを使用してサーバー証明書の公開キーを表示できます。

keytool -printcert -rfc -file uwca.crt

直接コピーして貼り付けると、コード内の公開鍵情報をハードコーディングできます。

この公開キーに対応する X.509 証明書は、次の形式で取得できます。

2.4 HTTPS通信にOKHttp3.0を使用する

HTTPS 通信のために Android システムによって提供される HttpsURLconnection を使用することに加えて、使用できる他のサードパーティ ライブラリがあります。OKhttp3.0 を例として、まず、未検証のサーバー側証明書チェーンの間違った記述を確認し、未検証のサーバー側証明書ドメイン名:

これらのエラーの発生は実際には HttpsURLConnection の発生と同じであり、両方とも SSLContext と HostnameVerifier が関係します。セキュリティ アプリケーション スキャナはこれらの潜在的なリスク ポイントをスキャンでき、解決策はセクション 2.3 と同じです。HttpsURLConnection を使用することは、 TrustManager と HostnameVerifier を実際に実装する方法。

2.5 WebviewのHTTPSセキュリティ

現在、多くのアプリケーションは WebView を使用して H5 ページをロードしています。サーバーが信頼できる CA によって発行された証明書を使用している場合は、webView.setWebViewClient(webviewClient) のときに WebViewClient の onReceivedSslError() をオーバーロードします。証明書エラーが発生した場合は、handler.proceed() を直接呼び出します。はエラーを無視し、問題のある証明書を含むページのロードを続行します。handler.cancel() を呼び出すと、問題のある証明書を含むページのロードを停止できます。証明書に問題がある場合は、ユーザーにリスクを通知し、セキュリティ レベルが必要な場合 セキュリティ レベルが比較的高い場合は、ページの読み込みを直接終了することができ、ネットワーク環境が危険であることをユーザーに通知するメッセージが表示されます。

Jusafe のアプリケーション セキュリティ スキャナは handler.proceed() が直接呼び出されるケースをスキャンするため、handler.proceed() を直接使用することはお勧めできません。

Web ビューが HTTPS をロードし、サーバー証明書の強力な検証が必要な場合は、HttpsURLConnection の強力な検証証明書を使用して、onPageStarted() でサーバー証明書を検証できます。検証が失敗した場合は、Web ページのロードを停止します。もちろん、これにより Web ページの読み込み速度が低下するため、さらなる最適化が必要になりますが、具体的な最適化方法についてはこの説明の範囲外であるため、ここでは詳しく説明しません。

3. Aliju Security から開発者へのアドバイス

Aliju Security の脆弱性スキャナーにより、多くのアプリに HTTPS が不適切に使用されるリスクがあることが判明しました。HTTPS を適切に使用すると、ユーザーのデバイスに証明書をインストールすることで、中間者攻撃や SSL ストリップ攻撃を効果的に防ぐことができます。

ただし、上記の方法はすべて、クライアントに証明書ファイルを事前に埋め込むか、コードに証明書をハードコーディングする必要があるため、サーバー側の証明書の有効期限が切れたり、漏洩などの理由で証明書を置き換える必要がある場合は、ユーザーが次の手順を実行する必要があります。クライアントのアップグレードを強制されるため、経験効果は良くありません。Aliju Security は、この問題を完全に解決できるセキュリティ コンポーネントをリリースしました。APP 開発者は、セキュリティ コンポーネントに公開キーを設定するだけでよく、セキュリティ コンポーネントの動的キー機能により、公開キーの動的アップグレードを実現できます。

また、HTTPSを正しく利用したからといってクライアントのHook解析や改ざんを完全に防ぐことはできず、通信のセキュリティを確保するには、重要な情報を暗号化してHTTPS通信に送信したり、署名処理を実装したりするなどの別の手段も必要となります。顧客がクライアントとサーバー間の通信要求を偽造できないことを保証するためのクライアント要求の数。現在、Aliju Security のセキュリティ コンポーネントは、安全なストレージ、シミュレータ検出、人間とマシンの識別などの機能に加えて、上記のすべての機能をすでに備えています。セキュリティコンポーネントは、クライアントモジュールをリアルタイムに更新し、攻撃と防御の強度を確保する機能も備えています。

4、参考

[1] サバイバル ガイド - TLS/SSL および SSL (X.509) 証明書、http://www.zytrax.com/tech/survival/ssl.html

[2] 公開鍵インフラストラクチャ、https://en.wikipedia.org/wiki/Public_key_infrastruction

[3]  http://www.barretlee.com/blog/2015/10/05/how-to-build-a-https-server/

[4] HTTPS と SSL によるセキュリティ、https://developer.android.com/training/articles/security-ssl.html

[5] 盗聴の嵐: Android プラットフォームの https スニッフィング ハイジャックの脆弱性、http://www.freebuf.com/articles/terminal/26840.html

[6] Android HTTPS 中間者ハイジャックの脆弱性の分析、https://jaq.alibaba.com/blog.htm?id=60

[7] HTTPS 中間者攻撃と証明書の検証の分析、http://www.evil0x.com/posts/26569.html

[8]  https://github.com/menjoo/Android-SSL-Pinning-WebViews

[9]  https://github.com/square/okhttp/wiki/HTTPS

[10]  https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/CustomTrust.java

5. Android セキュリティ開発シリーズ

目次

Android セキュリティ開発の一般的な特徴的なリスク

Android セキュリティ開発のための ZIP ファイル ディレクトリ トラバーサル

Android セキュリティ開発のためのプロバイダー コンポーネント セキュリティ

Android セキュリティ開発における主要なハードコーディングについて語る

Android のセキュリティ開発について語る Web ページのアプリを開く

暗号化アルゴリズムのピットでの Android アプリケーションのセキュリティ開発

著者: Yiqiao @ Ali Ju Security 、Android および iOS のセキュリティ テクノロジに関する記事については、 Ali Ju Security Blogをご覧ください。





おすすめ

転載: blog.csdn.net/qq_19822039/article/details/53333512