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

Ruby on rails 在ruby中存储可解密密码的安全方法,ruby-on-rails,ruby,ruby-on-rails-4,encryption,Ruby On Rails,Ruby,Ruby On Rails 4,Encryption,我想以一种安全的方式在数据库中以加密的形式存储一些密钥。同时,我需要在代码的某个地方使用非加密(原始)形式的密钥。我计划使用PBKDF2进行密码散列。是否可以使用PBKDF2以加密形式解密存储在数据库中的密钥。或者有没有简单安全的程序 密码和密钥通常以散列形式存储。这意味着它们在保存到数据库之前通过哈希函数进行处理。好的哈希函数(如bcrypt)具有以下属性: 它为相同的输入生成相同的输出 它为不同的输入产生非常不同的输出 它的输出无法与随机输出区分开来 它是不可逆的 最后一个属性具有非常重

我想以一种安全的方式在数据库中以加密的形式存储一些密钥。同时,我需要在代码的某个地方使用非加密(原始)形式的密钥。我计划使用PBKDF2进行密码散列。是否可以使用PBKDF2以加密形式解密存储在数据库中的密钥。或者有没有简单安全的程序

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

  • 它为相同的输入生成相同的输出
  • 它为不同的输入产生非常不同的输出
  • 它的输出无法与随机输出区分开来
  • 它是不可逆的
最后一个属性具有非常重要的安全含义:当有人访问数据库时,他们无法恢复原始密钥,因为散列函数是不可逆的,特别是当散列被腌制以防止攻击者使用rainbow表时

这意味着,如果以后要恢复密钥,必须以加密(而不是散列)形式保存它们。加密函数具有类似于散列函数的属性,关键区别在于它实际上是可逆的。对于这个解密步骤,您需要一个密钥,它需要存储在某个地方

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

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

  • 在数据库中存储传统的散列用户密码,例如使用bcrypt
  • 允许用户通过以下步骤存储其他密码:
    • 提示输入要存储的用户密码和密钥
    • 散列密码并与数据库进行比较以进行身份验证
    • 为每个输入的键生成salt
    • 使用用户输入的密码和salt加密密钥以存储,例如使用AES加密
    • 在数据库中存储salt和加密密钥
  • 要在要求以纯文本形式存储密钥的操作中检索存储的密钥,请执行以下操作:
    • 提示输入用户密码
    • 散列密码并与数据库进行比较以进行身份验证
    • 从数据库中检索加密密钥和salt
    • 使用用户密码和salt解密存储的密钥

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

密码永远不会以人们事后可以解密的方式存储在数据库中。不能保证有人不会入侵您的数据库表并窃取您存储的所有内容

如果您为每个用户存储加密(哈希)密码,即使您的数据库遭到黑客攻击,盗取您解密密码的人也要花很多时间才能找到实际密码。他们可以始终使用相同的加密,并比较常见密码的哈希结果。例如,他们可以加密“MyPassword123”,然后将哈希密码与数据库中的每个密码进行比较。使用此模式仍然可以猜测弱密码


因此,即使是不可解密的密码也有其弱点,但如果您允许某人解密您存储的内容,那么基本上他们很容易获得您用户的每一个密码。非常糟糕的做法。一些最大、最“安全”的公司的存储密码散列文件被盗,因此,您不能假设自己不会成为受害者。

我在使用Ruby进行用户验证时遇到了同样的问题,因为它比较了用户输入的明文和哈希密码之间的差异,哈希密码从不解密为明文。我发现可以解决您的问题的一个宝石是encryptor,它使用多个不同的密钥进行加密。因此,您可以做的是将密码保存在数据库中,同时将密钥安全地保存在另一个位置(存储中的文件)


更多信息可以在中找到。

安全和可解密密码是一种矛盾修饰法。如果它们是可解密的,它们就不安全。如果您的程序可以以简单的形式获取它们,那么无论您的密码存储有多安全都无关紧要。(不,您不能解密PBKDF2生成的派生密钥。)不要加密密码,当攻击者获得DB时,他也将获得加密密钥。用随机盐在HMAC上迭代大约100毫秒,并用散列保存盐。使用诸如password_hash、PBKDF2、Bcrypt等函数和类似函数。重点是让攻击者花费大量时间通过暴力手段查找密码。其目的不是将密钥保存在数据库中,而是保存在一个单独的文件位置(例如,只能由服务帐户和少数系统管理员访问)。Bcrypt和PBKDF2似乎只解决了密码验证的一个特定问题,但当您需要自动脚本的明文密码时,它并不能解决这个问题,比如说。如果需要明文密码,比如传递到另一个应用程序,一个更好的概念是使用一个单独的加密服务器,这样加密密钥不在DB服务器上,而是在另一个最小的非常安全的服务器上,请参见此。那么这与我提到的方法有何不同?我不赞成将密钥保存在数据库或计算机上