最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

.net - How to store PasswordHash and PasswordSalt correctly in DB - Stack Overflow

programmeradmin4浏览0评论

Below is HashingHelper.CreatePasswordHash() function I use to create passwordHash and passwordSalt during the Register action. I write this data into DB and when user wants to login I read from DB and call HashingHelper.VerifyPasswordHash() function to verify if ComputedHash() returned value matches the hash in DB.

On debug, I noticed while inserting passwordHash and passwordSalt into DB, it adds leading 0s for remaining space. I initially stored these two variables in DB as binary(500). Because of leading 0s it reproduces different hash and user can't login.

Example:

producedPasswordHash: {0,1,2,...,63}
storedPasswordHash: {0,1,2,...,63,0,0,....,0} (64 data and 436 leadings 0s)

public static class HashingHelper
{
    public static 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 static bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)
    {
        using (var hmac = new HMACSHA512(passwordSalt))
        {
            var computedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(password));

            for (int i = 0; i < computedHash.Length; i++)
            {
                if (computedHash[i] != passwordHash[i])
                {
                    return false;
                }
            }

            return true;
        }
    }
}

What is best practice for storing such data in DB?
Should I handle this before writing to DB?
Considering possible SHA-1024 req. in future, what are preferred sizes for hash and salt in DB?

Here states that even SHA-512 is overkill but post is from 2014.

Thanks for help,

Below is HashingHelper.CreatePasswordHash() function I use to create passwordHash and passwordSalt during the Register action. I write this data into DB and when user wants to login I read from DB and call HashingHelper.VerifyPasswordHash() function to verify if ComputedHash() returned value matches the hash in DB.

On debug, I noticed while inserting passwordHash and passwordSalt into DB, it adds leading 0s for remaining space. I initially stored these two variables in DB as binary(500). Because of leading 0s it reproduces different hash and user can't login.

Example:

producedPasswordHash: {0,1,2,...,63}
storedPasswordHash: {0,1,2,...,63,0,0,....,0} (64 data and 436 leadings 0s)

public static class HashingHelper
{
    public static 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 static bool VerifyPasswordHash(string password, byte[] passwordHash, byte[] passwordSalt)
    {
        using (var hmac = new HMACSHA512(passwordSalt))
        {
            var computedHash = hmac.ComputeHash(Encoding.UTF8.GetBytes(password));

            for (int i = 0; i < computedHash.Length; i++)
            {
                if (computedHash[i] != passwordHash[i])
                {
                    return false;
                }
            }

            return true;
        }
    }
}

What is best practice for storing such data in DB?
Should I handle this before writing to DB?
Considering possible SHA-1024 req. in future, what are preferred sizes for hash and salt in DB?

Here states that even SHA-512 is overkill but post is from 2014.

Thanks for help,

Share Improve this question edited Mar 31 at 12:35 Basheer Jarrah 5613 silver badges15 bronze badges asked Mar 31 at 12:25 WowDogeCodeWowDogeCode 291 silver badge7 bronze badges 6
  • 2 What's wrong with varbinary(500) along with separate salt and algorithm columns? – Charlieface Commented Mar 31 at 12:44
  • 4 First of all, you shouldn't use SHA for hashing passwords because it's not designed for that. Use bcrypt instead, which will also take care of properly salting your password hash ... – derpirscher Commented Mar 31 at 12:48
  • 1 The biggest mistake here is not using a proper password hash function (hmac-sha512 is a fast keyed hash, not a password hash). Then, it seems like you're using fixed-length columns in the DB of the wrong size. Either use variable length data structures or change the fixed length to the correct one. – Alejandro Commented Mar 31 at 12:56
  • @Charlieface So I should also store algorithm in DB? So in future I can also verify passwords hashed by older algorithms? – WowDogeCode Commented Mar 31 at 12:58
  • 1 That would probably be wise. EC alogrithms have shown that hash size is not a determinant of what alogrithm was used, so if you plan on changing algorithms then it makes sense to store it. – Charlieface Commented Mar 31 at 13:00
 |  Show 1 more comment

1 Answer 1

Reset to default 1

Based on SQL binary and varbinary docs:

Fixed-length binary data with a length of n bytes, where n is a value from 1 through 8,000. The storage size is n bytes.

Also based on the docs:

Data type Use when ...
binary the sizes of the column data entries are consistent.
varbinary the sizes of the column data entries vary considerably.
varbinary(max) the column data entries exceed 8,000 bytes.

So, you have to change the column data type to varbinary, to avoid constant allocation and leading zeros for unused bytes.

发布评论

评论列表(0)

  1. 暂无评论