【问题标题】:Why am I getting different results between C++ and PHP SHA256 hashes? [closed]为什么我在 C++ 和 PHP SHA256 哈希之间得到不同的结果? [关闭]
【发布时间】:2015-01-05 08:42:06
【问题描述】:

我正在尝试在 PHP 中生成一个 SHA256 哈希,该哈希将存储在数据库中并用于 C++ 程序的身份验证。

在 php 中,哈希是这样的:

$mail = strtoupper(utf8_decode('tester@tester.com'));
$password = strtoupper(utf8_decode('password'));

$email = hash_init('sha256');
         hash_update($email, $mail);
$mail  = strtoupper(hash_final($email)); // In C++ the output is uppercase

$sha   = hash_init('sha256');
         hash_update($sha, $mail);
         hash_update($sha, ':');
         hash_update($sha, $password);
$pass  = hash_final($sha);

或者换一种写法:

$pass = hash('sha256', strtoupper(hash('sha256', $mail)).':'.$password);

在 C++ 中,过程如下所示:

Utf8ToUpperOnlyLatin(email);
Utf8ToUpperOnlyLatin(password);

SHA256Hash email;
email.UpdateData(name);
email.Finalize();

SHA256Hash sha;
sha.UpdateData(ByteArrayToHexStr(email.GetDigest(), email.GetLength()));
sha.UpdateData(":");
sha.UpdateData(password);
sha.Finalize();

return ByteArrayToHexStr(sha.GetDigest(), sha.GetLength(), true);

还有方法:

std::string ByteArrayToHexStr(uint8 const* bytes, uint32 arrayLen, bool reverse /* = false */)
{
    int32 init = 0;
    int32 end = arrayLen;
    int8 op = 1;

    if (reverse)
    {
        init = arrayLen - 1;
        end = -1;
        op = -1;
    }

    std::ostringstream ss;
    for (int32 i = init; i != end; i += op)
    {
        char buffer[4];
        sprintf(buffer, "%02X", bytes[i]);
        ss << buffer;
    }

    return ss.str();
}

bool Utf8ToUpperOnlyLatin(std::string& utf8String)
{
    std::wstring wstr;
    if (!Utf8toWStr(utf8String, wstr))
        return false;

    std::transform(wstr.begin(), wstr.end(), wstr.begin(), wcharToUpperOnlyLatin);

    return WStrToUtf8(wstr, utf8String);
}

SHA256Hash::SHA256Hash()
{
    SHA256_Init(&mC);
    memset(mDigest, 0, SHA256_DIGEST_LENGTH * sizeof(uint8));
}

void SHA256Hash::UpdateData(const uint8 *dta, int len)
{
    SHA256_Update(&mC, dta, len);
}

void SHA256Hash::UpdateData(const std::string &str)
{
    UpdateData((uint8 const*)str.c_str(), str.length());
}

void SHA256Hash::Initialize()
{
    SHA256_Init(&mC);
}

void SHA256Hash::Finalize(void)
{
    SHA256_Final(mDigest, &mC);
}

使用这两种方法的输出是:

C++: 09FEBAB417CF2FA563AC89963519CCAC53D5F556F8BF20D7EEB818A0584A514E
PHP: 4e514a58a018b8eed720bff856f5d553accc19359689ac63a52fcf17b4bafe09

如果我要交换

$mail  = strtoupper(hash_final($email)); // In C++ the output is uppercase

$mail  = hash_final($email);

PHP 输出将是

89ba15a964331258bcc763f44473c492854bf9c2694cc2306da64ccef8ffeab2

为什么我似乎无法让 PHP 和 C++ 产生相同的结果?

谢谢。

【问题讨论】:

  • 补充一点说明,我希望 PHP 产生与使用 C++ 方法相同的结果。
  • 在您的 C++ 实现中,您有一个“reverse”参数,对于最终输出,该参数设置为 true。在第一对输出中,两者是不同的,因为 C++ 是相反的。似乎是对的,我错过了什么吗?
  • Geoffliu,把它写成答案,这样我就可以接受了。这确实是正确的。我不敢相信我错过了!时间太长,咖啡不够:)

标签: php c++ hash sha256


【解决方案1】:

C++ 实现使用哈希返回的字节的倒数。两种方法都是正确的,但输出与轻微疏忽不符。感谢 Geoffliu 指出这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 2014-04-08
    • 1970-01-01
    • 2015-12-27
    • 2011-06-08
    • 2012-10-19
    相关资源
    最近更新 更多