как использовать RSA для шифрования файлов (огромные данные) в C#

Я новичок в шифровании. Мне нужно реализовать асимметричный алгоритм шифрования, который, я думаю, использует закрытый/открытый ключ. Я начал использовать образец RSACryptoServiceProvider. это было нормально с небольшими данными для шифрования. Но при использовании его на относительно больших данных "2 строки", я получаю исключение CryptographicException"плохая длина"!

//Create a new instance of RSACryptoServiceProvider.
using (RSACryptoServiceProvider RSA = new RSACryptoServiceProvider())
{

    //Import the RSA Key information. This only needs
    //toinclude the public key information.
    //RSA.ImportParameters(RSAKeyInfo);
    byte[] keyValue = Convert.FromBase64String(publicKey);
    RSA.ImportCspBlob(keyValue);

    //Encrypt the passed byte array and specify OAEP padding.  
    //OAEP padding is only available on Microsoft Windows XP or
    //later.  
    encryptedData = RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
}

затем я нашел несколько примеров шифрования больших данных (или файлов) с помощью CryptoStream и использую только симметричные алгоритмы, такие как DES или 3DES, которые имеют функцию CreateEncryptor для возврата ICryptoTransform в качестве одного из входных данных конструктору CryptoStream!!!

CryptoStream cStream = new CryptoStream(fStream,
                new TripleDESCryptoServiceProvider().CreateEncryptor(Key, IV),
                CryptoStreamMode.Write);

как шифровать файлы с помощью RSA?

6 ответов


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

один из вариантов, который я реализовал при необходимости передачи больших объемов зашифрованных данных между двумя системами, должен иметь пару ключей RSA, открытый ключ которой известен как отправителю, так и получателю, тогда, когда данные должны быть отправлены, получатель генерирует новую пару ключей RSA, шифрует открытый ключ этой пары ключей общим открытым ключом и отправляет зашифрованный открытый ключ отправителя. Отправитель расшифровывает открытый ключ получателя, используя его закрытый ключ (который получателю не нужно знать, так же как отправителю не нужно знать закрытый ключ получателя), генерирует симметричный ключ шифрования, шифрует данные симметричным ключом, а затем шифрует симметричный ключ, используя открытый ключ, полученный от получателя. Затем зашифрованный симметричный ключ и зашифрованные данные отправляются получателю, который использует его генерируется закрытый ключ для расшифровки симметричного ключа, а затем расшифровывает данные.

можно использовать RSACryptoServiceProvider.ToXMLString() и RSACryptoServiceProvider.FromXMLString() методы для хранения общего открытого ключа в качестве строкового литерала XML в приложении-получателе.

Не забывайте, когда вы генерируете симметричный ключ шифрования для использования RNGCryptoServiceProvider() для генерации ключа, поскольку это гораздо более безопасный метод генерации (псевдо) случайных чисел.

кроме того, я настоятельно рекомендую не использовать 3DES в качестве симметричного алгоритм шифрования, он стар и начинает показывать свой возраст. Используйте симметричное шифрование AES с помощью AesCryptoServiceProvicer или RijndaelManaged классы.


RSA может шифровать только блоки данных, которые короче длины ключа, поэтому обычно вы делаете

  1. создайте случайный ключ правильной длины, необходимый для AES (или аналогичный).
  2. зашифруйте свои данные с помощью AES или аналогичного с помощью этого ключа
  3. зашифровать случайный ключ с помощью ключа RSA

затем вы публикуете оба выхода из 2 и 3

для расшифровки

  1. расшифровать ключ AES с помощью RSA ключ.
  2. расшифровать данные, используя этот ключ AES

обычно RSA используется только для передачи симметричного ключа (например, в начале потока), а затем массовые данные шифруются этим ключом.

асимметричное шифрование недостаточно эффективно для передачи большого количества данных.


для будущих поисков относительно исключений плохой длины RSA...

вы можете рассчитать максимальное количество байт, которые могут быть зашифрованы с использованием ключа размером со следующим:

((KeySize - 384) / 8) + 37

однако, если параметр оптимального асимметричного шифрования (OAEP) имеет значение true, то для вычисления максимального числа байтов можно использовать следующее:

((KeySize - 384) / 8) + 7

законные ключевые размеры 384 через 16384 с a размер пропуск 8.


реализации .NET RSA (и все алгоритмы открытого/закрытого ключа) не поддерживают большие блоки данных - потому что это не цель открытого/закрытого ключа.

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


у нас есть:

MaxBlockSize=((KeySize - 384) / 8) + 37

или

MaxBlockSize=((KeySize - 384) / 8) + 7

Итак, мы можем разделить данные на несколько блоков, а затем зашифровать каждый из них, а затем объединить их