在 React Native 中保存敏感数据
Posted
技术标签:
【中文标题】在 React Native 中保存敏感数据【英文标题】:Save sensitive data in React Native 【发布时间】:2016-12-26 00:10:58 【问题描述】:我正在构建一个 React Native 应用程序,我需要保存一些敏感数据,例如令牌和刷新令牌。显而易见的解决方案是使用AsyncStorage 保存该信息。问题在于 AsyncStorage 的安全级别。
AsyncStorage 提供了一种在本地存储令牌和数据的方法。它可以 在某些方面,与 LocalStorage 选项相比。在全 生产应用,建议不要访问 AsyncStorage 直接,而是使用抽象层,因为 AsyncStorage 是 与使用相同浏览器的其他应用程序共享,因此 考虑不周地从存储中移除所有物品可能会损害 相邻应用的功能。
https://auth0.com/blog/adding-authentication-to-react-native-using-jwt/
在本机应用程序中,我会在ios
中选择Keychain
,在android
中选择私人模式 中的Shared Preferences
。
对于我在 React Native 提供的文档中读到的内容:
在 iOS 上,AsyncStorage 由存储小值的本机代码支持 在序列化字典和单独文件中的较大值中。在 Android,AsyncStorage 将根据什么使用 RocksDB 或 SQLite 可用。
https://facebook.github.io/react-native/docs/asyncstorage.html
他们从不谈论这些数据的安全性。
最好的解决方案是为Android
(在私有模式中使用Shared Preferences
)和iOS
(使用钥匙串)创建一个模块保存敏感数据?或者使用提供的AsyncStorage
方法是否安全?
【问题讨论】:
你在寻找什么,在这篇文章中得到了回答:***.com/questions/37563224/… 该答案并未对AsyncStorage
的安全性做出任何假设。
你可以看看这个帖子:***.com/questions/45547657/…
Pedro 和 Julien,停止链接到其他帖子。这很烦人。如果有有用的信息,请在此处发布。这样一来,通过 Google 搜索最终到达这里的用户就不必一直链接到其他帖子。
【参考方案1】:
刚刚深入研究了 React Native 代码,我找到了答案。
安卓
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 将您的数据库存储在关联的私有磁盘空间中 应用。您的数据是安全的,因为默认情况下此区域不 其他应用程序可以访问。
Source
iOS
在 iOS 中,AsyncStorage
值保存在序列化的字典文件中。这些文件保存在应用程序NSDocumentDirectory
中。在 iOS 中,所有应用程序都存在于它们自己的沙箱中,因此一个应用程序的所有文件都是安全的,其他应用程序无法访问它们。
iOS 中处理AsyncStorage
模块的代码可以在这里找到:https://github.com/facebook/react-native/blob/master/React/Modules/RCTAsyncLocalStorage.m
我们可以看到here 用于存储AsyncStorage
保存的值的文件保存在NSDocumentDirectory
下(在应用程序沙箱环境中)。
每个应用程序都是一个岛 iOS 应用程序与文件系统的交互 主要限于应用程序沙箱内的目录。期间 安装新应用程序时,安装程序会创建一些 应用程序的容器。每个容器都有特定的角色。捆绑 容器保存应用程序的包,而数据容器保存 应用程序和用户的数据。数据容器是 进一步划分为应用程序可以使用的多个目录 对其数据进行排序和组织。该应用程序还可能请求访问 运行时的其他容器,例如 iCloud 容器。
Source
结论
使用AsyncStorage
保存用户令牌是安全的,因为它们保存在安全上下文中。
请注意,这仅适用于没有 root 的 Android 设备和没有 越狱 的 iOS 设备。另请注意,如果攻击者对设备具有物理访问权限,并且设备不受保护。他可以将设备连接到mac笔记本和extract the documents目录下,就可以看到documents目录下保存的所有内容。
【讨论】:
有参考资料和事实支持的好答案。谢谢! 回复:Android:“所以它是安全的”:没有什么是安全的,可以实现接近“安全”的理想。在这种情况下,如果设备被植根(无论是否有意),则可以访问数据。 就像我在结论中所说的那样。 "使用 AsyncStorage 保存用户令牌是安全,因为它们保存在安全上下文中。"将用户令牌也作为额外层进行加密不是更安全吗?似乎很多用户都有一个根植的 Android 设备并且可以窥探文件,但并不是每个人都会努力解密。 RN 文档明确指出您不应使用 AsyncStorage 进行令牌存储 - reactnative.dev/docs/security【参考方案2】:AsyncStorage
将键值对保存为 Documents 目录中的纯文本 JSON 文件。 它不加密其内容。
这是一个安全问题(至少在 iOS 上),因为有权访问设备的攻击者可能会获取沙盒内容的转储并轻松提取通过AsyncStorage
保存的任何数据。
这曾经在 AsyncStorage.js 的文档中没有明确说明,但现在是: https://github.com/facebook/react-native/pull/8809
另见:https://***.com/a/38398114/1072846
【讨论】:
这都是真的。您不应在 iOS 或 Android 上使用 AsyncStorage 存储敏感数据 那么如果我们使用react-native-keychain
加密令牌然后将其存储在AsyncStorage
中是否安全?【参考方案3】:
如果有人想要对数据进行加密的额外步骤,您可能需要查看以下内容:https://github.com/oblador/react-native-keychain
它在内部使用facebook conceal。
【讨论】:
【参考方案4】:我真的建议您使用像react-native-keychain 这样的库来将私有数据存储在react-native 中
对于 Android API 级别:
16-22 使用 Facebook 隐藏 23+ 使用 Android 密钥库你可以这样使用它:
// 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);
);
【讨论】:
有没有办法在钥匙串中存储第二组凭据?我只知道如何设置一对值,而且我已经用完了存储用户用户名和密码的插槽,以便与生物识别身份验证 (touchId/faceId) 结合使用。 嘿,这个库可以用来存储 jwt 令牌吗?我对存储用户名或密码不太感兴趣,我正在寻找一种安全的方式来在我的主应用程序(react native)和同一捆绑包和应用程序组下的 iOS 共享扩展程序之间存储令牌。如果答案是肯定的,哪个 API 函数将用于在 keychain 中设置令牌?谢谢以上是关于在 React Native 中保存敏感数据的主要内容,如果未能解决你的问题,请参考以下文章
由于谷歌播放控制台的新政策,React-native Android 应用程序不断拒绝:敏感信息