IOSアプリケーションのセキュリティ保護について話すとき、秘密、鍵、トークン、encryptionKeyなどの最も重要な機密情報の保護を忘れることがよくあります。この情報はiOSバイナリに保存されます。したがって、サーバー側のセキュリティプロトコルはどれも役に立ちません。
そのような情報をアプリに保存するのではなく、サーバーに保存して、SSLで保護されたWebサービス呼び出しを介して取得するべきだという多くの提案があります。しかし、これはすべてのアプリケーションで可能ではありません。例えば。アプリケーションがWebサービスをまったく必要としない場合。
IOSアプリでは、情報を保存する次のオプションがあります。
親切にこの問題にいくつかの素晴らしい解決策を送ってください。
独自のバックエンドを使用したくない場合は、Appleを使用してください。オンデマンドリソースを設定し、キー、トークン、任意のシークレットを含むデータファイルをAppleサーバー上に保持できます。最初のダウンロード後、このデータを十分に安全なキーチェーンに書き込むことができます。私は推測していますiOSとAppleサーバー間のネットワーキングも十分に安全です。
1)インターネット接続が必要です
1.1)プッシュ通知安全なデータ交換を行うための優れた方法は、Appleの(サイレント)プッシュサービスを使用することです。それらは、apnsを使用してhttps経由でデータを送信します-詳細3.1
1.2)アプリケーションを再インストールする機会がなく、アプリケーションが有効なインターネット接続を必要とする場合、新しいユーザー証明書を既に展開されているアプリケーションに配布するときにも、ほぼ同じようなアプローチが使用されますとにかく。
欠点:動作中のネットワーク接続が必要であり、基本的に情報がアプリケーションに送信され、すでに実行されている場合=>は、あなたのケースには適切ではないようです。 (ステップ4を参照)
2)静的データ(ネットワーク接続/通信パートナーなしでは交換は行われないため)
バンドル自体で提供される秘密鍵によるデータの暗号化。それが文字列であるかハッシュであるかに関係なく、アプリケーションに埋め込まれた関数を使用してリバースエンジニアリングすることができます。 iOS9以降、iOSアプリケーションを逆コンパイルするのはかなり難しく、基本的には提供されたヘッダーファイルを主に調べます。したがって、そのような関数、文字列、ハッシュ値などがある場合は、それを.mファイルで取得してください。
ただし、情報がデバイスまたはユーザーに固有ではなく、独自のマイクロ環境全体のシークレットであり、すべてのデバイスで有効である場合、更新プロセスがない場合は、暗号化されたデータと復号化メソッドを同じバンドルで提供する必要があります。 /情報交換か何か、あなたは考えることができます。
暗号化に最適:iOS System.Security https://developer.Apple.com/reference/security または単にopenssl
説明したキーチェーンアプローチの違いは次のとおりです。値が得られ、暗号化されて安全に保存されます。 (2)暗号化されて保存された(バンドルで)半安全な値を持ち、復号化される方法を説明します
3)情報交換
別のインスタンスによってハッシュされた重要なデータについて説明します。すごい! -確認していること、比較的確認していること、話しているインスタンスが実際に想定しているインスタンスであることを確認してください(ssl証明書のピン留めなどによるネットワークフッキングの防止ですが、ここでも侵入者(中間者)がいる可能性があります)。そして、(おそらく)証明書がアプリケーションバンドルで提供されて、通信サーバーの信頼性を保証します。ここで再び、マイクロ環境の特定のインスタンス間の安全なプロセスを保証することになっているデータを使用します。それにもかかわらず、このデータはアプリケーションのバンドルで提供されています。
3.1安全な情報交換の拡張-サイレントプッシュAppleのサーバーを利用して、この目的のために秘密を交換します。小さなデータチャンクだけを交換する必要がある場合。ユーザーにはサイレントプッシュ通知を使用することをお勧めします。これらはユーザーからの明示的な許可なしでも機能します。大きな利点:シークレットまたはキーが変更された場合、変更についてできるだけ早くユーザーに通知できます。彼らが変更を必要とするのは、ほとんどの場合確実に機能する新しいデータを受け取ったときだけです。例外:ローカルネットワークまたはBluetoothを介したデータ交換。この場合、ローカルの復号化キーを更新する必要があることをユーザーに通知することをお勧めします。または、この形式で鍵も交換します。もう一度:私はあなたの環境アーキテクチャに関するいくつかの詳細な情報を漏らしています。欠点:ユーザーがアプリを初めて使用したかどうかは、ユーザーが「教える」まではわかりません。 https://developer.Apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/APNSOverview.html#//Apple_ref/doc/uid/TP40008194-CH8-SW1
3.1安全な情報交換の拡張-アプリ内購入ユーザーがアプリ内購入を使用して、データを携帯電話に取得します。ここでの利点:これはユーザーによるアクティブなリクエストであり、ユーザーは特定の処理時間を期待していることと、機能するインターネット接続が必要であることを認識している必要があるため、大きなデータチャンクを簡単に提供できます。欠点:意図的にこれを選択する必要があります。それまでは、アプリは正常に動作しませんでした。 https://developer.Apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction.html#//Apple_ref/doc/uid/TP40008267
したがって、アプローチ(2)とは基本的な考え方が少し異なります。
要約すると、追加情報、安全に保存するために暗号化/必要なデータの種類、およびネットワーク交換を行うかどうかを提供できますか?
ここにいくつかの詳細情報が必要でしょう:-)
IOS上のアプリケーションは、解読するのがそれほど簡単ではないことをもう一度強調したいと思います。逆コンパイルしてもすべてが得られるわけではありません。たとえば、dumpdecryptなどの復号化ツールは、iOS 8.4までしか正しく機能しませんでした。
これを行う最良の方法は、組み込みのCloudKitを使用することです。 CloudKit Dashboardにシークレットを保存して、起動時にそれらをフェッチできます。 CloudKitはトランスポート層にすぎないため、アプリのシークレットをKeyChainに保存する必要があります。
KeyChainがユースケースに理想的ではない(理由がわからない)とのことですが、これはアプリにシークレットを含めないための良い方法です。別のソースからアプリのシークレットを取得することはできません。
CloudKitアクセスはシステムのiCloudアカウントを使用して保護されます。iCloudアカウントがない場合でも、iCloudサーバーに安全にアクセスできます。これのもう1つの利点は、いつでもアプリのシークレットを変更できるため、さらに安全性を高めたい場合は、ローテーションスケジュールを実装できることです。
私は@Lobstermanに同意し、これらの組み合わせを使用するのが最善の方法であると信じています。
Cocoapods-keys
が最適なオプションです。
cocoapods-keys
ドキュメントから
キー名は、OS Xキーチェーンの〜/ .cocoapods/keys /およびキー値に保存されます。ポッドインストールまたはポッド更新を実行すると、Objective-Cクラスがキーのスクランブルバージョンで作成されるため、復号化されたバイナリのコンテンツをダンプしてキーを抽出するだけでは困難になります。実行時に、アプリで使用するためにキーがスクランブル解除されます。
生成されたObjective-CクラスはPods/CocoaPodsKeysディレクトリに保存されるため、Podsフォルダーをチェックインする場合は、Pods/CocoaPodsKeysを.gitignoreファイルに追加するだけです。 CocoaPods-Keysは、SwiftまたはObjective-Cプロジェクトでの統合をサポートしています。
インストール、使用法、および詳細については、このリンクを確認してください: https://github.com/orta/cocoapods-keys
データの機密性が非常に高い場合、すべてのデバイスがクラック可能であるため、デバイスにオフラインで保存しないでください。それでもデバイスに保存したい場合は、キーチェーンはデータを安全に保存するための1つのオプションですが、暗号化はデバイスのPINコードに基づいています。ユーザーはピンの設定を強制されないため、状況によってはデータが暗号化されない場合もあります。さらに、ユーザーのPINコードは簡単にハッキングされる可能性があります。
より良い解決策は、完全に暗号化されたSQLiteデータベースである SQLCipher のようなものを使用することです。暗号化キーは、アプリケーションによって強制され、ユーザーのPINコードとは別にできます。