Asp.net core mvc BCrypt PasswordHasher:-FormatException:输入不是有效的Base-64字符串

Asp.net core mvc BCrypt PasswordHasher:-FormatException:输入不是有效的Base-64字符串,asp.net-core-mvc,base64,asp.net-identity,bcrypt,Asp.net Core Mvc,Base64,Asp.net Identity,Bcrypt,我浏览了几乎所有关于这个问题的相关问题,没有找到类似的情况或下面问题的可靠答案 问题: 我正在做一个ASP.NET核心MVC项目。我使用身份UI进行用户身份验证和授权。我已经重写了Idetity用户默认密码哈希器:'PasswordHasher',它也是通过'IPasswordHasher'接口实现的(ASP.NET Identity Version 2:PBKDF2和HMAC-SHA1,128位salt,256位子键,1000次迭代),并实现了我自己的类,如下所示: BCryptPasswor

我浏览了几乎所有关于这个问题的相关问题,没有找到类似的情况或下面问题的可靠答案

问题: 我正在做一个ASP.NET核心MVC项目。我使用身份UI进行用户身份验证和授权。我已经重写了Idetity用户默认密码哈希器:
'PasswordHasher'
,它也是通过
'IPasswordHasher'
接口实现的(ASP.NET Identity Version 2:PBKDF2和HMAC-SHA1,128位salt,256位子键,1000次迭代),并实现了我自己的类,如下所示:

BCryptPasswordHasher.cs

using Microsoft.AspNetCore.Identity;
using System;
using System.Text;

namespace WATERrhythmWeb
{
    public class BCryptPasswordHasher<TUser> : PasswordHasher<TUser> where TUser : class
    {
        readonly BCryptPasswordSettings _settings;
        public BCryptPasswordHasher()
        {
        }
        public BCryptPasswordHasher(BCryptPasswordSettings settings)
        {
            _settings = settings;
        }

        public override PasswordVerificationResult VerifyHashedPassword(TUser user, string hashedPassword, string providedPassword)
        {
            if (hashedPassword == null) { throw new ArgumentNullException(nameof(hashedPassword)); }
            if (providedPassword == null) { throw new ArgumentNullException(nameof(providedPassword)); }

            byte[] decodedHashedPassword = Convert.FromBase64String(hashedPassword);

            // read the format marker from the hashed password
            if (decodedHashedPassword.Length == 0)
            {
                return PasswordVerificationResult.Failed;
            }

            // ASP.NET Core uses 0x00 and 0x01, so we start at the other end
            if (decodedHashedPassword[0] == 0xFF)
            {
                if (VerifyHashedPasswordBcrypt(decodedHashedPassword, providedPassword))
                {
                    // This is an old password hash format - the caller needs to rehash if we're not running in an older compat mode.
                    return _settings.RehashPasswords
                        ? PasswordVerificationResult.SuccessRehashNeeded
                        : PasswordVerificationResult.Success;
                }
                else
                {
                    return PasswordVerificationResult.Failed;
                }
            }

            return base.VerifyHashedPassword(user, hashedPassword, providedPassword);
        }

        private static bool VerifyHashedPasswordBcrypt(byte[] hashedPassword, string password)
        {
            if (hashedPassword.Length < 2)
            {
                return false; // bad size
            }

            //convert back to string for BCrypt, ignoring first byte
            var storedHash = Encoding.UTF8.GetString(hashedPassword, 1, hashedPassword.Length - 1);

            return BCrypt.Net.BCrypt.Verify(password, storedHash);
        }

        public override string HashPassword(TUser user, string password)
        {
            //throw new NotImplementedException();
            return BCrypt.Net.BCrypt.HashPassword(password);
        }
    }
}

  • 然而,当同一个用户尝试登录时,我得到了 以下错误。(很明显,当哈希密码 在数据库中使用用户输入密码进行验证):

    FormatException:输入不是有效的Base-64字符串,因为它
    包含一个非基64字符、两个以上的填充字符或
    填充字符中的非法字符。


  • 错误来自中的以下代码行
    PasswordVerificationResult VerifyHashedPassword(用户、字符串hashedPassword、字符串提供的密码)
    code>PasswordHasher的方法 类,其中将
    hashedPassword
    转换为
    base64字符串

    byte[] decodedHashedPassword = Convert.FromBase64String(hashedPassword);
    

有人能给我解释一下如何解决这个问题吗?
谢谢。

我不太确定您在这里要做什么,但是如果这
$2a$10$vuhdbnkllpltz4d4vgg.cHOx3O2jMAaeH5mFvNTVuf4wqoEtvRx442
是您试图解码的
Convert.FromBase64String(hashedPassword)
那么它必须失败。hashedPassword不是base64字符串。只需查找base64编码,您将看到
$
不属于base64字符集。这两个角色在这里都是一个辩论者。我也不确定数据库中的散列密码转换为原始密码意味着什么。您无法从哈希还原原始文件。非常感谢您的回复。是的,现在只有我意识到这里的代码之外还有一个错误。正如你所说,散列不能被解码(单向)。但我在这篇文章中遵循了这一点。我也对这里的方法感到困惑。
byte[] decodedHashedPassword = Convert.FromBase64String(hashedPassword);