.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
相关产品推荐
相关产品推荐

