【问题标题】:Are Rails passwords generated with bcrypt portable?使用 bcrypt 生成的 Rails 密码是否可移植?
【发布时间】:2013-09-29 15:33:46
【问题描述】:

我有一个现有的 Web 应用程序,它有几千个用户,我将其移植到 Rails。在我重写和重构此应用程序时,我可能需要在任意数量的不同服务器上运行它以用于开发、测试和生产目的。

我在我的用户模型中使用 Rails 的内置 has_secure_password 方法,但我担心密码数据的可移植性。我需要将我的数据库内容从一台机器移动到另一台机器以在不同的环境中进行测试,这非常重要,我可以在每个环境中使用相同的用户和密码集来测试用户身份验证功能。

到目前为止,很容易找到有关 bcrypt-ruby 如何与 Rails has_secure_password 一起工作的答案,但经过数周的搜索,我还没有找到明确的答案。

如果 has_secure_password 导致 WorkFactor + Salt + HashedPassword 连接并保存到 password_digest 数据库列,那么 如果移动到任何其他机器(假设任何其他机器正在运行),该哈希是否可以重新生成并可靠地比较Rails 在类 Unix 操作系统上)?

OR 换句话说 - 使用 Rails 的 has_secure_password 生成的 bcrypt-ruby 密码可移植吗?

后续问题:如果盐总是随机生成(我见过相同的密码使用不同的哈希,所以我不认为盐是从密码本身的文本中创建的)那么 Rails 应用程序如何能够可靠地重新散列登录表单提交的密码并将其与数据库中的内容进行比较。显然,它必须首先知道盐是什么才能进行比较。它是怎么做到的?

【问题讨论】:

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


    【解决方案1】:

    是的,密码是可移植的。使用的格式是标准的“加密编码”格式,也用作 RFC 2307 的一部分(在 RFC 2307 中,字符串的前缀为“{CRYPT}”)。我使用过一个 Perl 库 Authen::Passphrase,它可以很高兴地针对来自 RoR 数据库的 bcrypt 散列版本验证密码。

    对于后续问题: salt 嵌入在存储的值中(连同散列的类型、要使用的 bcrypt 周期数,当然还有散列本身),并且验证服务器需要读取存储的值,然后它简单地重新使用相同的盐来生成散列部分——如果输入密码正确,那么散列将是相同的。身份验证过程不会创建新的随机盐。仅在生成用于存储的全新哈希时才会创建随机盐。

    bcrypt 密码很容易拆分成组件供服务器读取(我选择了非现实字符以便更容易看到边界,实际上 salt 和 hash 是 base 64 编码的二进制数据):

     $2a$10$AaBbCcDdEeFfGgHhIiJjKk0987654321098765432109876543210
    
    • 这部分的意思是“使用 bcrypt,2**10 == 1024 次迭代”:$2a$10$

    • 这部分是盐:AaBbCcDdEeFfGgHhIiJjKk,总是22个字符

    • 这部分是哈希:0987654321098765432109876543210,总是31个字符

    【讨论】:

    • 谢谢,我遇到的麻烦是围绕着 Rails 围绕身份验证所做的魔法,因为我没有明确告诉框架“嘿,获取与此用户名匹配的密码哈希,拉取出盐,对表单输入进行哈希处理,然后比较它们”。实际上,我的意思是“获取此输入并对其进行哈希处理,然后将其与与此用户名对应的匹配哈希进行比较”,而 Rails 会使用一些魔法来填补背景中的空白。到目前为止,Rails 最难的部分是让您自己让框架处理您通常自己编写的内容。
    猜你喜欢
    • 2017-03-11
    • 2018-06-23
    • 2014-05-26
    • 2020-06-27
    • 2013-05-30
    • 2010-11-27
    • 2011-11-12
    • 2016-05-28
    • 2014-10-28
    相关资源
    最近更新 更多