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

StackOverflow https://stackoverflow.com/questions/1199058

Вопрос

Я новичок в шифровании.Мне нужно реализовать алгоритм асимметричного шифрования, который, я думаю, использует закрытый/открытый ключ.Я начал использовать образец 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?

Это было полезно?

Решение

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

Один из вариантов, который я реализовал при необходимости передачи больших объемов зашифрованных данных между двумя системами, — это иметь пару ключей 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 до 16 384 с размером пропуска 8.

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

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

у нас есть:

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

ИЛИ

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top