Использую шифрование Rijndael. Проблема следующая: если зашифровать строку и тут же расшифровать, то все работает отлично, а если зашифровать строку и записать в файл, а потом считать его и расшифровать то выдает ошибку "System.Security.Cryptography.CryptographicException' occurred in mscorlib.dll Additional information: Заполнение неверно и не может быть удалено." Сам класс шифровки:
public static class SymmetricEncryptionUtility
{
private static bool _ProtectKey;
private static string _AlgorithmName;
public static string AlgorithmName
{
get { return _AlgorithmName; }
set { _AlgorithmName = value; }
}
public static bool ProtectKey
{
get { return _ProtectKey; }
set { _ProtectKey = value; }
}
public static void GenerateKey(string targetFile)
{
// Создать алгоритм
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
Algorithm.GenerateKey();
// Получить ключ
byte[] Key = Algorithm.Key;
if (ProtectKey)
{
// Использовать DPAPI для шифрования ключа
Key = ProtectedData.Protect(
Key, null, DataProtectionScope.LocalMachine);
}
// Сохранить ключ в файле
using (FileStream fs = new FileStream(targetFile, FileMode.OpenOrCreate))
{
fs.Write(Key, 0, Key.Length);
}
}
public static void ReadKey(SymmetricAlgorithm algorithm, string keyFile)
{
byte[] Key;
using (FileStream fs = new FileStream(keyFile, FileMode.Open))
{
Key = new byte[fs.Length];
fs.Read(Key, 0, (int)fs.Length);
}
if (ProtectKey)
algorithm.Key = ProtectedData.Unprotect(Key, null, DataProtectionScope.LocalMachine);
else
algorithm.Key = Key;
}
public static byte[] EncryptData(string data, string keyFile)
{
// Преобразовать строку data в байтовый массив
byte[] ClearData = Encoding.UTF8.GetBytes(data);
// Создать алгоритм шифрования
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
ReadKey(Algorithm, keyFile);
// Зашифровать информацию
MemoryStream Target = new MemoryStream();
// Сгенерировать случайный вектор инициализации (IV)
// для использования с алгоритмом
Algorithm.GenerateIV();
Target.Write(Algorithm.IV, 0, Algorithm.IV.Length);
// Зашифровать реальные данные
CryptoStream cs = new CryptoStream(Target, Algorithm.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(ClearData, 0, ClearData.Length);
cs.FlushFinalBlock();
// Вернуть зашифрованный поток данных в виде байтового массива
return Target.ToArray();
}
public static string DecryptData(byte[] data, string keyFile)
{
// Создать алгоритм
SymmetricAlgorithm Algorithm = SymmetricAlgorithm.Create(AlgorithmName);
ReadKey(Algorithm, keyFile);
// Расшифровать информацию
MemoryStream Target = new MemoryStream();
// Прочитать вектор инициализации (IV)
// и инициализировать им алгоритм
int ReadPos = 0;
byte[] IV = new byte[Algorithm.IV.Length];
Array.Copy(data, IV, IV.Length);
Algorithm.IV = IV;
ReadPos += Algorithm.IV.Length;
CryptoStream cs = new CryptoStream(Target, Algorithm.CreateDecryptor(),
CryptoStreamMode.Write);
cs.Write(data, ReadPos, data.Length - ReadPos);
cs.FlushFinalBlock(); /////////////// ОШИБКА ////////////////////
// Получить байты из потока в памяти и преобразовать их в текст
return Encoding.UTF8.GetString(Target.ToArray());
}
}
Вот так записываю в файл
StringBuilder sb = new StringBuilder();
foreach(Account ac in login.allAccounts)
{
sb.AppendLine(String.Format("{0} {1} {2}", ac.Name, ac.Password, ac.Folder));
}
byte[] data = SymmetricEncryptionUtility.EncryptData(sb.ToString(), login.keyFileName);
File.WriteAllBytes("./users/users.dat", data);
Потом читаю с файла
byte []data = File.ReadAllBytes("./users/users.dat");
string decr = SymmetricEncryptionUtility.DecryptData(data, keyFileName); //// Ошибка!!!
Подскажите, пожалуйста, в чем проблема...
У меня все работает. Данная ошибка возникает если секретный ключ задан неверно. Обратите внимание на параметр login.keyFileName при записи, при чтении уже keyFileName, возможно, ошибка именно здесь.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей