在ruby中存储可解密密码的安全方法

时间:2015-01-09 06:36:11

标签: ruby-on-rails ruby ruby-on-rails-4 encryption

我希望以安全的方式将一些密钥以加密形式存储在数据库中。同时我需要在代码中的某处使用非加密(原始)形式的密钥。我打算使用PBKDF2进行密码哈希PBKDF2。是否可以使用PBKDF2以加密形式解密存储在数据库中的密钥。或者是否有任何简单安全的程序?

3 个答案:

答案 0 :(得分:7)

密码和密钥通常以散列形式存储。这意味着它们在保存到数据库之前通过哈希函数进行处理。良好的散列函数(如bcrypt)具有以下属性:

  • 它为同一输入生成相同的输出
  • 它为不同的输入产生非常不同的输出
  • 其输出无法与随机区分
  • 不可逆

最后一个属性具有非常重要的安全隐含性:当有人访问数据库时,他们无法恢复原始密钥,因为哈希函数不可逆,特别是当哈希被加盐以防止攻击者使用彩虹表时。 / p>

这意味着如果您想稍后恢复密钥,则必须将它们保存为加密(不是哈希)表单。加密函数具有类似哈希函数的类似属性,其关键区别在于它实际上是可逆的。对于此解密步骤,您需要一个密钥,需要将密钥存储在某处。

您可以将密钥存储在应用程序配置中,但这意味着如果有人获得对您服务器的访问权限,他们就能够检索加密密钥并解密所有存储的密钥。

我建议一种替代方法,用户只允许检索自己存储的密钥。它基于这样的想法,即密钥是使用只有用户知道的用户专用密码加密的。每当您需要执行需要存储或检索密钥的操作时,系统都会提示用户输入密码。这样,您自己和攻击者都无法检索它们,但如果用户通过输入密码允许,程序可以访问它们。

  • 在数据库中存储常规哈希用户密码,例如使用bcrypt
  • 允许用户使用以下过程存储其他密码:
    • 提示用户密码和存储密钥
    • 哈希密码并与数据库进行比较以进行身份​​验证
    • 为每个输入的密钥生成盐
    • 使用用户输入的密码和salt加密要存储的密钥,例如使用AES加密
    • 在数据库中存储salt和加密密钥
  • 要在纯文本格式中要求它们的操作中检索存储的键:
    • 提示输入用户密码
    • 哈希密码并与数据库进行比较以进行身份​​验证
    • 从数据库中检索加密的密钥和salt
    • 使用用户密码和salt解密存储的密钥

小心从应用程序日志中删除用户提交的密码; - )

答案 1 :(得分:1)

密码永远不会以任何方式存储在数据库中,之后人们可以对其进行解密。无法保证有人不会破解您的数据库表并窃取您存储的所有内容。

如果您为每个用户存储加密(哈希)密码,即使您的数据库被黑客攻击,也会花费很多时间来窃取您的解密密码以查找实际密码。他们总是可以使用相同的加密并比较生成的常用密码哈希值。例如,他们可以加密" MyPassword123"然后将该散列密码与数据库中的每个密码进行比较。使用这种模式仍然可以猜到弱密码。

因此,即使是不可解密的密码也有其弱点,但如果您允许某人解密您存储的内容,那么基本上它们非常容易获取您用户的每一个密码。非常糟糕的做法。一些最大和最安全的"公司已经存储了密码哈希被盗,所以你不能认为你不会成为受害者。

答案 2 :(得分:0)

我遇到了使用Ruby的bcrypt同样的问题,它用于用户验证,因为它比较了用户输入的明文和散列密码之间的差异以及散列密码永远不会解密为清除文本。我发现可以解决您的问题的一个宝石是加密器,它使用几个不同的密钥进行加密。因此,您可以做的是将密码保存在数据库中,同时将密钥安全地保存在另一个位置(存储中的文件)。

更多信息可在rubygems page

中找到