【发布时间】:2013-09-03 16:51:43
【问题描述】:
我正在尝试编写一个 Rails 应用程序,它可以让您将加密的密码存储在 Rails 数据库中。当你想存储密码时,你会在一个短语上调用 encrypt ,它会准确地告诉你生成的加密字符串是什么,你可以将它与特定的网站或帐户名一起存储,你将能够引用它在一张桌子上。然后,当您需要密码时,您可以选择该网站/密码对并对其进行解密以检索密码。我的问题是以下方案是否安全。
- 我将拥有一个绑定到用户的模型(例如,称为 SecretKeeper)。
- 在初始化 SecretKeeper 时,会使用 FastAES 对象的实例和密码(例如
@aes = FastAES.new(secret_phrase))对其进行初始化 - 然后当用户想要对密码进行加密时,SecretKeeper 会调用
Base64.urlsafe_encode64(@aes.encrypt([password].pack("m"))).slice(0..-2)返回编码后的字符串,然后将其存储在数据库中。 -
要解码,用户必须传入加密字符串以及“主”密码,该密码与用于创建 FastAES 对象的 secret_phrase 是分开的。此主密码以加密字符串的形式存储在与用户关联的数据库中(使用与上述第 3 条相同的方法)。为了验证这个主密码,当用户尝试解密密码时,我对主密码进行加密并将其与数据库中的哈希值进行比较以查看它是否匹配。如果是,我会继续调用
@aes.decrypt(Base64.urlsafe_decode64("#{encoded}=")).ljust(8, "\x00").unpack("m").first并返回结果字符串- 那么这是个好主意吗?或者我应该做些什么来让它更安全?
- 我还计划添加一个密码盐,它将以明文形式存储在数据库中。我是否也应该计划对此进行加密?
【问题讨论】:
-
你为什么要加密,而不是散列、加盐等?
-
我需要能够解码密码以显示给用户,例如这个工具能够提醒用户他们在不同应用程序/网站上的密码是什么(假设他们在每个网站上使用不同的密码)。
-
我无法评论大部分算法,但 AES 加密中缺少 IV 令人不安。 stackoverflow.com/a/9050752/1517648
-
如果我理解正确,
secret_phase是在您的应用程序中生成并存储在某处?我对密码学的理解非常基础,但加密/解密通常不是在客户端完成的吗?例如 1Password 或 LastPass。如果所有加密都是通过您的服务器完成的,那么在通过 Internet 传输未加密信息的地方会有一个巨大的差距,对吗?还是我在这里遗漏了什么? -
正确地获取密码存储应用程序是非常具有许多陷阱的微妙任务 - 看看像 Password Safe 和 KeePass 这样的应用程序。
标签: ruby-on-rails security encryption cryptography