簡體   English   中英

PHP和C#SHA256哈希返回不同的字符串

[英]PHP and C# SHA256 Hashes returning different strings

因此,我發現了一個像這樣的問題並得到了可接受的答案,因此我跳了起來,嘗試實施必要的更改。 但是由於某種原因,我仍然得到兩個不同的字符串,而且我不知道這是錯的。 我試圖評論已接受的答案以尋求幫助,但是我缺乏這樣做的聲譽。 所以,我想我會再問這個問題(那個問題也已經2歲了)。

讓我解釋一下我在做什么。

在PHP中...

$intermediatesalt = md5(uniqid(rand(), true));
$salt = substr($intermediatesalt, 0, 8);
$hashpassword = base64_encode(
hash('sha256', $salt . hash('sha256', $password), true)
);

$ hashpassword所在的行是從該問題的可接受答案中摘錄的。 我沒有寫任何這樣的php,我的朋友寫了。 我只了解編程來更改代碼,但是我無法用php創建任何東西,更不用說HTML了。

創建哈希后,哈希和鹽都存儲在數據庫中。

我正在使用的C#方法也來自我在這里找到的答案。

    public static string ComputeHash(string plainText, string salt)
    {
        // Convert plain text into a byte array.
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        byte[] saltBytes = Encoding.UTF8.GetBytes(salt);

        SHA256Managed hash = new SHA256Managed();

        // Compute hash value of salt.
        byte[] plainHash = hash.ComputeHash(plainTextBytes);

        byte[] concat = new byte[plainHash.Length + saltBytes.Length];

        System.Buffer.BlockCopy(saltBytes, 0, concat, 0, saltBytes.Length);
        System.Buffer.BlockCopy(plainHash, 0, concat, saltBytes.Length, plainHash.Length);

        byte[] tHashBytes = hash.ComputeHash(concat);

        // Convert result into a base64-encoded string.
        string hashValue = Convert.ToBase64String(tHashBytes);

        // Return the result.
        return hashValue;
    }

但是出於某種奇怪的原因,即使提出問題的人得到了他/她想要的東西,我仍然得到了不希望的結果。

這是加載播放器數據的代碼塊,然后將php生成的哈希密碼與c#生成的哈希密碼進行比較。

        // load the player based on the given email
        PlayerStructure.Player newPlayer = MySQL.loadPlayer(email);

        // compute a hash based on the given password and the retrieved salt
        // then, compare it to the hashed password on the database
        string hPassword = Program.ComputeHash(password, newPlayer.salt);

        if (newPlayer.password != hPassword)
        {
            sendStatusMsg(index, "Invalid password.");
            sendStatusMsg(index, "1: " + hPassword);
            sendStatusMsg(index, "2: " + newPlayer.password);

            return;
        }

MySQL.loadPlayer從數據庫加載哈希字符串和鹽字符串,而我不得不使用那些sendStatusMessage方法來打印字符串,因為這是針對服務器應用程序的,該應用程序最多需要15分鍾才能在調試模式下從數據庫加載數據。 因此,我改為運行調試exe,因此不會運行Console.WriteLine調用。 newPlayer.password是存儲在數據庫中的哈希密碼(使用php創建的密碼)。 hPassword是使用我借用的C#方法計算得出的哈希值。

鹽是e0071fa9,純文本密碼是“ test”。

這是我通過sendStatusMsg方法獲得的結果:

Invalid password.
1: 3QQyVEfmBN4kJJHsRQ307TCDYxNMpc4k3r3udBaVz8Y=
2: moHRVv9C0JvpdTk28xGm3uvPPuhatK2rAHXd5he4ZJI=

關於我可能做錯了什么的任何想法? 正如我之前所說,我只是在這里使用答案(幾乎逐字借用代碼),但仍然沒有得到想要的結果。 這是我引用的問題: 為什么我的PHP SHA256哈希值不等同於C#SHA256Managed哈希值

因為作為您要鏈接的問題的答案, hash默認情況下會返回一個十六進制編碼的字符串,而不是原始字節。 您將true作為第三個參數傳遞來覆蓋對hash的外部調用的此行為,但對於內部調用則沒有這樣做。

實際上,為什么首先要有兩個哈希? 內部哈希似乎根本沒有任何作用。

正如喬恩(Jon)先前所述,php稍有缺陷。 如果有人嘗試做這樣的事情,請知道

$hashpassword = base64_encode(
hash('sha256', $salt . hash('sha256', $password), true)
);

相對於

$hashpassword = base64_encode(
hash('sha256', $salt . hash('sha256', $password, true), true)
);

產生巨大的變化。 php的第二行是達到目的的。

我希望這有幫助!

在PHP上,請避免使用自己的哈希機制,除非您是安全/加密專家並且(更重要的是,知道您在做什么)。

很好地了解password_hash在PHP中的工作方式(如果使用不支持它的PHP版本-請對其進行升級),您可以始終使用Anthony Ferrara兼容性庫來獲得良好的效果:

https://github.com/ircmaxell/password_compat

如果關注他的博客,您將獲得一些有關所涉問題的提示:

http://blog.ircmaxell.com/search/label/安全性

:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM