合并两个数组时,第一个数组变短 1
When merging two arrays, the first array gets shorter by 1
我有一个用 SHA256 散列的密码。然后我有一个看起来像这样的盐:
AAAAAAAAAAAAAAAAAAAAAAAAAA==
在这个过程的最后,它们都是字节数组,然后我将它们合并成一个新的字节数组。
我的问题是在将密码与盐合并时,我的散列密码在末尾缩短了一个字符。
预期输出:
uIxnpgdBQpSPJrqwYucIOeyOyqyCv7HbBfd74ovoxjI=AAAAAAAAAAAAAAAAAAAAAAAAAA==
输出:
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;
}
如何防止我的密码被缩短?
你做错了。您不得将盐添加到散列密码中。您必须将盐添加到纯密码中,然后进行哈希处理。重点是使当前密码或短密码的哈希无法识别。
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;
}
为每个密码创建随机盐字节,并将盐作为单独的信息与散列密码一起存储。像这样,每个密码都有不同的盐。这使得 Pre-computed dictionary attack/Rainbow table attack 不可行。盐不需要加密。您可能还想将其存储为 base 64 字符串。要再次获取盐字节,您将需要 Convert.FromBase64String()
.
我有一个用 SHA256 散列的密码。然后我有一个看起来像这样的盐:
AAAAAAAAAAAAAAAAAAAAAAAAAA==
在这个过程的最后,它们都是字节数组,然后我将它们合并成一个新的字节数组。
我的问题是在将密码与盐合并时,我的散列密码在末尾缩短了一个字符。
预期输出:
uIxnpgdBQpSPJrqwYucIOeyOyqyCv7HbBfd74ovoxjI=AAAAAAAAAAAAAAAAAAAAAAAAAA==
输出:
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;
}
如何防止我的密码被缩短?
你做错了。您不得将盐添加到散列密码中。您必须将盐添加到纯密码中,然后进行哈希处理。重点是使当前密码或短密码的哈希无法识别。
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;
}
为每个密码创建随机盐字节,并将盐作为单独的信息与散列密码一起存储。像这样,每个密码都有不同的盐。这使得 Pre-computed dictionary attack/Rainbow table attack 不可行。盐不需要加密。您可能还想将其存储为 base 64 字符串。要再次获取盐字节,您将需要 Convert.FromBase64String()
.