При объединении двух массивов первый массив уменьшается на 1 - PullRequest
0 голосов
/ 09 марта 2019

У меня есть пароль, который я хэширую с SHA256. Тогда у меня есть соль, которая выглядит так:

AAAAAAAAAAAAAAAAAAAAAA ==

В конце процесса оба они являются байтовыми массивами, которые я затем объединяю в новый байтовый массив.

Моя ПРОБЛЕМА заключается в том, что при объединении пароля с солью мой хешированный пароль в конце сокращается на один символ.

Ожидаемый результат:

uIxnpgdBQpSPJrqwYucIOeyOyqyCv7HbBfd74ovoxjI = AAAAAAAAAAAAAAAAAAAAAAAAA ==

Выход:

uIxnpgdBQpSPJrqwYucIOeyOyqyCv7HbBfd74ovoxjIAAAAAAAAAAAAAAAAAAAAAAAAA ==

Как видите, после l .

отсутствует = .

Мой метод:

public static byte[] HashPassword(byte[] passwordToHash)
{
    byte[] hInput;
    byte[] hSalt = GetSalt();
    using(SHA256 sh = SHA256.Create())
    {
        hInput = sh.ComputeHash(passwordToHash);
    }
    byte[] SaltedPw = new byte[(hInput.Length+ 1 ) + (hSalt.Length + 3)];
    Array.Copy(hInput,0, SaltedPw, 0,hInput.Length);
    Array.Copy(hSalt, 0, SaltedPw, hInput.Length, hSalt.Length);
    return SaltedPw;
}

public static byte[] GetSalt()
{
    byte[] salt = new byte[16];
    return salt;
}

Как я могу предотвратить сокращение моего пароля?

1 Ответ

4 голосов
/ 09 марта 2019

Вы делаете это неправильно. Вы не должны добавлять соль в хешированный пароль. Вы должны добавить соль в простой пароль, а затем хэш. Смысл в том, чтобы сделать хэш текущего или короткого пароля неузнаваемым.

Кодировка base 64 применяется только к конечному результату, чтобы разрешить сохранение хэша пароля в виде строки. Следовательно, вам никогда не придется объединять строки base 64. Строки Base 64 дополняются = в конце, чтобы получить длину, кратную 4. Поэтому вы никогда не увидите = в середине.

public static string GetHashedPassword(string plainPassword, byte[] salt)
{
    byte[] passwordBytes = GetBytes(plainPassword);

    // Merge the password bytes and the salt bytes
    var mergedBytes = new byte[passwordBytes.Length + salt.Length];
    Array.Copy(passwordBytes, mergedBytes, passwordBytes.Length);
    Array.Copy(salt, 0, mergedBytes, passwordBytes.Length, salt.Length);

    // Now hash password + salt
    byte[] hash;
    using (var sha = SHA256.Create()) {
        hash = sha.ComputeHash(mergedBytes);
    }
    return Base64Encode(hash);
}

Вам также понадобится это:

public static string Base64Encode(byte[] bytes)
{
    return System.Convert.ToBase64String(bytes);
}

static byte[] GetBytes(string str)
{
    byte[] bytes = new byte[str.Length * sizeof(char)];
    System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
    return bytes;
}

Создайте случайные байты соли для каждого пароля и сохраните соль как отдельный фрагмент информации вместе с хешированным паролем. Таким образом, каждый пароль получает различную соль. Это делает Предсчитанную атаку по словарю / Атаку Радужной таблицы неосуществимой. Соль не нуждается в шифровании. Вы, вероятно, захотите сохранить его как строку base 64. Чтобы снова получить соленые байты, вам понадобится Convert.FromBase64String().

...