为什么我的密码检查器不起作用? C#

Why does my password checker not work? c#

我正在尝试为我的应用创建一个登录系统,并希望使用 sha256 和 salt 来存储密码。问题是当我再次用相同的盐对相同的密码进行哈希处理以检查它时,我得到了不同的结果。这是两个函数的代码


 String[] securePassword(String password)
        {
            String[] result = new string[2];
            byte[] salt = new byte[32];
            System.Security.Cryptography.RNGCryptoServiceProvider.Create().GetBytes(salt);
            byte[] plainTextBytes =  UnicodeEncoding.Unicode.GetBytes(password);
          
            byte[] combinedBytes = new byte[plainTextBytes.Length + salt.Length];
            System.Buffer.BlockCopy(plainTextBytes, 0, combinedBytes, 0, plainTextBytes.Length);
            System.Buffer.BlockCopy(salt, 0, combinedBytes, plainTextBytes.Length, salt.Length);
            System.Security.Cryptography.HashAlgorithm hashAlgo = new System.Security.Cryptography.SHA256Managed();
            byte[] hash = hashAlgo.ComputeHash(combinedBytes);

            result[0] = Convert.ToBase64String(hash);
            result[1] = Convert.ToBase64String(salt);

            return result;
        }


bool check_password(String password_introduced,String Password,String Salt)
        {
            byte[] salt = Convert.FromBase64String(Salt);
            byte[] plainTextBytes = UnicodeEncoding.Unicode.GetBytes(password_introduced);

            byte[] combinedBytes = new byte[plainTextBytes.Length + salt.Length];
            System.Buffer.BlockCopy(plainTextBytes, 0, combinedBytes, 0, plainTextBytes.Length);
            System.Buffer.BlockCopy(salt, 0, combinedBytes, plainTextBytes.Length, salt.Length);
            System.Security.Cryptography.HashAlgorithm hashAlgo = new System.Security.Cryptography.SHA256Managed();
            byte[] hash = hashAlgo.ComputeHash(combinedBytes);
            String result = Convert.ToBase64String(hash);
            return (result == Password);
            
        }

好吧,你所拥有的对我有用。我清理了一些东西,包括删除重复代码 (DRY) 和标准化你的方法和参数的外壳。

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

namespace ConsoleApp1
{
    public class Program
    {
        static void Main()
        {
            string[] result = SecurePassword("foobar");
            bool valid = CheckPassword("foobar", result[0], result[1]);
        }

        static string[] SecurePassword(string password)
        {
            string[] result = new string[2];

            byte[] salt = new byte[32];
            RNGCryptoServiceProvider.Create().GetBytes(salt);
            byte[] plainTextBytes = UnicodeEncoding.Unicode.GetBytes(password);

            byte[] hash = CreateHash(plainTextBytes, salt);

            result[0] = Convert.ToBase64String(hash);
            result[1] = Convert.ToBase64String(salt);

            return result;
        }


        static bool CheckPassword(string password_introduced, string password, string originalSalt)
        {
            byte[] salt = Convert.FromBase64String(originalSalt);
            byte[] plainTextBytes = UnicodeEncoding.Unicode.GetBytes(password_introduced);

            byte[] hash = CreateHash(plainTextBytes, salt);

            string result = Convert.ToBase64String(hash);
            return (result == password);

        }

        static byte[] CreateHash(byte[] plainTextBytes, byte[] salt)
        {
            byte[] combinedBytes = new byte[plainTextBytes.Length + salt.Length];
            Buffer.BlockCopy(plainTextBytes, 0, combinedBytes, 0, plainTextBytes.Length);
            Buffer.BlockCopy(salt, 0, combinedBytes, plainTextBytes.Length, salt.Length);
            HashAlgorithm hashAlgo = new System.Security.Cryptography.SHA256Managed();
            byte[] hash = hashAlgo.ComputeHash(combinedBytes);
            return hash;
        }
    }
}

CheckPassword 的调用返回 true

请改用 BCrypt 等专用密码哈希函数。 SHA* 哈希不适用于哈希密码,因为它们速度太快,因此很容易被暴力破解,即使使用现成的 GPU(如今每秒大约 7 Giga SHA256)也是如此。

// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
string passwordHash =  BCrypt.HashPassword("my password");

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
bool isCorrect = BCrypt.Verify("my password", passwordHash);