php - 将 PHP 的 password_verify 转换为 Ruby on Rails

标签 php ruby-on-rails ruby

我们正在将我们的站点从旧的 PHP 框架转换为 Rails,并且真的希望用户能够继续使用他们的旧密码登录。在旧网站上,我们使用 password_hash 和 password_verify 来散列和验证密码。但是,在 Rails 上我似乎无法验证旧密码。

这是我们在 PHP 中的内容:

哈希:

password_hash($user['salt'] . $password . $user['salt'], PASSWORD_DEFAULT);

验证:

password_verify($user['salt'] . $password . $user['salt'], $user['password'])

在新的 Rails 框架上,我们使用 Devise 并构建了一个自定义迁移脚本来移动所有内容,并根据存储在数据库中的 password_version 识别正确的密码散列方法,这就是我在我的内部使用的用户模型:

def valid_password?(password)
  if password_version == 'legacy'
    hash = BCrypt::Password.new(encrypted_password)
    hash_str = password_salt+password+password_salt

    return hash.is_password? hash_str
  end

  super(password)
end

任何想法将不胜感激

最佳答案

PHP password_hash 密码的格式大致如下所示:

$2y$10$.vGA1O9wmRjrwAVXD98HNOgsNpDczlqm3Jq7KnEd1rVAGv3Fykk1a

默认的 Ruby Bcrypt 方法生成以下形式的密码:

$2a$10$GtKs1Kbsig8ULHZzO1h2TetZfhO4Fmlxphp8bVKnUlZCBYYClPohG

对于此处的干净解决方案,您始终可以通过 $2y$2a 前缀来区分两者。格式列已经包含在格式中时,就不需要格式列了。

例如:

case (encrypted_password[0,3])
when '$2y'
  # Legacy PHP password
  BCrypt::Password.new(encrypted_password.sub(/\A\$2y/, '$2a')).is_password?(salt + password + salt)
when '$2a'
  # Ruby BCrypt password
  BCrypt::Password.new(encrypted_password).is_password?(password) 
else
  # Unexpected type?
end

密码验证成功后要做的是使用Ruby的方法将密码重新写入数据库,逐步替换所有旧的PHP格式的密码。

关于php - 将 PHP 的 password_verify 转换为 Ruby on Rails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38983631/

相关文章:

ruby-on-rails - 使用 nginx 运行 capybara

ruby-on-rails - 在 rails 中创建大标签

ruby-on-rails - 对哈希数组进行分组

php - 如何从 PHP 读取 PNG 元数据?

php - php tidy 的替代品?

php pdo切换主键值

sql - 为什么 Rails ActiveRecord 访问数据库两次?

ruby - 使用 rvm 安装 ruby​​2 时出错

php - 为什么它编写的 md5 以及任何语言(如 php、ruby 等)的下载?

php - 对一列的数组数据进行分组并对另一列的数据求和