【问题标题】:Password Hash does not match密码哈希不匹配
【发布时间】:2018-10-08 17:33:55
【问题描述】:

我无法登录用户,因为密码哈希不匹配。我究竟做错了什么。 保存密码哈希的我的 sql 服务器具有 nvarchar 的数据类型。我之前用过二进制数据类型,但是没用。

 private readonly MovieHubContext _context;
    public AuthRepository(MovieHubContext context)
    {
        _context = context;
    }

    //method is called when the user hits the login button
    public async Task<Users> Login(string username, string password)
    {
        //returns the username from the databse
        var user = await _context.Users.FirstOrDefaultAsync(x => x.UserName == username);
        if (user == null)
        {
            return null;
        }

        if (!VerifyPasswordHash(password, System.Text.Encoding.UTF8.GetBytes(user.PasswordHash),
            System.Text.Encoding.UTF8.GetBytes(user.PasswordSalt)))
            return null;
        return user;

    }
    // this method is used to verify the password 
    private bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)
    {
        using (var hmac = new System.Security.Cryptography.HMACSHA512(passwordSalt))
        {
            //changes the string into byte and them computes the hash
            byte[] computedHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
            for (int i = 0; i < computedHash.Length; i++)
            {
                //compares the hashed password(user input) with the hashed password from the database
                if (computedHash[i] != passwordHash[i])
                    return false;
            }
        }
        return true;
    }
    // This method is used to register the users
    public async Task<Users> Register(Users users, string password)
    {
        byte[] passwordHash, passwordSalt;
        CreatePasswordHash(password, out passwordHash, out passwordSalt);

        users.PasswordHash = System.Text.Encoding.UTF8.GetString(passwordHash);
        users.PasswordSalt = System.Text.Encoding.UTF8.GetString(passwordSalt);

        //save into database
        await _context.Users.AddAsync(users);
        await _context.SaveChangesAsync();

        return users;


    }

    private void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
    {
        using (var hmac = new System.Security.Cryptography.HMACSHA512())
        {
            passwordSalt = hmac.Key;
            passwordHash = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
        }
    }

    public async Task<bool> UserExists(string username)
    {
        if (await _context.Users.AnyAsync(x => x.UserName == username))
            return true;

        return false;
    }

这是我为注册和登录我的客户而编写的代码。我无法找到我做错了什么。

【问题讨论】:

    标签: c# asp.net-mvc authentication asp.net-core cryptography


    【解决方案1】:

    只需在注册/验证时将 UTF8.GetBytes 替换为 Convert.FromBase64String 并将 UTF8.GetString 替换为 Convert.ToBase64String

    public async Task<Users> Register(Users users, string password)
    {
        byte[] passwordHash, passwordSalt;
        CreatePasswordHash(password, out passwordHash, out passwordSalt);
    
        users.PasswordHash = Convert.ToBase64String(passwordHash);
        users.PasswordSalt = Convert.ToBase64String(passwordSalt);
    
        //save into database
        await _context.Users.AddAsync(users);
        await _context.SaveChangesAsync();
    
        return users;
    }
    

    public async Task<Users> Login(string username, string password)
    {
        //returns the username from the databse
        var user = await _context.Users.FirstOrDefaultAsync(x => x.UserName == username);
        if (user == null)
        {
            return null;
        }
    
        if (!VerifyPasswordHash(password, Convert.FromBase64String(user.PasswordHash),
            Convert.FromBase64String(user.PasswordSalt)))
            return null;
        return user;
    
    }
    

    您的无效结果的原因是您的GetString 正在返回一个包含不可打印字符的字符串,这些字符未正确地从数据库中保存/检索到数据库。

    只需打印出这些字符串,看看你会得到什么。

    相比之下,base64 编码可确保将字节数组转换为 安全 字符串,以便您可以安全地存储/检索它们。

    这是一个稍微修改过的版本(async & dbcontext 被移除),

    https://dotnetfiddle.net/fH5mXh

    【讨论】:

    • 非常感谢。我在转换数据时绊倒了。你的解释很清楚。
    【解决方案2】:

    在这里输入代码我遇到了同样的问题,因为我在sql server中以二进制(64)的数据类型存储数据然后我改变了

            public async Task<User> Login(string username, string password)
        {
            var user = await _context.Users.FirstOrDefaultAsync(x => x.Username == username);
            if(user == null)
            return null;
            if(!VerifyPasswordHash(password, user.PasswordHash, user.PasswordSalt))
            return null;
    
            return user;
        }
        public async Task<User> Register(User user, string password)
        {
            byte[] passwordHash, passwordSalt;
            CreatePasswordHash(password, out passwordHash, out passwordSalt);
            user.PasswordHash = passwordHash;
            user.PasswordSalt = passwordSalt;
    
            await _context.Users.AddAsync(user);
            await _context.SaveChangesAsync();
    
            return user;
        }
        private void CreatePasswordHash(string password, out byte[] passwordHash, out byte[] passwordSalt)
        {
            using (var hmaic = new System.Security.Cryptography.HMACSHA512())
            {
              passwordSalt = hmaic.Key;
              passwordHash = hmaic.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
            }
        }
        private bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)
        {
           using (var hmaic = new System.Security.Cryptography.HMACSHA512(passwordSalt))
            {             
              var computedHash = hmaic.ComputeHash(System.Text.Encoding.UTF8.GetBytes(password));
    
              for(int i =0; i < computedHash.Length; i++)
              {
                  if(computedHash[i] != passwordHash[i])
                  return false;
              }
    
              return true;
            }
    
        }
    

    【讨论】:

    • 您能否详细说明您所做的更改?
    猜你喜欢
    • 2015-04-05
    • 2013-05-19
    • 2012-07-05
    • 2016-08-27
    • 2015-05-11
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    • 1970-01-01
    相关资源
    最近更新 更多