使用C#生成sha512哈希值并在php中进行比较

3

我已经查找到了一个将PHP sha512哈希值与C#中的哈希值进行匹配的代码。目前,我正在寻找一种方法从在C#中生成的哈希值得到与PHP中相同的结果。我们正逐渐从asp.net转向PHP,并需要一种在数据库中检查密码的方法。以下是用于生成哈希值的C#代码。

// Create a hash from a pwd and salt using sha512
    public static string CreatePasswordHash(string _password, string _salt)
    {
        string saltAndPwd = String.Concat(_password, _salt);
        SHA512 sha512 = new System.Security.Cryptography.SHA512Managed();

        byte[] sha512Bytes = System.Text.Encoding.Default.GetBytes(saltAndPwd);

        byte[] cryString = sha512.ComputeHash(sha512Bytes);

        string hashedPwd = string.Empty;

        for (int i = 0; i < cryString.Length; i++)
        {
            hashedPwd += cryString[i].ToString("X");
        }

        return hashedPwd;
    }

在 PHP 中,我尝试过让它匹配,但似乎有几个字节的偏差。

function CreatePasswordHash($_password, $_salt)
    {            
        $saltAndPwd = $_password . $_salt;            
        $hashedPwd = hash('sha512', $saltAndPwd);      
        return strtoupper($hashedPwd);
    }

当使用相同的盐和密码时,以下是我得到的结果。第一个结果来自C#,第二个结果来自PHP:

60BB73FDA3FF7A444870C6D0DBC7C6966F8D5AD632B0A02762E0283051D7C54A5F4B01571D1A5BC8C689DBC411FEB92158383A56AFC6AE6074696AF36E16    
60BB73FDA3FF7A444870C6D0DBC7C609066F8D5AD632B0A02762E0283051D7C54A5F4B001571D1A5BC8C689DBC411FEB092158383A56AFC6AE6074696AF36E16

有什么想法,为什么它们不匹配?这与字节序有关吗?

这可能是编码不匹配吗? - Samuel Parkinson
1
你的C#代码出了问题,且吞噬了一些“0”。但是你应该迁移到更安全的密码哈希算法,不要再使用普通的SHA-512。相反,使用具有足够迭代次数的bcrypt算法。 - CodesInChaos
4个回答

6

尝试:

hashedPwd += cryString[i].ToString("X2");

编辑PHP代码:

function CreatePasswordHash($_password, $_salt)
{
    $saltAndPwd = $_password . $_salt;
    $hashedPwd = hash('sha512', $saltAndPwd);

    $hex_strs = str_split($hashedPwd,2);

    foreach($hex_strs as &$hex) {
        $hex = preg_replace('/^0/', '', $hex);
    }
    $hashedPwd = implode('', $hex_strs);

    return strtoupper($hashedPwd);
}

这将使它通过编辑 C# 工作,但我需要通过编辑 PHP 使其工作。密码已经存在于数据库中。 - xLilCasper

2
C#打印输出不包括前导零。
替换为:
hashedPwd += cryString[i].ToString("X");

使用

hashedPwd += cryString[i].ToString("X2");

这使得它通过编辑C#工作,我需要通过编辑php使其工作。密码已经在数据库中。 - xLilCasper
如果这些用户已经在数据库中,最好是彻底修复你的代码,并尽可能为受影响的用户请求密码重置。 - Samuel Parkinson
我同意,虽然我不确定我能否让CEO同意这种做法。但我们可以在每次他们登录时修复它。删除旧的密码哈希并替换为新的。 - xLilCasper

1
请确保在C#和PHP中使用相同的字符编码。 GetBytes返回的结果取决于编码方式,因此需要进行双重检查。 System.Text.Encoding.Default则依赖于操作系统的本地化设置。

0

你可以尝试使用open_ssl_digest

echo openssl_digest($saltAndPwd, 'sha512');

如果您的PHP版本大于等于5.3

您也可以使用hash_algos函数来查看系统支持哪些算法。

希望对您有所帮助。


open_ssl_digest 产生相同的结果。 - xLilCasper

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