PBKDF2没有返回明文并在C#中散列预期值

时间:2017-08-27 02:13:15

标签: c# pbkdf2

我试图在C#中使用PBKDF2来创建密码,然后我试图检索该密码。

var masterPwd = "masterPassword";
var service = "www.google.com";
byte[] salt = CreateSalt(16);
var encodedPwd = CreateMasterPassword(masterPwd, salt);
var decoded = CreateMasterPassword(encodedPwd, salt);

定义了以下功能:

        public static byte[] CreateSalt(int size)
        {
            var salt = new byte[size];
            using (var random = new RNGCryptoServiceProvider())
            {
                random.GetNonZeroBytes(salt);
            }

            return salt;
        }

        public static string CreateMasterPassword(string password, byte[] salt)
        {

            string PassHash = Convert.ToBase64String(KeyDerivation.Pbkdf2(
            password: password,
            salt: salt,
            prf: KeyDerivationPrf.HMACSHA256,
            iterationCount: 10000,
            numBytesRequested: 256 / 8));
            return PassHash;
        }

在这种情况下,不应该解码与masterPwd相同吗?

1 个答案:

答案 0 :(得分:1)

我认为你对PBKDF2的作用有点误解。它不是一个加密函数,你可以恢复明文数据(让我们把蛮力放在一边,因为它不是'预期用途')。相反,它是一种“缓慢”的散列机制,通常被称为“单向”。

PBKDF2是密钥派生函数,但也用于存储密码。以下是PBKDF2用于密码存储时的典型流程。

  1. 用户使用带密码的网站创建帐户。该站点生成一个随机盐,然后使用salt将PBKD2应用于密码,并存储结果和盐。盐以纯文本形式存储。
  2. 当用户需要再次登录时,该站点会要求输入用户名和密码。它查找该用户的salt,然后将PBKDF2重新应用于用户输入的密码。
  3. 它将存储的哈希值与用户输入的哈希值进行比较。如果哈希值相等,则站点知道他们正确输入了密码。
  4. 此方法意味着网站不会以可能知道的方式存储密码。这允许网站拒绝密码的知识。

    如果这是你想要做的,那就是你应该如何使用它。

    如果确实需要一种“双向”算法,那么这就是从散列到加密。在这个地方将使用对称算法,其中包括密钥和IV管理的所有麻烦问题。你很可能想看一下构建在libsodium等对称密码之上的高抽象。

    libsodium是一个很好的抽象,建立在基元之上,可以猜测如何使用它们。如果提供简单的API,例如“使用此密码加密此内容”并且正确地从密码中获取加密密钥,则对加密执行某种形式的身份验证,并且信息安全专家会很好地认可。