Bil*_*ill 5 ruby ruby-on-rails bcrypt bcrypt-ruby ruby-on-rails-4
我有一个现有的Web应用程序,有几千个用户,我正在移植到Rails.当我重写和重构这个应用程序时,我可能需要在任意数量的不同服务器上运行它以进行开发,测试和生产.
我在我的用户模型中使用Rails的内置has_secure_password方法,但我担心密码数据的可移植性.我需要将数据库的内容从一台机器移动到另一台机器,以便在不同的环境中进行测试,并且非常重要的是我可以在每个环境中使用相同的用户和密码集测试用户身份验证功能.
到目前为止,很容易找到关于bcrypt-ruby如何与Rails一起工作的答案,has_secure_password但经过数周的搜索后,我还没有找到明确的答案.
如果has_secure_password将WorkFactor + Salt + HashedPassword中的结果连接并保存到password_digest数据库列,则可以重新生成该哈希,并在移动到任何其他计算机时可靠地进行比较(假设任何其他计算机在类Unix操作系统上运行Rails)?
或者换句话说 - 使用Rails的has_secure_password便携式生成的bcrypt-ruby密码?
后续问题:如果盐总是随机生成的(我看到相同的密码使用不同的哈希值,所以我不认为盐是从密码本身的文本创建的)那么Rails应用程序将如何能够可靠地在登录表单上重新提交密码提交,并将其与数据库中的内容进行比较.显然,为了比较它,它必须首先知道盐是什么.它是如何做到的?
是的,密码是可移植的.使用的格式是标准的"加密编码"格式,也用作RFC 2307的一部分(在RFC 2307中,字符串将以"{CRYPT}"为前缀).我使用过Perl库Authen::Passphrase,可以根据RoR数据库中的bcrypt-hashed版本快速验证密码.
对于后续问题: salt嵌入在存储值中(连同散列类型,要使用的bcrypt循环数,当然还有散列本身),并且要验证服务器需要读取存储的值,然后它只是重新使用相同的盐来生成散列部分 - 如果输入的密码是正确的,那么散列将是相同的.身份验证过程不会创建新的随机盐.只有在生成用于存储的全新哈希时才会创建随机盐.
bcrypt密码很容易拆分成组件供服务器读取(我选择了非实际字符,以便更容易看到边界,实际上salt和hash是base 64编码的二进制数据):
$2a$10$AaBbCcDdEeFfGgHhIiJjKk0987654321098765432109876543210
Run Code Online (Sandbox Code Playgroud)
这部分意味着"使用bcrypt,2**10 == 1024次迭代": $2a$10$
这部分是盐:AaBbCcDdEeFfGgHhIiJjKk,总是22个字符
这部分是哈希:0987654321098765432109876543210总是31个字符