React Native で Secure Storage
RNでSecureなデータをStorageに入れて取り扱いたい。
ユーザーからのセキュアなインプットを前提とすれば、データはほぼ安全に保存することが出来る。ここでいうインプットは、パスワードや生体認証など。
だが、こういったインプットがなくコード上でだけでセキュアにデータを取り扱うのは自分の知る限りだと不可能でどこまでセキュリティを許容するか、になりそう。
まず、データを格納するストレージのセキュリティ性については問題はなさそう。AsyncStorageはunsecureでencryption系の処理がなにもない状態でデータが保持されているので、Secureなデータの保持はexpo-secure-storageなどを使う。
問題は、ユーザーインプットでなくハードコードされた情報だけで実現しようとすると、ストレージへデータ保存するときのKeyもハードコートされてしまうこと。
たとえば、expo-secure-storeの場合はKVSのKeyがハードコートされていることになるし、react-native-mmkvの場合はconstructorで渡すencryptionKey+KVSのKeyがハードコートされていることになる。
ストレージ自体のセキュリティが高くても鍵自体がハードコートされているのでその情報をもとにリークしてしまう。RNの場合はクライアントコードはすべて開示されてしまうので、これを暗号化することは出来ない。
react-native-mmkv
- mmkvのラッパー。
- 内部実装はmmkvを依存してて、react-native-mmkv はただのwrapperなので暗号化やセキュアの仕組みについてはノータッチみたい。
- https://github.com/mrousavy/react-native-mmkv/issues/409#issuecomment-1306903419
- mmkv
- iOS:
- Android:
-
react-native-storage-mmkv
もあるがメンテ的にちょっと懸念がありそう。- https://github.com/mrousavy/react-native-mmkv/issues/100#issuecomment-1043976088
- こっちはiOSはkeychainらしい。
expo-secure-storage
- nativeのセキュアな機能のラッパー
- iOS: Keychain Services
- Android: SharedPreferences + Android Keystore system
- KVSだが、Keyが文字通りに鍵となる?
Storage はセキュアだけど、データの出し入れを行うKeyをどうセキュアに扱うのか
Client のコードは基本的にすべてリークされており、特にRNの場合もJSのバンドルにPlainTextでコード内容をすべて確認できる。
そのため、Storageの機能としてセキュアであってもそこへのデータの出し入れを行うKey自体がハードコートされていたらNGなのでは?
keyをgenerateする
react-native-mmkv
のissueなどを見てると、このkeyをinputにして動的に扱っているケースをいくつか見かけた。
- https://github.com/mrousavy/react-native-mmkv/issues/462#issue-1406147910
- https://github.com/mrousavy/react-native-mmkv/issues/435#issuecomment-1196770624 (maintainerの実コードでも)
なので、おそらくこれが一番良い。
静的なkeyでもOK?
ただ、maintainerのコメントでenvから展開されたコードでもsafeだって言ってる。あれ、それって結局バンドルされたらPlainTextなのでリークされちゃうのでは。さっきと言ってることが違うのでは。。。
- https://github.com/mrousavy/react-native-mmkv/issues/565#issuecomment-1658073180