有没有办法在 Asp.Net Core Identity 中将 PasswordHash 的数据类型从字符串更改为字节数组

Posted

技术标签:

【中文标题】有没有办法在 Asp.Net Core Identity 中将 PasswordHash 的数据类型从字符串更改为字节数组【英文标题】:Is there a way to change the Data Type of PasswordHash from String to Byte array in Asp.Net Core Identity 【发布时间】:2021-12-31 14:37:25 【问题描述】:

我正在最小化 API 项目中实现 asp.net 核心身份库,并且用户表的 PasswordHash 字段执行其默认哈希和加盐,但我想执行我的自定义哈希和加盐密码。 那么,如何将 PasswordHash 的类型从“string”更改为“byte[]”

此外,PasswordHash 字段不应实现任何默认散列机制

【问题讨论】:

不,因为这是来自 Microsoft.AspNetCore.Identity.EntityFrameworkCore 的实现。 为什么要更改该类型? 您可以用自己的实现替换IPasswordHasher。我不确定我是否会建议这种做法,除非您这样做是为了与单独的服务集成。 您不能将散列的byte[] 表示为string 吗?与替代方案相比,它不会那么令人头疼。 只需使用Convert.ToBase64StringConvert.FromBase64String 将字符串val 存储在数据库中即可。然后你可以创建任何你想要的字节[]。 【参考方案1】:

我做了这样的事情

注册时

 private void CreatePasswordHash(string Password, out byte[] PasswordHash, out byte[] PasswordSalt)
    
        using (var hmac = new HMACSHA512())
        
            PasswordSalt = hmac.Key;
            PasswordHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(Password));
        
    

那么,

 public async Task<ServiceResponse<AspNetUsers>> AddUser(AddUserDto user)
    
        var ServiceResponse = new ServiceResponse<AspNetUsers>();
        AspNetUsers Users = _mapper.Map<AspNetUsers>(user);
        try
        
            if (await UserExist(Users.UserName))
            
                ServiceResponse.Success = false;
                ServiceResponse.Message = "User Already Exist";
                return ServiceResponse;
            
            CreatePasswordHash(Users.PasswordHash, out byte[] PasswordMade, out byte[] PasswordSalt);

            Users.Id = CommonCode.NewGUID();
            Users.SecurityStamp = CommonCode.NewGUID();
            Users.ConcurrencyStamp = CommonCode.NewGUID();
            Users.PasswordHash = Convert.ToBase64String(PasswordMade);
            Users.PasswordSalt = PasswordSalt;
            var AddUser = await _context.Users.AddAsync(Users);
            await _context.SaveChangesAsync();
            ServiceResponse.Data = await _context.Users.SingleAsync(x => x.Id == Users.Id);
            ServiceResponse.Success = true;
            ServiceResponse.Message = "User successfully added!";
        
        catch (Exception ex)
        
            ServiceResponse.Success = false;
            ServiceResponse.Message = ex.Message;
        
        return ServiceResponse;
    

在登录时,我做了这样的事情。

        private bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)
    
        using (var hmac = new HMACSHA512(passwordSalt))
        
            var computeHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(password));
            for (int i = 0; i < computeHash.Length; i++)
            
                if (computeHash[i] != passwordHash[i])
                
                    return false;
                
            
            return true;
        
    

那么,

        public async Task<ServiceResponse<string>> Login(LoginInformation Credentials)
        
        var ServiceResponse = new ServiceResponse<string>();
        try
        
            var User = await _context.Users.FirstOrDefaultAsync(x => x.Email.ToLower() == Credentials.Email.ToLower());
                            
            if(User == null)
            ServiceResponse.Success = false;
            ServiceResponse.Message = "User not found.";
            
            else
            if(!VerifyPasswordHash(Credentials.Password, Convert.FromBase64String(User.PasswordHash), User.PasswordSalt))
            
                ServiceResponse.Success = false;
                ServiceResponse.Message = "Username Or Password Is Incorrect";
            
            else
                ServiceResponse.Data = "Login success"; 
                ServiceResponse.Success = true;
                ServiceResponse.Message = "Login is Successfull!";
            
        
        catch (Exception ex)
        
            ServiceResponse.Data = string.Empty;
            ServiceResponse.Success = false;
            ServiceResponse.Message = ex.Message;
        
        return ServiceResponse;
    

【讨论】:

以上是关于有没有办法在 Asp.Net Core Identity 中将 PasswordHash 的数据类型从字符串更改为字节数组的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 Asp.Net Core Identity 中将 PasswordHash 的数据类型从字符串更改为字节数组

有没有办法将元数据添加到 ASP.NET Core 中的所有 GET 端点?

有没有办法在 ASP.NET Core 2.1 中捕获对 Razor 页面不存在的自定义处理程序的 HTTP 请求?

Json 对象 Asp.net Core 3.1 的最大长度

ASP.NET Core 中的加密配置

强制在 ASP.NET Core 中具有查询参数的所有 Url