Проблемы с расшифровкой

491
14 мая 2017, 21:39

Использую шифрование 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); //// Ошибка!!!

Подскажите, пожалуйста, в чем проблема...

Answer 1

У меня все работает. Данная ошибка возникает если секретный ключ задан неверно. Обратите внимание на параметр login.keyFileName при записи, при чтении уже keyFileName, возможно, ошибка именно здесь.

READ ALSO
Клиент читает из потока нули

Клиент читает из потока нули

Если сообщение больше размера буфера, то на клиент часть данных приходит как нули

357
Файловый менеджер C# Ошибка Перемещение файла

Файловый менеджер C# Ошибка Перемещение файла

Столкнулся с такой проблемой, что не могу переместить файлы с дисков С и D, которые уже были созданы на нем, как я понимаю дело все в правах...

353
Файловые ассоциации в Xamarin Android

Файловые ассоциации в Xamarin Android

Пытаюсь разобраться с подключением открытия для своего расширения файлаКак это заставить работать правильно: MainActivity

344
SignalR асинхронное подключение + Unity3D

SignalR асинхронное подключение + Unity3D

Пытаюсь разобраться с тем, как выполнить асинхронное подключение к хабу в SignalRИзначально использовал такой код:

387