我正在构建一个React Native应用程序,我需要保存一些敏感数据,如令牌和刷新令牌 . 显而易见的解决方案是使用AsyncStorage保存该信息 . 问题是AsyncStorage的安全级别 .
AsyncStorage提供了一种本地存储令牌和数据的方法 . 在某些方面,它可以与LocalStorage选项进行比较 . 在完整的 生产环境 应用程序中,建议不要直接访问AsyncStorage,而是使用抽象层,因为AsyncStorage与使用相同浏览器的其他应用程序共享,因此从存储中删除所有项目的不当可能会影响相邻应用程序的功能 .
https://auth0.com/blog/adding-authentication-to-react-native-using-jwt/
在本机应用程序中,我会在 iOS
中查找 Keychain
,在 Android
中查看 private mode 中的 Shared Preferences
.
对于我在React Native提供的文档中读到的内容:
在iOS上,AsyncStorage由本机代码支持,该代码将小值存储在序列化字典中,将较大值存储在单独的文件中 . 在Android上,AsyncStorage将根据可用内容使用RocksDB或SQLite .
https://facebook.github.io/react-native/docs/asyncstorage.html
他们从不谈论数据的安全性 .
这是为 Android
(在 private mode 中使用 Shared Preferences
)创建模块的最佳解决方案,为 iOS
(使用 Keychain )创建另一个模块来保存敏感数据?或者使用提供的 AsyncStorage
方法是否安全?
4 回答
AsyncStorage
将键值对保存为Documents目录中的纯文本JSON文件 . It does not encrypt its contents .这是一个安全问题(至少在iOS上),因为有权访问设备的攻击者可以获取沙箱内容的转储,并且可以轻松提取通过
AsyncStorage
保存的任何数据 .以前在AsyncStorage.js的文档中没有明确说明,但它现在是:https://github.com/facebook/react-native/pull/8809
另见:https://stackoverflow.com/a/38398114/1072846
刚刚深入研究React Native代码,我找到了答案 .
Android
React Native
AsyncStorage
模块实现基于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文档,应用程序创建的数据库保存在与关联应用程序相关的专用磁盘空间中,因此它是安全的 .
Source
iOS
在iOS中,
AsyncStorage
值保存在序列化字典文件中 . 这些文件保存在应用程序NSDocumentDirectory
中 . 在iOS中,所有应用程序都存在于 their own sandbox 中,因此一个应用程序的所有文件都是安全的,其他应用程序无法访问它们 .可以在此处找到处理
AsyncStorage
模块的iOS代码:https://github.com/facebook/react-native/blob/master/React/Modules/RCTAsyncLocalStorage.m我们可以看到here用于存储
AsyncStorage
保存的值的文件保存在NSDocumentDirectory
(在应用程序沙箱环境中) .Source
Conclusion
使用
AsyncStorage
来保存用户令牌是安全的,因为它们是在安全的上下文中保存的 .请注意,这仅适用于没有 root 的Android设备和没有 jailbreak 的iOS设备 . 另请注意,如果攻击者对设备有 physical access 且设备未受保护 . 他可以将设备连接到mac笔记本电脑和extract the documents目录,并查看文档目录下保存的所有内容 .
我真的建议你使用像react-native-keychain这样的库来存储react-native中的私人数据
对于Android API级别:
16-22使用Facebook Conceal
23使用Android Keystore
你可以像这样使用它:
如果有人想要加密数据的额外步骤,您可能需要查看:https://github.com/oblador/react-native-keychain
它在内部使用facebook conceal .