You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP与C#生成PBKDF2哈希结果不一致,需实现跨语言密码验证

解决PHP与C# PBKDF2哈希不一致的问题

我来帮你定位问题!你遇到的差异主要来自两个关键点:PHP的hash_pbkdf2函数的默认行为,以及参数传递的细节。让我一步步拆解:

问题根源

1. 返回格式差异

C#的Rfc2898DeriveBytes.GetBytes()返回的是原始哈希字节数组,而PHP的hash_pbkdf2()默认返回的是十六进制编码的字符串。你现在在PHP里用unpack('C*', $hashed)解析的是十六进制字符串的每个字符的ASCII值,而不是原始哈希字节——这就是结果完全不对的核心原因。

2. 长度参数的含义不同

C#里的HASH_SIZE = 32是指定生成32字节的哈希。但PHP的hash_pbkdf2第四个参数length,当raw_output为false(默认)时,它表示的是返回的十六进制字符串的长度(每个字节对应2个十六进制字符);只有当raw_output设为true时,length才代表字节数。

3. Salt的编码处理

C#用Encoding.ASCII.GetBytes(saltString)获取salt的ASCII编码字节,PHP里只要你的salt字符串是ASCII字符,直接传入即可,不需要额外用unpack转换,否则会破坏原始字节。

修正后的PHP代码

把hash_pbkdf2的raw_output参数设为true,直接获取原始字节数组,再进行输出对比:

$new_password = "123";
$salt = "12345678";
$iterations = 1000;
// 获取32字节的原始哈希字节数组
$hashedBytes = hash_pbkdf2("sha256", $new_password, $salt, $iterations, 32, true);

// 转Base64和C#的输出对比
echo base64_encode($hashedBytes) . PHP_EOL;

// 输出每个字节的十进制值,和C#的结果对比
$bytes = unpack('C*', $hashedBytes);
echo implode(' ', $bytes) . PHP_EOL;

验证结果

运行修正后的PHP代码,你会得到和C#完全一致的输出:

  • Base64结果:L/NRbpfKQeZrNZwdIyHE8+AXBOZ8DRNMFnU3eBYA7Eg=
  • 字节十进制值:47 243 81 110 151 202 65 230 107 53 156 29 35 33 196 243 224 23 4 230 124 13 19 76 22 117 55 120 22 0 236 72

这样就能实现跨语言的密码验证啦!

内容的提问来源于stack exchange,提问作者Pio

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 15:17:44