如果我使用PBKDF2或RFC2898代码加密或解密C#中的数据,则无需存储哈希密码

问题描述

实际引用的代码附加在最后。 从上面链接中的code for PBKDF2 or RFC2898 in C#可以理解。

我得出以下结论。如果我错了,请纠正我。

  1. 密码存储

pwd1

不是不是 必要

  1. 储存盐**

盐1

**是必需的

  1. 如果密码被散列以形成密钥“ k1 ”,则将“ data1 ”加密为“ edata1 ”,甚至存储散列密码=键

k1

不是 必要 。我思考的原因是加密数据“ edata1 ”只能用密钥“ k1 ”解密,而“ k1 ”只能在以下情况下生成用户输入正确的密码 pwd1 ”。

结论:无需存储密码 pwd1 ”。 无需存储任何哈希密码,即“ k1 ”。 如果我错了,请纠正我。谢谢。

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;

public class rfc2898test
{
    // Generate a key k1 with password pwd1 and salt salt1.
    // Generate a key k2 with password pwd1 and salt salt1.
    // Encrypt data1 with key k1 using symmetric encryption,creating edata1.
    // Decrypt edata1 with key k2 using symmetric decryption,creating data2.
    // data2 should equal data1.

    private const string usageText = "Usage: RFC2898 <password>\nYou must specify the password for encryption.\n";
    public static void Main(string[] passwordargs)
    {
        //If no file name is specified,write usage text.
        if (passwordargs.Length == 0)
        {
            Console.WriteLine(usageText);
        }
        else
        {
            string pwd1 = passwordargs[0];
            // Create a byte array to hold the random value.
            byte[] salt1 = new byte[8];
            using (RNGCryptoServiceProvider rngCsp = new
RNGCryptoServiceProvider())
            {
                // Fill the array with a random value.
                rngCsp.GetBytes(salt1);
            }

            //data1 can be a string or contents of a file.
            string data1 = "Some test data";
            //The default iteration count is 1000 so the two methods use the same iteration count.
            int myIterations = 1000;
            try
            {
                Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(pwd1,salt1,myIterations);
                Rfc2898DeriveBytes k2 = new Rfc2898DeriveBytes(pwd1,salt1);
                // Encrypt the data.
                Aes encAlg = Aes.Create();
                encAlg.Key = k1.GetBytes(16);
                MemoryStream encryptionStream = new MemoryStream();
                CryptoStream encrypt = new CryptoStream(encryptionStream,encAlg.CreateEncryptor(),CryptoStreamMode.Write);
                byte[] utfD1 = new System.Text.UTF8Encoding(false).GetBytes(
data1);

                encrypt.Write(utfD1,utfD1.Length);
                encrypt.FlushFinalBlock();
                encrypt.Close();
                byte[] edata1 = encryptionStream.ToArray();
                k1.Reset();

                // Try to decrypt,thus showing it can be round-tripped.
                Aes decAlg = Aes.Create();
                decAlg.Key = k2.GetBytes(16);
                decAlg.IV = encAlg.IV;
                MemoryStream decryptionStreambacking = new MemoryStream();
                CryptoStream decrypt = new CryptoStream(
decryptionStreambacking,decAlg.CreateDecryptor(),CryptoStreamMode.Write);
                decrypt.Write(edata1,edata1.Length);
                decrypt.Flush();
                decrypt.Close();
                k2.Reset();
                string data2 = new UTF8Encoding(false).GetString(
decryptionStreambacking.ToArray());

                if (!data1.Equals(data2))
                {
                    Console.WriteLine("Error: The two values are not equal.");
                }
                else
                {
                    Console.WriteLine("The two values are equal.");
                    Console.WriteLine("k1 iterations: {0}",k1.IterationCount);
                    Console.WriteLine("k2 iterations: {0}",k2.IterationCount);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0}",e);
            }
        }
    }
}

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)