本地存储可以被认为是安全的吗?

我被要求开发一个网络应用程序,将功能长期离线。为了实现这一点,我不能避免在本地存储中保存敏感数据(个人数据,但不是只存储散列类型的数据)。

我承认这不是推荐的做法,但是在别无选择的情况下,我正在采取以下措施来保护数据:

  • 使用斯坦福 javascript 加密库和 AES-256对进入本地存储的所有内容进行加密
  • 用户密码是加密密钥,不存储在设备上
  • 通过 ssl 从一个受信任的服务器提供所有内容(联机时)
  • 使用 owasp 反同项目验证进出服务器上本地存储的所有数据
  • 在 appcache 的 network 部分中,不使用 * ,而是仅列出与可信服务器连接所需的 URI
  • 一般来说,尝试应用 OWASP XSS 备忘单中建议的指导方针

我知道,细节往往是关键所在,我也知道,总的来说,人们对本地存储和基于 javascript 的安全性持怀疑态度。有没有人可以评论一下:

  • 上述方法的根本缺陷?
  • 对于这些缺陷有什么可能的解决方案吗?
  • 当 html 5应用程序必须长时间离线运行时,有没有更好的保护本地存储的方法?

谢谢你的帮助。

125209 次浏览

这里的基本前提是: 不,它还不安全。

基本上,您不能在 JavaScript: 认为有害的 JavaScript 加密中运行加密。

问题是您不能可靠地将加密代码导入浏览器,即使可以,JS 也不允许您安全地运行它。因此,除非浏览器拥有一个加密容器(加密媒体扩展提供了这个容器,但是为了 DRM 的目的,这个容器正在被联合起来反对) ,否则就不可能做到安全。

至于“更好的办法”目前还没有。您唯一的选择是以纯文本形式存储数据,并希望能达到最好的效果。或者根本不存储信息。不管怎样。

或者,或者如果你的 需要这种安全,你需要本地存储,创建一个自定义应用程序..。

网络加密

客户端(浏览器) javascript 中的加密关注点如下。除了其中一个问题外,所有这些问题都不适用于 WebCrypto API,即现在的 相当好的支撑

对于脱机应用程序,仍然必须设计和实现安全密钥存储库。

旁白: 如果您正在使用 Node.js,请使用内置的 加密 API。

原生 Javascript 加密技术(WebCrypto 之前)

我假设主要的关注点是那些能够实际访问计算机并为您的站点读取 localStorage的人,并且您希望通过加密来帮助防止这种访问。

如果有人有物理访问,你也开放的攻击其他和比阅读更糟糕。其中包括(但不限于) : 键盘记录器、脱机脚本修改、本地脚本注入、浏览器缓存中毒和 DNS 重定向。这些攻击只有在用户在机器被入侵后使用它时才会起作用。然而,在这种情况下,物理访问意味着您有更大的问题。

因此,请记住,本地加密技术有价值的有限情况是机器被盗。

有些库确实实现了所需的功能,例如 斯坦福 Javascript 加密库。尽管如此,还是存在固有的弱点(如@ircmaxell 回答中的链接所示) :

  1. 缺乏熵/随机数生成;
  2. 缺乏安全密钥存储库,即私钥必须有密码保护,如果存储在本地,或存储在服务器上(禁止离线访问) ;
  3. 缺乏安全擦除;
  4. 缺乏时间特征。

这些弱点中的每一个都与一类密码妥协相对应。换句话说,虽然你可能有“加密”的名称,它将远远低于严格的一个渴望在实践中。

尽管如此,精算评估并不像“ Javascript 加密很弱,不要使用它”那样微不足道。这不是一个认可,严格来说是一个警告,它要求你完全了解上述弱点的暴露,你所面对的矢量的频率和成本,以及你在失败时的缓解或保险能力: Javascript 加密,尽管它的弱点,可能会减少你的暴露,但只有对小偷有限的技术能力。但是,您应该假定 Javascript 加密对于以该信息为目标的已确定且有能力的攻击者没有价值。有些人可能会认为,把这些数据称为“加密的”是误导人的,因为人们已经知道,这些数据存在许多固有的弱点。换句话说,你可以略微减少你的技术风险敞口,但你增加你的财务风险从披露。当然,每种情况都是不同的,对减少金融风险的技术风险敞口的分析也是非同小可的。这里有一个说明性的类比: 一些银行需要弱密码,尽管存在固有的风险,因为它们暴露于弱密码的损失比支持强密码的最终用户成本要低。

如果你读到最后一段并且想到“网上有个叫布莱恩的家伙说我可以使用 Javascript 加密”,不要使用 Javascript 加密

对于问题中描述的用例,用户似乎更应该加密本地分区或主目录,并使用强密码。这种类型的安全性通常经过良好的测试,受到广泛的信任,并且是普遍可用的。

作为对这个主题的探索,我有一个题为“使用 Web 加密 API 保护 TodoMVC”的演示文稿(视频密码)。

它使用 网络加密 API将 todo 列表存储在 localStorage 中,通过密码保护应用程序,并使用密码派生密钥进行加密。如果忘记或丢失密码,则无法恢复。(免责声明-这是一个 POC,不打算生产使用。)

正如其他答案所述,这仍然容易受到安装在客户端计算机上的 XSS 或恶意软件的影响。但是,当数据存储在服务器上并且应用程序正在使用时,任何敏感数据也将存储在内存中。我建议离线支持可能是最有说服力的用例。

最后,加密 localStorage 可能只能保护数据不受只读访问系统或其备份的攻击者的攻击。它为 OWASP 排名前10的项目 A6-敏感资料暴露增加了少量的深度防御,并允许您回答“这些数据是否长期以明文形式存储?”正确。

这是一篇非常有趣的文章。我正在考虑实现 JS 加密,以便在使用本地存储时提供安全性。很明显,这只有在设备被盗(并且正确实现)时才能提供保护。它不能提供对键盘记录器等的保护。然而,这不是一个 JS 问题,因为键盘记录器的威胁是所有应用程序的问题,不管它们的执行平台(浏览器,本机)。至于第一个答案中提到的文章“ JavaScript Crypto Conthought Harmful”,我有一个批评意见,它说: “你可以使用 SSL/TLS 来解决这个问题,但是这是昂贵和复杂的。”。我认为这是一个非常雄心勃勃的主张(可能相当有偏见)。是的,SSL 是有成本的,但是如果您看一下为多个操作系统开发本地应用程序的成本,而不是仅仅因为这个问题而基于 Web 的成本,那么 SSL 的成本就变得微不足道了。

我的结论是: 客户端加密代码是有一席之地的,然而,对于所有应用程序,开发人员必须认识到它的局限性,并在适合自己需要的情况下加以实现,同时确保存在降低其风险的方法。

没有。

LocalStorage 可以被任何网页访问,如果你有密钥,你可以更改任何你想要的数据。

也就是说,如果您可以设计一种方法来安全地加密密钥,那么如何传输数据并不重要,如果您可以将数据包含在一个闭包中,那么数据(在某种程度上)是安全的。

不能访问任何网页(真实) ,但是可以通过开发工具(如 chrome (ctl-shift-J))轻松访问和编辑。因此,在存储值之前需要自定义加密。

但是,如果 javascript 需要解密(验证) ,那么解密算法就会暴露出来,可以进行操作。

Javascript 需要一个完全安全的容器,以及正确实现只有 js 解释器才能使用的私有变量和函数的能力。但是,这违反了用户安全——因为追踪数据可以不受惩罚地使用。

因此,javascript 永远不会是完全安全的。