You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 5中Pbkdf2使用To/FromBase64String出现字节不一致问题求助

问题成因
  • 核心错误:passwordCreator 方法中没有对「传入的合法salt」和「需要新生成的salt」做分支处理,不管是否传入了有效salt,都会执行rngCsp.GetNonZeroBytes(salt)用随机数覆盖salt的原始内容。校验阶段传入的、从存储值解码得到的salt字节直接被随机值替换,导致生成的哈希和之前存储的哈希完全不匹配。
  • 次要逻辑错误:passwordChecker 方法中先执行Convert.FromBase64String(salt)再判断user.Salt是否为null,当用户没有存储salt时会直接抛出空引用异常,而非正常返回false。
修复方案

调整passwordCreator的逻辑,将随机填充salt的代码移入「新生成salt」的分支中,仅当没有传入合法salt时才生成随机salt;同时调整passwordChecker的空校验顺序,避免空引用异常。修复后代码如下:

private string passwordCreator(string Password, byte[] salt = null, bool needsOnlyHash = false)
{
    if(salt == null || salt.Length != 32)
    {
        salt = new byte[256/8];
        // 仅当新生成salt时才填充随机值
        using(var rngCsp = new RNGCryptoServiceProvider())
        {
            rngCsp.GetNonZeroBytes(salt);
        }
    }

    string pw = Convert.ToBase64String(KeyDerivation.Pbkdf2(
                        password: Password, 
                        salt: salt, 
                        prf: KeyDerivationPrf.HMACSHA256, 
                        iterationCount: 100000, 
                        numBytesRequested: 256/8
                    ));

    if(needsOnlyHash) return pw;

    return $"{pw}:{Convert.ToBase64String(salt)}";
} 

private bool passwordChecker(DimUser user, string Password)
{
    // 先做空校验,避免后续操作抛出异常
    if(user == null || string.IsNullOrEmpty(user.UserPw) || string.IsNullOrEmpty(user.Salt))
    {
        return false;
    }

    string pw = user.UserPw; 
    string salt = user.Salt; 
    var saltedByte = Convert.FromBase64String(salt);
    var passwordSubmitted = passwordCreator(Password,saltedByte,true);
    return String.Compare(pw, passwordSubmitted) == 0;
}

内容的提问来源于stack exchange,提问作者John Lee Hedge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 23:06:02