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#

@DouglasHeld Ridiculous! Rfc2898 or PBKDF2 using SHA1 is not broken, there is no collision vulnerability. SHA1 is broken for signing. See Is PBKDF2-HMAC-SHA1 really broken? and Is PBKDF2 (RFC 2898) broken because SHA1 is broken?.
– zaph
Nov 15 '17 at 13:06
 
 
回答1

For those who need it, .NET Framework 4.7.2 includes an overload of Rfc2898DeriveBytes that allows the hashing algorithm to be specified:

byte[] bytes;
using (var deriveBytes = new Rfc2898DeriveBytes(password, salt, iterations, HashAlgorithmName.SHA256))
{
    bytes = deriveBytes.GetBytes(PBKDF2SubkeyLength);
}

The HashAlgorithmName options at the moment are:

  • MD5
  • SHA1
  • SHA256
  • SHA384
  • SHA512
 
 
 
 
 
 

 

 

 

 

posted @ 2019-01-08 17:56  ChuckLu  阅读(694)  评论(0编辑  收藏  举报