如何最好地使用用户密码加密数据库数据?

5
假设一个应用程序具有属于用户的非常特定的数据,除了所有者之外,没有人应该看到它。我使用DataMapper ORM映射器和MySQL数据库。该应用程序是用Sinatra的Ruby编写的。
应用程序行为:
1. 用户注册账户并创建用户名和密码。 2. 登录到他的仪表板。 3. 某些特定表中的字段必须受到保护。
基本上,我正在寻找模型属性的自动加密功能。就像这样:
class Transaction
  include DataMapper::Resource

  property :id, Serial
  property :value, String, :length => 1024, :encrypted => true
  ... etc ...
  belongs_to :user
end

我认为实时加密/解密会导致性能问题,但这没关系。至少如果可以解决这个问题 - 我就满意了。
有什么好的想法吗?

你是否正在尝试对数据库中特定字段进行透明加密和解密,仅供其所属用户使用? - Piskvor left the building
是的!我需要保持一些数据加密,而不是全部加密。 - Dan Sosedoff
7个回答

3
我不会存储任何依赖于用户记住密码并使用该密码解密数据的数据。当用户更改密码时,您将怎么做?解密/加密所有内容吗?我不太确定。如果管理员重置密码怎么办?所有数据都丢失了吗?同样,我表示怀疑。
请查看有关存储机密的其他链接,但请不要使用用户的任何值作为加密的一部分。

1
是的,用户输入的密码应该用于验证对其余数据的访问,而不是用于实际加密。密码还可以用于验证对随机加密字符串(永远不会更改)的访问,以便加密用户数据。 - David R Tribble

2
您想要将数据加密存储在数据库中吗?首先,我建议您考虑为什么需要这样做?您应该编写应用程序,只有经过身份验证的用户才能访问其自己的数据。
如果您确实需要存储需要解密的加密数据(而不是单向哈希),那么关于Ruby加密的内容有很多,可以在此处了解:http://www.example-code.com/ruby/encryption.asp

只有经过身份验证的用户才能访问自己的数据。这确实是问题的前提。但是,数据并不存在于真空中,如果需要存储它们,它们必须存储在某个地方。只要您适当地对它们进行加密,您也可以将它们存储在数据库中,其他因素允许的情况下(在数据库中存储100 MB文件没有意义,而存储1K字符串则可能可行)。 - Piskvor left the building
是的,数据主要是数字和短字符串,这是与金钱相关的数据,因此需要为每个用户保密。另一件事是-如何在这种加密数据上执行任何聚合操作? - Dan Sosedoff

1
你肯定应该在用户端对数据进行加密/解密-否则加密存储就没有意义了,因为私人数据的痕迹仍然存在于某个地方-在网络缓存中,在不同类型的交换文件中等。此外,数据可以被中间人攻击窃取。
因此,您可能想要的是基于Javascript的客户端加密。这个主题在http://javascript.about.com/library/blencrypt.htm(Rijndael加密算法)中得到了广泛的涵盖,并且在http://www.movable-type.co.uk/scripts/aes.html上有很棒的AES实现库。
你应该在提交表单之前加密数据(使用 "提交" 按钮的 onClick 回调),然后将其传递给服务器并按常规方式处理。
缺点是,您不能使用任何Rails处理这样的数据-只能使用客户端javascript。

1

我必须为加密敏感数据而这样做。我包装了 strongbox gem 并将其放在 github 上:http://github.com/bitzesty/safe

safe gem 提供 AR 属性的公钥加密。


0

您使用单向哈希算法。将密码进行哈希处理并存储哈希值。每当用户输入密码时,您都会对输入的密码进行哈希处理并将其与存储的哈希密码进行比较。如果它们相同,则允许用户通过。否则,拒绝访问。


不要忘记使用盐。http://zh.wikipedia.org/wiki/%E7%9B%90_(%E5%AF%86%E7%A0%81%E5%AD%A6) - Mark Byers
2
这个做法“不以明文形式存储用户密码”是很好的,但我认为提问者在某些时候需要解密用户数据(例如医疗记录)。 - Piskvor left the building
我知道密码的相关内容,但问题是如何保持用户数据加密。 - Dan Sosedoff

0
通常不建议将用户的密码以明文形式存储。
通常会将其作为MD5或SHA1的哈希值进行加盐处理后存储。
因此,您需要一个随机盐,将其存储在用户表中,然后对他们的密码和盐进行哈希处理,如下所示:
$hash = md5(md5(salt) + pass)

我建议不要存储可以返回的密码,唯一建议您存储的方式是使用单向哈希。

话虽如此,有一些加密方案可供使用,例如RSA加密。这样,您的应用程序将使用您的公钥对从最终用户接收到的用户密码进行加密,当您需要解密时,请使用您的私钥进行解密。实际上,以这种方式存储密钥的应用非常有限(例如自动提供登录到另一个站点),通常被视为不良行为。


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接