Reactネイティブアプリケーションを構築しています。トークンや更新トークンなどの機密データを保存する必要があります。明らかな解決策は、 AsyncStorage を使用してその情報を保存することです問題は、AsyncStorageのセキュリティレベルです。
AsyncStorageは、トークンとデータをローカルに保存する方法を提供します。 LocalStorageオプションと比較すると、いくつかの点で異なります。完全な実稼働アプリケーションでは、AsyncStorageに直接アクセスしないことをお勧めしますが、AsyncStorageは同じブラウザーを使用して他のアプリと共有されるため、抽象レイヤーを使用することをお勧めします。近隣のアプリの機能。
https://auth0.com/blog/adding-authentication-to-react-native-using-jwt/
ネイティブアプリでは、Keychain
のiOS
とShared Preferences
inprivate modein Android
。
React Native:
IOSでは、AsyncStorageはネイティブコードによってサポートされており、シリアルコード化された辞書に小さな値を格納し、別のファイルに大きな値を格納します。 Androidでは、AsyncStorageは利用可能なものに基づいてRocksDBまたはSQLiteを使用します。
https://facebook.github.io/react-native/docs/asyncstorage.html
彼らはそのデータのセキュリティについて決して話しません。
Android
のモジュールを作成する最適なソリューションです(Shared Preferences
inprivate mode)および別のiOS
(Keychainを使用)が賢明なデータを保存しますか?または、提供されているAsyncStorage
メソッドを使用しても安全ですか?
React Nativeコードを掘り下げて、答えを見つけました。
Android
React Native
AsyncStorage
moduleの実装は、SQLiteOpenHelper
に基づいています。すべてのデータクラスが処理されるパッケージ: https://github.com/facebook/react-native/tree/master/ReactAndroid/src/main/Java/com/facebook/react/modules/storage
データベースを作成する手順を含むクラス: https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/Java/com/facebook/react/modules/storage/ ReactDatabaseSupplier.Java
Androidドキュメンテーションにより、アプリケーションによって作成されたデータベースは、関連付けられたアプリケーションのプライベートディスク領域に保存されるため、安全です。
デバイスの内部ストレージに保存するファイルと同様に、Androidはデータベースを関連アプリケーションのプライベートディスクスペースに保存します。デフォルトではこの領域は他のアプリケーションからアクセスできないため、データは安全です。
iOS
IOSでは、AsyncStorage
値はシリアル化された辞書ファイルに保存されます。これらのファイルはアプリケーションNSDocumentDirectory
に保存されます。 iOSでは、すべてのアプリケーションは独自のサンドボックスにあるため、1つのアプリケーションのすべてのファイルは保護され、他のアプリケーションからはアクセスできません。
AsyncStorage
モジュールを処理するiOSのコードは、次の場所にあります。 https://github.com/facebook/react-native/blob/master/React/Modules/RCTAsyncLocalStorage.m =
ご覧のとおり、 hereAsyncStorage
によって保存された値を保存するために使用されるファイルは、NSDocumentDirectory
(アプリケーションサンドボックス環境内)の下に保存されます。
すべてのアプリは島ですiOSアプリのファイルシステムとのやり取りは、アプリのサンドボックス内のディレクトリにほとんど制限されています。新しいアプリのインストール中に、インストーラーはアプリ用のコンテナをいくつか作成します。各コンテナには特定の役割があります。バンドルコンテナはアプリのバンドルを保持しますが、データコンテナはアプリケーションとユーザーの両方のデータを保持します。データコンテナーは、アプリがデータの並べ替えと整理に使用できるいくつかのディレクトリにさらに分割されます。アプリは、実行時に追加のコンテナ(iCloudコンテナなど)へのアクセスを要求することもあります。
結論
ユーザートークンは安全なコンテキストで保存されるため、AsyncStorage
を使用してユーザートークンを保存しても安全です。
これはAndroidデバイスがrootなしで、iOSデバイスがjailbreak。また、攻撃者がデバイスに物理アクセスを持ち、デバイスが保護されていない場合、デバイスをMacラップトップに接続し、 抽出するdocuments ディレクトリとドキュメントディレクトリの下に保存されているすべてのコンテンツを参照してください。
AsyncStorage
は、キーと値のペアをプレーンテキストJSONファイルとしてDocumentsディレクトリに保存します。 コンテンツを暗号化しません。
これはセキュリティの問題です(少なくともiOSでは)。デバイスにアクセスできる攻撃者は、サンドボックスの内容のダンプを取得し、AsyncStorage
を介して保存されたデータを簡単に抽出できるためです。
これは、AsyncStorage.jsのドキュメントに明確に記載されていませんでしたが、現在は https://github.com/facebook/react-native/pull/8809 です。
誰かがデータを暗号化するという追加のステップが必要な場合は、次をご覧ください。 https://github.com/oblador/react-native-keychain
内部で facebook conceal を使用します。
react-native-keychain のようなライブラリを使用して react-native にプライベートデータを保存することをお勧めします
Android APIレベル:
次のように使用できます。
// Generic Password, service argument optional
Keychain
.setGenericPassword(username, password)
.then(function() {
console.log('Credentials saved successfully!');
});
// service argument optional
Keychain
.getGenericPassword()
.then(function(credentials) {
console.log('Credentials successfully loaded for user ' + credentials.username);
}).catch(function(error) {
console.log('Keychain couldn\'t be accessed! Maybe no value set?', error);
});