3

目前我们正在开发一个小型应用程序,我们在基于 Rails 的后端中存储来自基于 JS 的图形编辑器(想想这个的增强版)的一堆 JSON 数据。我们希望允许用户存储加密的数据(AES、RSA 等),作为应用程序维护者,我们不可能解密我们数据库中的内容——当然,只要有一个强密码。没有用户帐户管理,什么都没有。人们只能通过秘密链接创建和编辑他们的图表,仅此而已。

在编辑或保存当前状态之前,将需要密码来加密/解密进出数据库的图形。现在,我们现在面临的概念性问题如下:

  1. 我们是否在整个会话期间存储密码?如果不是,用户每次刷新浏览器或想要将其图形的当前状态保存到数据库时都必须输入密码。不舒服...

  2. 如果 - 从软件工程的角度来看 - 这是适用的:这种信息一般存储在哪里?除了 cookie,我们还有哪些选择?

  3. 如果是这样 - 我们是否必须存储纯密码,或者有没有办法以某种方式加密密码,以便在 cookie 被盗的情况下,攻击者将面临更困难的游戏获取密码?

4

1 回答 1

1

很多时候,安全是一种平衡,这就是一种情况。

考虑到您的要求(没有用户管理后端的 webapp),我认为您有两个选择:

  • 您不存储密码,但用户体验更差。正如您所说,任何刷新都需要用户再次输入密码。

  • 您在客户端存储密码(见下文如何),一个合理的位置是 SessionStorage。这种方式很舒服并且可以像任何用户期望的那样工作:它“只是工作”,直到用户关闭浏览器,但不是之后。显然,这具有非常现实的风险,即密码以某种形式存在于浏览器中。它适用于任何 Javascript(考虑 xss),并且您无法阻止它被缓存到磁盘(无论您做什么,请考虑使 pc 休眠等)。一般来说,这是一种反模式,但并不是那么简单。安全决策应该基于风险。

这是您必须根据特定于您的用例的风险做出的决定。数据是什么,攻击的可能性有多大(你做了什么来合理保证你的代码是安全的),影响是什么(如果密码丢失,你会失去什么,包括声誉损失等)。如果他们必须一直输入密码,您的用户是否真的会讨厌该产品?只有你能回答这些问题。

在客户端加密密码没有意义,攻击者将拥有一切来解密它。然而,散列它可能有好处,一开始可能有点令人惊讶。如果您实际上没有存储密码而是某种转换,那么无论您存储什么都是密码,所以看起来它没有意义。它仍然存在的原因是因为人们倾向于重用密码,所以如果您使用 PBKDF2 从密码中派生一个密钥并将其存储为密钥,那么攻击者无法从浏览器获得实际密码(但是如果存在妥协,他们仍然可以访问数据,比如 xss)。

因此,如果(且仅当)您接受上述存储风险以及与 javascript 加密相关的风险,您应该

  • 使用适当的密钥派生函数(如 pbkdf2)从用户密码中派生密钥
  • 将该密钥作为加密密钥存储在 SessionStorage 中
于 2018-03-21T21:13:31.600 回答