kmaragon / Konscious.Security.Cryptography

MIT License
202 stars 20 forks source link

Different hash result on different machines #32

Closed arwyl closed 4 years ago

arwyl commented 4 years ago

Can Argon2i return different results for the same input parameters on different machines?

a simple program for reproducing:

using Konscious.Security.Cryptography;
using System;
using System.Text;

namespace Argon2Test
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Input your password:");
            string password = Console.ReadLine();
            Console.WriteLine("Input salt bytes string (starting with 0x):");

            string saltBytesStr = Console.ReadLine();

            const int hashBytesCount = 16;

            byte[] pass = Encoding.Unicode.GetBytes(password);
            byte[] salt = StringToByteArray(saltBytesStr.Substring(2)); // remove 0x

            var res = GetHash(pass, salt, hashBytesCount);

            Console.WriteLine($"Initial password: {password}");
            Console.WriteLine($"Initial password bytes: 0x{ByteArrayToString(pass)}");
            Console.WriteLine($"Initial salt bytes: 0x{ByteArrayToString(salt)}");
            Console.WriteLine($"Result password hash bytes: 0x{ByteArrayToString(res)}");

        }

        static byte[] GetHash(byte[] input, byte[] salt, int hashBytesCount)
        {
            var argon2 = new Argon2i(input)
            {
                Salt = salt,
                Iterations = 30,
                DegreeOfParallelism = Environment.ProcessorCount,
                MemorySize = 2048
            };

            var hash = argon2.GetBytes(hashBytesCount);
            return hash;
        }

        static byte[] StringToByteArray(string hex)
        {
            int numberChars = hex.Length;
            byte[] bytes = new byte[numberChars / 2];
            for (int i = 0; i < numberChars; i += 2)
                bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
            return bytes;
        }

        static string ByteArrayToString(byte[] input)
        {
            var s = new StringBuilder(String.Empty);
            if (input != null)
            {
                foreach (byte b in input)
                {
                    s.Append(b.ToString("x2").ToLower());
                }
            }
            return s.ToString();
        }

    }
}

was tested on three different machines. results:

1) Input your password: r5sXN@KeZ1 Input salt bytes string (starting with 0x): 0x22d033d53b2457152147b1196b338203 Initial password: r5sXN@KeZ1 Initial password bytes: 0x72003500730058004e0040004b0065005a003100 Initial salt bytes: 0x22d033d53b2457152147b1196b338203 Result password hash bytes: 0x1952ae3cd1048af513689a10854d929b

2) Input your password: r5sXN@KeZ1 Input salt bytes string (starting with 0x): 0x22d033d53b2457152147b1196b338203 Initial password: r5sXN@KeZ1 Initial password bytes: 0x72003500730058004e0040004b0065005a003100 Initial salt bytes: 0x22d033d53b2457152147b1196b338203 Result password hash bytes: 0x09eeb4257e50b6ca1946ee54eb00509a

3) Input your password: r5sXN@KeZ1 Input salt bytes string (starting with 0x): 0x22d033d53b2457152147b1196b338203 Initial password: r5sXN@KeZ1 Initial password bytes: 0x72003500730058004e0040004b0065005a003100 Initial salt bytes: 0x22d033d53b2457152147b1196b338203 Result password hash bytes: 0x1f319b7d1ccc63859b2c3e49af1ef9d2

how can that be?

arwyl commented 4 years ago

package from nuget: Assembly Konscious.Security.Cryptography.Argon2, Version=1.2.1.0

arwyl commented 4 years ago

the problem was in Environment.ProcessorCount