在PHP中生成哈希以匹配T-SQL HASHYTES输出



我需要在PHP中生成一个哈希,该哈希与T-SQL中HASHYTES函数的输出相匹配。

以下是最初用于在T-SQL:中生成哈希的代码

declare @input varchar(15) =  [this is the incoming value entered by the user]
declare @salt binary(32) =  CRYPT_GEN_RANDOM(32)
declare @saltchars nvarchar(32) = cast(@salt as nvarchar(32) )
declare @inputchars nvarchar(50) = cast(@input as nvarchar(50) )
declare @sha binary(32) = HASHBYTES('SHA2_256', @passwordchars + @saltchars)

对于输入"0";pete1234matt";,我们得到的输出是:

salt =  0x75D6215CA44339B645E86BE790FF562D3EE4BC51034FDC6A9697F767BB961B5B
sha  =  0x979EEAC93B5F6624269634202D9F3B5B8008113B03A83D104784184E0F9361F8

现在,这是我编写的PHP代码,我接受提供的和输入,然后将它们编码为UTF-16LE,正如我所期望的转换为nvarchar所做的那样。这是正确的吗?

$password = 'pete1234matt'; 
$salt = 0x75D6215CA44339B645E86BE790FF562D3EE4BC51034FDC6A9697F767BB961B5B;
$saltchars = mb_convert_encoding($salt, 'UTF-16LE');
$passwordchars = mb_convert_encoding($password, 'UTF-16LE');
$sha = hash('sha256', $passwordchars . $saltchars);
//$sha ==   17b87bd0491f32f1e474ad9293e2fe5db56ed0a5c9939435f0984fdc04806dc5
//Expected: 979EEAC93B5F6624269634202D9F3B5B8008113B03A83D104784184E0F9361F8

我倾向于盐有编码问题,但不太清楚哪里出了问题。谁能对字符编码有更多的了解;T-SQl在这里帮我一把!!

  1. 您使用的十六进制表示法仅适用于PHP中的数字。您希望将其作为字符串放入并调用hex2bin()
  2. 我不知道你为什么要把盐转化为UTF16,但不要这么做
$password = 'pete1234matt'; 
$salt = hex2bin('75D6215CA44339B645E86BE790FF562D3EE4BC51034FDC6A9697F767BB961B5B');
$saltchars = $salt;
$passwordchars = mb_convert_encoding($password, 'UTF-16LE');
$sha = hash('sha256', $passwordchars . $saltchars);
//Expected: 979EEAC93B5F6624269634202D9F3B5B8008113B03A83D104784184E0F9361F8
var_dump($sha);

输出:

string(64) "979eeac93b5f6624269634202d9f3b5b8008113b03a83d104784184e0f9361f8"

不要养成在没有明确指定源编码的情况下调用任何字符集转换函数的习惯。PHP字符串本质上只是没有编码概念的字节数组。PHP的配置设置控制假定的默认字符集,但使用正确解码的十六进制调用mb_convert_encoding($salt, 'UTF-16LE');将根据PHP默认值(可能是UTF8或ISO-8859-1(解释字符串,并将其转换为mojibake。实际上,当字符串已经是UTF16LE时。

例如:

$test_8   = 'hello 🍆';
$test_16  = mb_convert_encoding($test_8, 'UTF-16LE', 'UTF-8');
$mojibake = mb_convert_encoding($test_16, 'UTF-16LE');
var_dump(
bin2hex($test_8),
bin2hex($test_16),
bin2hex($mojibake)
);

输出:

string(20) "68656c6c6f20f09f8d86"
string(32) "680065006c006c006f0020003cd846df"
string(64) "68000000650000006c0000006c0000006f000000200000003c003f0046003f00"

最新更新