我工作的一个简单的工具,以文件作为一个学习的经验进行加密。 似乎一切都工作正常,但我想知道如果我有安装密钥/ IV /盐的数据安全。
我注意到,当涉及到密码学大多数人似乎设想,加载恶意软件通过远程准备通过正在运行的应用/页面文件的内存潜水让这些安全文件向导载人的工作环境。
让我们假设你是一个干净的机器上,你加密了一些文件,并关闭计算机。 我想知道的是,是否有人可以把你的硬盘驱动器,并使用我提出的代码检索文件的内容。
攻击向量我最关心的是确保页面文件/文件缓存是无法访问。 我也想,以确保使用的密钥/ IV系统不会让一个彩虹表/基于哈希的攻击是可行的。
输入密码:
使用设置为true的passwordchar值的文本框中输入的密码。
我真的不关心串在内存中,只要它是加密后正常删除之中。 我读了使用SecureString的是一种毫无意义的在这一点上,因为如果您的计算机上有恶意软件已经,你可以很容易地对其中有一个键盘记录使一切无用的。
private static string salt = "02341235XadfaDADFexA8932F7Dz3J3X";
I盐使用硬编码的32字符串的密码。 (以上字符串是只是一个例子。)
为了得到它,它需要有人反编译/浏览.exe文件本身有一个十六进制编辑器(的东西,我知道,如果很容易做到,但仍然一个额外的步骤)。
我曾考虑让这种盐可编辑的,但我不知道我怎么能安全地保存它。 我认为这是一个有点可笑加密您的盐,因为那么你将有同样的问题等,所以只是把它当作自己似乎最有意义给我的exe文件内的硬编码字符串。
其工作原理是,如果你决定把你的密码“thepassword”,它实际上是保存为“thepasswordfaDADFexA8932F7Dz3J3X”。
这里主要的关键是,你总是有一个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
我这里主要关注的是,四是基于关键。 同样,我不知道这是否会造成任何问题,我希望你们可以让我知道,如果有问题,它们是什么。
此外,这是另一种情形,其中硬编码的盐是一种不好的做法? 如果这被保存在加密文件,如果是的话,它真的使之更加安全? 我应该让这个编辑呢?
该加密流是使用使用关键字的设置:
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 /盐更好的办法。 我认为它是最有可能的足够安全,只要没有与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
}
}
}
}