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
 
 
 
 
 
 

 

 

 

 

作者:Chuck Lu    GitHub    
posted @   ChuckLu  阅读(700)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
历史上的今天:
2016-01-08 Types of Entity in Entity Framework:
2016-01-08 DBContext
2016-01-08 Model Browser
2015-01-08 只运行一个应用程序的错误代码的分析
2015-01-08 如何确保C#的应用程序只被打开一次
点击右上角即可分享
微信分享提示