我正在使用c#来实现Rijndael算法来加密/解密文件。以下是我的代码:
private void EncryptFile(string inputFile, string outputFile, string password)
{
try
{
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password.ToString());
string cryptFile = outputFile;
FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);
RijndaelManaged RMCrypto = new RijndaelManaged();
CryptoStream cs = new CryptoStream(fsCrypt,
RMCrypto.CreateEncryptor(key, key),
CryptoStreamMode.Write);
FileStream fsIn = new FileStream(inputFile, FileMode.Open);
int data;
while ((data = fsIn.ReadByte()) != -1)
cs.WriteByte((byte)data);
fsIn.Close();
cs.Close();
fsCrypt.Close();
}
catch
{
}
}
现在,问题是,只有当密码长度为8的倍数时,该功能才有效。即,如果密码长度为8,16,32等,则其他功能不起作用。
答案 0 :(得分:2)
简单地获取密码并以字节为单位获取其Unicode表示形式是非常糟糕的关键。请不要那样做!正确的方法是使用盐渍哈希作为密钥 - 也就是说,取一个盐,一个密码,并将它们与哈希函数混合在一起。
要从可变长度密码派生密钥,请使用PBKDF2。当攻击者快速访问数据时,PBKDF2旨在使暴力破解变慢。
string password = ...;
byte[] salt = ...;
int keyLength = 32;
byte[] key;
using(var pbkdf = new Rfc2898DeriveBytes(password, salt))
{
key = pbkdf.GetBytes(keyLength);
}
如果您需要使用较少CPU的东西,HMAC可以工作,但也可以更快地使用强力:
using(var hmac = new HMACSHA256())
{
hmac.Key = salt;
key = hmac.ComputeHash(Encoding.UTF8.GetBytes(password));
}
请注意,现在存在可以非常有效地攻击PBKDF2的硬件,因此这对于确定具有资源的确定攻击者来说无济于事。如果这对您很重要,那么从.NET基类开始分支并使用更现代的算法(如scrypt)可能更受欢迎。
答案 1 :(得分:0)
伪代码=>
string passwordFlagLength(string password)
{
int count = 1
for (int i = 0 to 31)
{
if (password.length == count) return password;
if (password.length < count) return password + new string("x", count - password.length);
count = count * 2
}
}
这需要一个密码并使其长度为1,2,4,8等......最多为31位值。(int w / out negative)
如果该值已经是正确的标志大小编号,则使用它,否则用“x”填充其余部分
- &GT;注意:我同意所有人的观点,关于更好的是做安全性/问题,我刚刚发布了这个,因为发布的直接问题是由于字符串大小不是基本的2位值。我还在原始代码中应用了我忘记的计数