将密码验证从ASP迁移到PHP


Migrating password auth from ASP to PHP

我在将一个ASP站点的用户帐户迁移到Drupal时遇到了一些问题。

ASP站点通过HashEncode(password +Salt)创建密码哈希

我试图找出哪个是php中的等效函数,所以我可以在我们的drupal密码模块中匹配它。

有人做了一个体面的尝试http://forums.overclockers.com.au/showthread.php?t=632736&page=2,但它不工作。

我听说HashEncode是sha1,但我不认为这是情况。在另一个站点上,它显示两个输出不相同,我已经在我的本地确认了php部分。

HashEncode("ABCD") = A11D4F0A70B882D58494B188DA0430CF4F17CFA8
sha1('ABCD') = fb2f85c88567f3c8ce9b799c7c54642d0c7b41f6

有没有人知道ASP HashEncode是如何工作的,以及我如何在php中重现它,以便我可以跨用户迁移?

提前感谢!

它通常是HMACSHA1散列,但技巧是确保其编码为utf16。下面是一个javascript实现:

function str2rstr_utf16le(input) {
  var output = [],
      i = 0,
      l = input.length;
  for (; l > i; ++i) {
    output[i] = String.fromCharCode(
      input.charCodeAt(i)        & 0xFF,
      (input.charCodeAt(i) >>> 8) & 0xFF
    );
  }
  return output.join('');
}
//utf 16 encoding is important
var pwd = str2rstr_utf16le("test");
var hash = CryptoJS.HmacSHA1(pwd, pwd);
var encodedPassword = CryptoJS.enc.Base64.stringify(hash);
alert(encodedPassword);

正如您所链接的论坛上已经提到的,尝试找到HashEncode函数的源代码,看看那里究竟发生了什么。也许ASP正在使用SHA2,它可以有多个密钥长度(例如SHA256/SHA512)。

但是您也可以删除所有密码,因此您的用户需要在新软件上重新创建它们。这样,所有密码都将使用PHP的函数生成。

使用SHA256 + salt的例子:

/**
 * generate salted password
 * @param string $plainTextPassword
 * @param string $salt default = NULL (create new salt)
 * @param int $saltLength default = 9
 * @return string password-hash
 */
function passwordHash($plainTextPassword, $salt = null, $saltLength = 9)
{
    if(is_null($salt))
    {
        // create new salt
        $salt = substr(sha1(uniqid(mt_rand(), true)), 0, $saltLength);
    }
    else
    {
        $salt = substr($salt, 0, $saltLength);
    }
    return $salt . hash('sha256', $salt . $plainTextPassword);
}