如何将PHP密码实现转换为Ruby



我正在mac上进行开发并部署到Linux。我正在现有的PHP应用程序上编写一个Rails API,因此我无法更改密码或密码,但我需要身份验证才能工作。我需要能够根据现有密码进行身份验证,然后最终更改密码,使其仍然能够被原始的PHP应用程序读取。我可以访问确切的密码功能。我需要一个Ruby的解决方案(可以使用gem(。

PHP中的代码(salt被更改以保护无辜者(是这样的:

$passwordSHA = crypt($_POST['pass'],'$6$rounds=21000$abcdefghijklmnopqrstuv$');

我正在尝试编写一个函数来验证用户提供的密码是否与数据库中的加密密码匹配。我试着用正确的盐做这件事,但没有奏效(这可能只是与没有正确包括回合有关(。

存储在数据库中的密码看起来(sorta,为安全起见更改(是这样的。请注意,开始总是$6$rounds=21000$zxyabcdefghijklm$:

$6$rounds=21000$zxyabcdefghijklm$F/L4T80nbaaaaLMb7nPJ2OV5H/aaa.00v900000/Z5jlTLSa.XXXXXX./444444/p8b61UBz9z2Bj4qsABC4.

即使使用OpenSSL和BCrypt,我也尝试过一些不同的东西,但我甚至不知道如何从$6开始。

更新:尝试第一个答案,我没有得到任何接近正确长度的答案。也许这些信息有助于找出为什么这不起作用:

2.5.3 :001 > ruby_crypt = "foo".crypt('$6$rounds=21000$salt$')
=> "$6A86JNndVTdM"

更新2:请注意盐的长度。它比UnixCrypt允许的最大长度16还要长。

UPDATE 3/ANSWER:这里的问题是salt应该被截断超过16个字符。然后另外PHP插入舍入计数。最终答案是:

hashed_password = UnixCrypt::SHA512.build(password, salt, 5000).gsub('$6', '$6$rounds=21000')

为了方便使用UnixCrypt,这似乎很有效:

require 'unix_crypt'
PHP_CMD = %q|php -r 'echo crypt("foo", "$6$rounds=21000$salt$");'|
php_crypt = `#{PHP_CMD}`
puts "PHP:"
puts php_crypt
# This code is using native crypt and is platform dependent and not portable
# ruby_crypt = 'foo'.crypt('$6$rounds=21000$salt$')
# Because $6 means SHA512, we can use UnixCrypt instead for portability (thanks @matt)
ruby_crypt = UnixCrypt::SHA512.build('foo', 'salt', 21000)
puts "nRUBY:"
puts ruby_crypt
# If doing password validation only, it is best to use the 'valid?' method,
# as it will handle modifications in the algorithm and salt automatically.
puts "nValidate:"
p php_crypt == ruby_crypt
p UnixCrypt.valid?('foo', php_crypt)
p UnixCrypt.valid?('foo', ruby_crypt)

输出:

PHP:
$6$rounds=21000$salt$kvEIl.U0dy6F6y9dkTeTwUrpCOpz5eYK.jyTC2LeKo/gq9HYpDtD6.fMlHyLW.5h3fF4v.R19lX8W18KDvper1
RUBY:
$6$rounds=21000$salt$kvEIl.U0dy6F6y9dkTeTwUrpCOpz5eYK.jyTC2LeKo/gq9HYpDtD6.fMlHyLW.5h3fF4v.R19lX8W18KDvper1
Validate:
true
true
true

最新更新