«Хеширование паролей C# PBKDF2 в Django-совместимом формате (pbkdf2_sha256), проблемы с проверкой паролей»

Я работаю над приложением на C#, где мне нужно проверить пароли пользователей, которые были хэшированы с помощью PBKDF2 algorithm (pbkdf2_sha256) от Django. Пароли хранятся в формате:

pbkdf2_sha256$iterations$salt$hash

Например: pbkdf2_sha256$870000$wyEbTcPvbTOet9npIyftqZ$Xv274JNGq1ZMQQHzmZx8q5n+Nly/U5Wf1WYLRO4d8YY=

Я пытаюсь воспроизвести тот же процесс на C#, используя Rfc2898DeriveBytes для проверки пароля. Однако я сталкиваюсь с проблемой, когда вычисленный хэш не совпадает с хранимым хэшем, даже если введенный пароль верен.

Вот код на C#, который я использую для проверки пароля:

    public static bool VerifyPassword(string enteredPassword, string storedPasswordHash) 
    { 
            var parts = storedPasswordHash.Split('$');
            if (parts.Length != 4 || parts[0] != "pbkdf2_sha256")
            {
                Console.WriteLine("Invalid password format.");
                return false;
            }
    
            string iterationsStr = parts[1];
            string salt = parts[2]; 
            string storedHash = parts[3]; 
    
            if (!int.TryParse(iterationsStr, out int iterations))
            {
                Console.WriteLine("Invalid iterations count.");
                return false;
            }
    
            byte[] saltBytes = DecodeBase64Salt(salt);
            if (saltBytes == null)
            {
                return false;
            }
    
            byte[] passwordBytes = Encoding.UTF8.GetBytes(enteredPassword);
            byte[] computedHashBytes;
    
           
            using (var pbkdf2 = new Rfc2898DeriveBytes(passwordBytes, saltBytes, iterations, HashAlgorithmName.SHA256))
            {
                computedHashBytes = pbkdf2.GetBytes(32); 
            }
    
            string computedHash = Convert.ToBase64String(computedHashBytes);
            Console.WriteLine($"Computed Hash: {computedHash}");
            return storedHash == computedHash;
        }
    
        private static byte[] DecodeBase64Salt(string salt)
        {
            switch (salt.Length % 4)
            {
                case 2: salt += "=="; break;
                case 3: salt += "="; break;
            }
    
            try
            {
                return Convert.FromBase64String(salt);
            }
            catch (FormatException)
            {
                Console.WriteLine("Error decoding Base64 salt.");
                return null;
            }
        }

Я декодирую соль из строки Base64 и использую Rfc2898DeriveBytes с SHA256, но полученный хэш не совпадает с тем, что хранится в базе данных. Я также пробовал регулировать подстановку Base64, но проблема сохраняется.

Кто-нибудь знает, что может быть причиной несоответствия между вычисленными и сохраненными хэшами? Как я могу исправить проверку пароля, чтобы она была совместима с PBKDF2 реализацией Django?

Вернуться на верх