C# Rijndael加密函数-密钥/IV/Salt设置
我正在开发一个简单的实用程序来加密文件,作为一种学习体验。 一切似乎都很正常,但我想知道我是否已经安全地设置了密钥/IV/Salt数据 我注意到,当涉及到密码学时,大多数人似乎设想一个工作环境,该环境中装载有恶意软件,由一个向导远程操控,随时准备通过运行中的应用程序/页面文件的内存来获取这些安全文件 让我们假设你在一台干净的机器上,加密一些文件并关闭计算机。 我想知道的是,是否有人可以使用我提出的代码获取您的硬盘并检索文件的内容 <> P>攻击向量是我最关心的,就是确保页面文件/文件缓存是不可访问的。 我还想确保使用的Key/IV系统不会使基于彩虹表/散列的攻击变得可行 输入密码: 使用passwordchar值设置为true的文本框输入密码 我并不真正关心字符串是否在内存中,只要它在加密后被正确删除。我读到使用SecureString在这一点上是没有意义的,因为如果你的计算机上已经有恶意软件,你可以很容易地在那里有一个键盘记录器,这使得其他一切都变得无用C# Rijndael加密函数-密钥/IV/Salt设置,c#,security,encryption,C#,Security,Encryption,我正在开发一个简单的实用程序来加密文件,作为一种学习体验。 一切似乎都很正常,但我想知道我是否已经安全地设置了密钥/IV/Salt数据 我注意到,当涉及到密码学时,大多数人似乎设想一个工作环境,该环境中装载有恶意软件,由一个向导远程操控,随时准备通过运行中的应用程序/页面文件的内存来获取这些安全文件 让我们假设你在一台干净的机器上,加密一些文件并关闭计算机。 我想知道的是,是否有人可以使用我提出的代码获取您的硬盘并检索文件的内容 P>攻击向量是我最关心的,就是确保页面文件/文件缓存是不可访问的
private static string salt = "02341235XadfaDADFexA8932F7Dz3J3X";
我使用一个硬编码的32字符字符串来设置密码。
(上面的字符串只是一个示例。)
要做到这一点,需要有人用十六进制编辑器反编译/查看.exe文件本身(我知道这很容易做到,但还是需要额外的一步)
我已经考虑过让这个盐可以编辑,但我不确定如何安全地保存它。我认为加密你的salt有点可笑,因为那样你就会有同样的问题等等,所以把它作为一个硬编码字符串放在exe里面对我来说是最有意义的
其工作方式是,如果您决定将密码设置为“密码”,它实际上会保存为“密码FADADFEXA8932F7DZ3J3X”
这里的主键是,无论输入什么,您始终拥有32个字符的密码
钥匙和IV:
钥匙和IV也被腌制如下。
这就是我想要得到一些信息的原因,因为老实说,我不完全确定它在做什么:
UnicodeEncoding UE = new UnicodeEncoding();
byte[] keysalt = UE.GetBytes("Xjafe231x42X423XadXCadfkhjeAdS"); //Another string of random characters hard coded in the exe
byte[] IVSodium = UE.GetBytes("83Xkda7l78Dkx85KdJazppoqq6SaxDs"); //Another string of random characters hard coded in the exe
byte[] key = new Rfc2898DeriveBytes(password, keysalt).GetBytes(32); //Derive the key using the password and salt
byte[] IV = new Rfc2898DeriveBytes(password, IVSodium).GetBytes(16); //Derive the IV using the password and salt
我主要关心的是IV是基于密钥的。同样,我不确定这是否会导致任何问题,我希望你们能让我知道,如果有问题,他们是什么
另外,这是另一个硬编码salt的场景吗?是否应该将其存储在加密文件中,如果是,是否真的使其更安全?我是否也应该将此设置为可编辑
加密流是使用using关键字设置的:
using (FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create))
{
using (RijndaelManaged RMCrypto = new RijndaelManaged())
{
using (CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, IV), CryptoStreamMode.Write))
{
using (FileStream fsIn = new FileStream(inputFile, FileMode.Open))
{
byte[] buffer = new byte[4096]; //4096 is kind of arbitrary - better idea?
int data;
long bytesRead = 0;
while((data = fsIn.Read(buffer, 0, buffer.Length)) > 0)
{
bytesRead += data;
/////////////////////////////////////////
// Handle Aborts and Update Progress Bar
/////////////////////////////////////////
if (!caller.isClosing)
caller.Invoke((MethodInvoker)delegate {
caller.fileProgressBar.Value = ((int)(((double)bytesRead / totalBytes) * 100));
});
else
return false; //Encryption Aborted
/////////////////////////////////////////
cs.Write(buffer, 0, data);
fsIn.Close();
cs.Close();
fsCrypt.Close();
return true;
}
}
}
}
}
感谢您的时间,请告诉我是否有更好的方法来设置密钥/IV/Salt。
我认为,只要IV和密钥包含相似字符时不存在数学问题,它就很可能足够安全。如果是这样,我是否也应该使用硬编码IV?这似乎很奇怪
请注意,我没有保存密码散列或类似的内容。密码不会保存在任何位置。它只是用来生成密钥和IV
谢谢你抽出时间
编辑:以下是推荐给未来用户的更改。
请注意,这不是使用胡椒粉,而是随机添加的盐,尽管添加胡椒粉很容易
byte[] salt = new byte[32]; //Create a 32 byte salt
rand.NextBytes(salt); //Fill it with random values (use RandomNumberGenerator rand = new RNGCryptoServiceProvider(); to be safe
byte[] IV = new byte[16]; //Create a 16 byte IV
rand.NextBytes(IV); //Fill it with random numbers
byte[] key = new Rfc2898DeriveBytes(password, salt).GetBytes(32); //Derive our Key by mixing our password with the salt
using (FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create))
{
using (RijndaelManaged RMCrypto = new RijndaelManaged())
{
using (CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, IV), CryptoStreamMode.Write))
{
using (FileStream fsIn = new FileStream(inputFile, FileMode.Open))
{
fsCrypt.Write(salt, 0, salt.Length); //Write our salt to the file
fsCrypt.Write(IV, 0, IV.Length); //Write our IV to the file
fsIn.CopyTo(cs); //Encrypt and Write
}
}
}
}
据我所知,
盐有两个用途:
GetBytes
)。但是有一个问题,这可能会使PBKDF2函数的初始迭代次数增加一倍,这会消耗CPU时间,并降低与攻击者相比的优势。最好只生成一个随机IV,并将其作为密文的前缀
因此,最后你应该存储
salt | IV |密文
,然后使用salt | pepper
作为salt并计算你的密钥,然后使用计算出的密钥和IV进行加密/解密。不要使用固定的salt,salt的意义在于,如果密码被重用,你无法判断它是否被重用。salt不需要保密,只需将其附加到正在加密的文件的前面即可