c# - 如果我使用 PBKDF2 或 RFC2898 代码在 C# 中加密或解密数据,是否不需要存储哈希密码
问题描述
最后附上实际引用的代码。 从上面链接中给出的C#中PBKDF2或RFC2898的代码中我可以理解。
我得出以下结论。如果我错了,请纠正我。
- 存储密码
密码1
没有 必要。_
- 盐的储存**
盐1
** 是 必要的。
- 如果密码被哈希形成密钥' k1 ',将' data1 '加密为' edata1 ',甚至存储哈希密码=key
k1
,没 必要。我的想法背后的原因是加密数据'<strong>edata1'只能用密钥'<strong>k1'解密,并且只有用户输入正确的密码'<strong>pwd1'才能生成'<strong>k1' .
结论:不需要存储密码“<strong>pwd1”。不需要存储散列密码,即“<strong>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, 0, 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, 0, 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);
}
}
}
}
解决方案
推荐阅读
- java - 离子构建项目失败:无法确定任务':app:lintVitalRelease'的依赖关系
- python - 遍历索引目录的服务器 URL 并读取文件
- perl - perl cpan 安装与 GIT Perl cpan 安装冲突我该如何纠正?
- dotnetzip - 为什么我的 zip 文件夹没有用密码锁定,但里面的文件被锁定了?
- c# - 将 http 请求添加到 .NET 中的多部分/混合请求
- ios - 从 ViewController 追加流?
- c - 为什么使用 -O(1/2/3) 选项进行优化会干扰 scanf()?
- javascript - 如何在 javascript 中到达嵌套对象内部?
- bash - 在特定符号之间过滤具有匹配 ID 字符串的多 fasta 文件
- algorithm - 确定是否可以将一组节点视为有向无环图的孤立子图