如何将C#的VerifyPasswordHash方法转换为PHP以验证HMAC-SHA512密码哈希
Fixing the PHP Password Hash Verification for HMACSHA512
Let's fix your PHP implementation step by step — you've got a couple of key issues that are causing the hash mismatch with the C# original:
Key Problems in Your Current Code
- Reversed
hash_hmacparameters: In C#, you use the salt as the HMAC key and the password as the input data. Your PHP code has these reversed, passing the salt as the data and password as the key. - Unconverted hex strings: Your stored hash and salt are hexadecimal strings with a
0xprefix, but you're using them directly as plain strings instead of converting them to raw binary bytes (which is what the C# code relies on). - Unnecessary
utf8_encode: This function converts ISO-8859-1 to UTF-8, but C# usesEncoding.UTF8.GetBytesto directly encode the string to UTF-8 bytes. If your$passwordis already UTF-8 (which it should be), this function can introduce errors for non-ISO-8859-1 characters.
Corrected PHP Implementation
<?php $password = 'Password202!'; $storedHashHex = '0x0C3F6C5921CCD0305B2EDEDE1553B1DF55B87A9D55FEE3384A3833611BC40D106BBB48CCE1093AE35B9D0E3A1FE62E86186A6EC143BA00E53945E99C259B4913'; $storedSaltHex = '0xC62C5A645280DBCC615ED4A3E861D800B00A929856A9664B3AED50A06481ED19AFB09F74D3D7A9EA25327D93F23FDFBD2DE8CF3A75D65A3EA97290E0486F1F4322D2B5853AE6FE848E50355C35B62A993CF6689D9F9ABC861C5E7D88B099617E6A6C7792E285EFBB809FD69CD926C9BD9129AD1BE7DDB5DD459C2B9A2B945B31'; function VerifyPasswordHash(string $password, string $storedHashHex, string $storedSaltHex): bool { // Strip the 0x prefix and convert hex strings to raw binary bytes $storedSalt = hex2bin(ltrim($storedSaltHex, '0x')); $storedHash = hex2bin(ltrim($storedHashHex, '0x')); // Compute HMAC-SHA512: password as data, salt as the key (raw binary) $computedHash = hash_hmac('sha512', $password, $storedSalt, true); // Use timing-safe comparison to avoid timing attacks return hash_equals($storedHash, $computedHash); } // Test the verification $isValid = VerifyPasswordHash($password, $storedHashHex, $storedSaltHex); echo $isValid ? 'Password is valid!' : 'Password is invalid!'; ?>
Explanation of Changes
- Hex to Binary Conversion: We remove the
0xprefix withltrim, then usehex2binto convert the hex strings to raw binary — matching the byte arrays used in the C# code. - Correct
hash_hmacOrder: The parameters now follow the correct sequence: algorithm, input data (password), HMAC key (raw salt), andtrueto return raw binary output (matching C#'sComputeHashresult). - Timing-Safe Comparison:
hash_equalsensures the comparison takes the same amount of time regardless of how many characters match, preventing timing attacks that could expose password details.
内容的提问来源于stack exchange,提问作者Дидар Темирханов
相关产品推荐
相关产品推荐

