PBKDF2加密
5.2 PBKDF2
PBKDF2 applies a pseudorandom function (see Appendix B.1 for an
example) to derive keys. The length of the derived key is essentially
unbounded. (However, the maximum effective search space for the
derived key may be limited by the structure of the underlying
pseudorandom function. See Appendix B.1 for further discussion.)
PBKDF2 is recommended for new applications.
PBKDF2 (P, S, c, dkLen)
Options: PRF underlying pseudorandom function (hLen
denotes the length in octets of the
pseudorandom function output)
Input: P password, an octet string
S salt, an octet string
c iteration count, a positive integer
dkLen intended length in octets of the derived
key, a positive integer, at most
(2^32 - 1) * hLen
Output: DK derived key, a dkLen-octet string
Rfc2898DeriveBytes Class
password - the password that needs to be hashed. This should be converted
into a char array before passing.
salt- salt value that should append to the password.
iterations- no. of iterations to be done. This value can be used to adjust the speed of the algorithm.
keyLength- This is the required output length of the hashed function.
This function returns a byte array that needs to be converted into a string using a suitable hex encoder.
需要注意的是,加密的结果是字节数组。在存储到数据库的时候,可以转换为十六进制的字符串或者Base64字符串
[Test]
public void Pbkdf2Test()
{
string saltString = "8291f825-5772-4b3b-a28c-18887099f6d4";
var array = Encoding.UTF8.GetBytes(saltString);
GetHexString(array, 16);
GetHexString(array, 128);
GetHexString(array,256);
GetHexString(array,512);
var rfc2898DeriveBytes = new Rfc2898DeriveBytes("123", array, 4000);
var result2 = rfc2898DeriveBytes.GetBytes(40);
Console.WriteLine($"加密结果数组长度{result2.Length}");
var string2 = Convert.ToBase64String(result2);
Console.WriteLine(string2);
Console.WriteLine(string2.Length);
}
public void GetHexString(byte[] array, int keyLength)
{
var rfc2898DeriveBytes = new Rfc2898DeriveBytes("123", array, 4000);
var result = rfc2898DeriveBytes.GetBytes(keyLength);
Console.WriteLine($"加密结果数组长度{result.Length}");
var hexString = ByteArrayToString(result);
Console.WriteLine(hexString);
Console.WriteLine("========Split========");
}
public static string ByteArrayToString(byte[] ba)
{
var hex = new StringBuilder(ba.Length * 2);
foreach (var b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString();
}
用SHA256作为Hash
Hash underlying hash function
https://neurotechnics.com/tools/pbkdf2-test 可以用来验证
//https://neurotechnics.com/tools/pbkdf2-test
var password = "123";
var saltString = "qwer1234";
var salt = Encoding.UTF8.GetBytes(saltString);
var iteration = 4000;
var bitLength = 512;
var rdcRfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, iteration, HashAlgorithmName.SHA256);
var hash = rdcRfc2898DeriveBytes.GetBytes(bitLength/8);
Console.WriteLine(ByteArrayToString(hash));
返回结果的十六进制是6ac407934d532312db27a828063c37f529d20925f0dc37363882ca127266d5fd67a78fc6bbee273fb184bc9962d2595a9938a6fa7387d52219f849d3028c05eb【512bits是64个bytes】
Rfc2898 / PBKDF2 with SHA256 as digest in c#
For those who need it, .NET Framework 4.7.2 includes an overload of Rfc2898DeriveBytes that allows the hashing algorithm to be specified:
The HashAlgorithmName options at the moment are: