使用Ruby验证用Blowfish加密的PHP密码

6

我正在将一个用PHP编写的应用程序转换为Ruby。在加密密码时,PHP应用程序使用以下代码:

if($method == 2 && CRYPT_BLOWFISH) return crypt($pass, '$2a$07$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxx$');

我假设这是使用Blowfish实现。这里的x都是a-zA-Z0-9字符。
Ruby中的Blowfish实现使用以下语法(取自http://crypt.rubyforge.org/blowfish.html):
blowfish = Crypt::Blowfish.new("A key up to 56 bytes long")
plainBlock = "ABCD1234"
encryptedBlock = blowfish.encrypt_block(plainBlock)

我没有一个长度为56字节或更少的字符串,并且从PHP版本中也不清楚应该是什么。那么,我该如何编写一个Ruby函数来加密密码,以给出与PHP相同的结果?
1个回答

4
PHP代码正在使用盐值$2a$07$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxx$进行哈希处理$pass,如果设置了CRYPT_BLOWFISH(CRYPT_BLOWFISH == 1)。该盐必须遵循PHP文档中指定的格式("$2a$",两位数字成本参数,"$",以及来自字母表"./0-9A-Za-z"的22个数字)。
我不确定您是否可以使用所提到的库来完成此操作,但您可以改用bcrypt-ruby
对于您的代码,可以像这样进行处理,我正在使用PHP示例中的相同数据(http://php.net/manual/en/function.crypt.php),只取盐的前29个字符,因为超出此范围PHP会忽略它:
require 'bcrypt-ruby'
pass = "rasmuslerdorf" # Here you should put the $pass from your PHP code
salt = '$2a$07$usesomesillystringfors' # Notice no $ at the end. Here goes your salt
hashed_password = BCrypt::Engine.hash_secret(pass,salt) # => "$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi"

这将为您提供与PHP示例相同的输出。如果您的盐太长,只需取前29个字符($2a$07$加上接下来的22个额外字符)。

我测试了PHP的行为,如果盐太长(总长度超过29个字符),则其余部分将被忽略;如果盐太短,则返回0。例如,在PHP中:

<?php
  crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$') 
  // returns $2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi

  crypt('rasmuslerdorf', '$2a$07$usesomesillystringfors')
  // returns $2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi

  crypt('rasmuslerdorf', '$2a$07$usesomesilly')
  // returns 0 because the salt is not long enough
?>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接