密码哈希函数从Python移植到.net 8

问题描述 投票:0回答:1

我们有一个用 python 编写的旧软件系统,它使用以下密码哈希函数:

import hashlib, binascii, os
 
def hash_password(password):
    """Hash a password for storing."""
    salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
    pwdhash = hashlib.pbkdf2_hmac('sha512', password.encode('utf-8'), 
                                salt, 100000)
    pwdhash = binascii.hexlify(pwdhash)
    return (salt + pwdhash).decode('ascii')
 
def verify_password(stored_password, provided_password):
    """Verify a stored password against one provided by user"""
    salt = stored_password[:64]
    stored_password = stored_password[64:]
    pwdhash = hashlib.pbkdf2_hmac('sha512', 
                                  provided_password.encode('utf-8'), 
                                  salt.encode('ascii'), 
                                  100000)
    pwdhash = binascii.hexlify(pwdhash).decode('ascii')
    return pwdhash == stored_password

我们尝试将此代码迁移到.net 8,但无法获得正确的结果 => python 中生成的哈希值不等于 C# 中生成的哈希值

有人知道我们的方法可能有什么问题吗?

这是我们尝试过的:

public string HashPassword(string password)
    {
        var salt = Encoding.ASCII.GetBytes(GenerateRandomString(60));

        using var pbkdf2 = new Rfc2898DeriveBytes(
            Encoding.UTF8.GetBytes(password),
            salt,
            100000,
            HashAlgorithmName.SHA512);
        var hashedPassword = pbkdf2.GetBytes(64);

        return Encoding.ASCII.GetString(salt.Concat(hashedPassword).ToArray());
    }

    public bool VerifyPassword(string password, string hash)
    {
        var salt = hash[..64];
        var passwordHash = Encoding.UTF8.GetBytes(hash[64..]);
        
        using var pbkdf2 = new Rfc2898DeriveBytes(
            Encoding.UTF8.GetBytes(password),
            Encoding.ASCII.GetBytes(salt),
            100000,
            HashAlgorithmName.SHA512);
        var hashedPassword = pbkdf2.GetBytes(64);
        
        return hashedPassword.SequenceEqual(passwordHash);
    }

private string GenerateRandomString(int length)
    {
        var sb = new StringBuilder();  
        var random = new Random();

        for (int i = 0; i < length; i++)
        {
            double flt = random.NextDouble();
            int shift = Convert.ToInt32(Math.Floor(25 * flt));
            char letter = Convert.ToChar(shift + 65);
            sb.Append(letter);  
        }

        return sb.ToString();
    }
python .net hash cryptography
1个回答
0
投票

感谢您的帮助。我设法找到解决方案。

public string HashPassword(string password)
    {
        var salt = HexDigest(SHA256.HashData(RandomNumberGenerator.GetBytes(30)));

        var hashedPassword = ComputeHmacSha512Hash(password, salt);

        return salt + HexDigest(hashedPassword);
    }

    public bool VerifyPassword(string passwordToVerify, string saltPasswordHash)
    {
        var salt = saltPasswordHash[..64];
        var password = saltPasswordHash[64..];
        
        var hashedPassword = ComputeHmacSha512Hash(passwordToVerify, salt);
        
        return password.SequenceEqual(HexDigest(hashedPassword));
    }

    private static byte[] ComputeHmacSha512Hash(string password, string salt)
    {
        using var pbkdf2 = new Rfc2898DeriveBytes(
            Encoding.UTF8.GetBytes(password),
            Encoding.ASCII.GetBytes(salt),
            100000,
            HashAlgorithmName.SHA512);
        return pbkdf2.GetBytes(64);
    }

    private static string HexDigest(byte[] bytes)
    {
        return BitConverter.ToString(bytes).Replace("-", "").ToLower();
    }
© www.soinside.com 2019 - 2024. All rights reserved.