2014-11-08 58 views
1

我試圖在PHP中生成一個SHA256哈希,它將存儲在數據庫中,並用於通過C++程序進行身份驗證。爲什麼我在C++和PHP SHA256哈希之間得到不同的結果?

在PHP中的散列看起來是這樣的:

$mail = strtoupper(utf8_decode('[email protected]')); 
$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++產生相同的結果?

謝謝。

+0

要添加一點澄清,我希望PHP產生與使用我的C++方法相同的結果。 – Epicurus4 2014-11-08 17:54:11

+0

在您的C++實現中,您有一個「反向」參數,該參數在最終輸出中設置爲true。在第一對輸出中,這兩個是不同的,因爲C++是相反的。似乎是對的,我錯過了什麼? – geoffliu 2014-11-08 19:51:59

+0

Geoffliu,寫這個答案,我可以接受它。這確實是正確的。我不敢相信我錯過了!太多時間了,沒有足夠的咖啡:) – Epicurus4 2014-11-08 19:54:54

回答

1

C++實現使用了散列返回的字節的反轉。這兩種方法都是正確的,但是產出不匹配會導致輕微的疏漏。感謝Geoffliu指出了這一點。

相關問題