Мне было интересно, как мне зашифровать много данных, используя ChaCha20Poly1305 или AesGcm. В моем проекте работает .NET 7.
Мне нужно зашифровать данные размером от 100 МБ до 1 ГБ с помощью одного из этих алгоритмов (для меня лучше подойдет ChaCha20Poly1305). Я не хочу загружать все данные в память.
Я спрашиваю, потому что не вижу перегрузки метода для ChaCha20Poly1305.Encrypt и Decrypt, который будет брать данные из потока и записывать зашифрованные данные в поток.
Я знаю, что могу использовать библиотеки, такие как NaCl, Libsodium или BouncyCastle, но я спрашиваю, потому что хотел бы сделать это без использования каких-либо внешних библиотек. Не предлагайте мне использовать такие классы, как Aes, я хочу использовать один из вышеперечисленных.
Функция, которую я ожидал быть доступной, оказалась недоступной.
// Other code like key generation ^
byte[] nonce = new byte[12];
byte[] tag = new byte[16];
var cipher = new ChaCha20Poly1305(key);
using FileStream inputFile = File.OpenRead("plainTextFile.dat");
using FileStream outputFile = File.OpenWrite("encrypted.bin");
// Error CS1503: Cannot convert System.IO.FileStream to byte[]
cipher.Encrypt(nonce, inputFile, outputFile, tag);
Спасибо за любую помощь. Я пробовал
Это намеренно так. Большинство этих аутентифицированных API-интерфейсов шифрования не будут возвращать шифр/открытый текст до тех пор, пока тег аутентификации не будет рассчитан/проверен. Это особенно верно для дешифрования больше, чем для шифрования. Шифрование аутентификации предназначено для данных, которые могут полностью храниться в памяти. Тот факт, что это аутентифицированное шифрование, подтверждается этикетками GCM и Poly1305.
@PresidentJamesK.Polk, значит, это означает, что я должен использовать ChaCha20Poly1305 только для небольших сообщений и данных? Итак, для текущего случая, когда есть большие файлы, я должен использовать алгоритм шифрования, такой как AesCbc.





Я никогда не видел класс шифра, но, похоже, он ожидает массив байтов, а не файл, поэтому просто прочитайте файл в массив и передайте его в функцию, теперь напишите новый файл с зашифрованным массивом:
using System.IO;
byte[] fileAsBytes = File.ReadAllBytes("plainTextFile.dat");
byte[] fileAsBytesButEncypted;
cipher.Encrypt(nonce, fileAsBytes, fileAsBytesButEncypted, tag);
File.WriteAllBytes("encrypted.bin", fileAsBytesButEncypted);
Вот в чем проблема - я не могу загрузить весь файл в память, так как файл слишком большой. Может быть, шифрование по частям, но тогда я не знаю, будет ли тег работать правильно при шифровании по частям. Класс «шифр» - это не класс, а экземпляр класса, если я понял ваш ответ.
Эти алгоритмы имеют стиль, называемый AEAD, что означает аутентифицированное шифрование со связанными данными. У них есть хорошее свойство безопасности, которое обеспечивает как конфиденциальность, так и целостность, но небезопасно выпускать какой-либо открытый текст до тех пор, пока тег (который находится в конце) не будет проверен.
Таким образом, вам нужно зашифровать данные фрагментами, каждый из которых имеет отдельный одноразовый номер. Проще всего это сделать с помощью фрагмента фиксированного размера, например 64 КиБ (65536 байт), хотя последний фрагмент может быть меньше. Каждый фрагмент получает 64-битный индекс, начиная с нуля. Вы выполняете XOR индекса фрагмента с исходным одноразовым номером и используете это значение в качестве одноразового номера для шифрования вашего фрагмента. Когда вы шифруете эти данные, вы передаете этот индекс плюс один байт (1, если это последний фрагмент, 0, если нет) в качестве дополнительных данных, чтобы предотвратить изменение порядка вашего сообщения злоумышленником, и когда вы записываете каждый фрагмент, вы напишу зашифрованные данные плюс тег.
При расшифровке то же самое. Вы выполняете XOR индекса фрагмента с исходным одноразовым номером, чтобы получить одноразовый номер для этого фрагмента и передать индекс и один байт в качестве дополнительных данных. Обратите внимание, что при чтении из файла вы будете считывать 64 КиБ данных плюс 16 байт тега в каждом фрагменте.
Вы, конечно, можете использовать AES-CBC для шифрования данных, но если вы не используете отдельный MAC-адрес, такой как HMAC с безопасной хэш-функцией (например, HMAC-SHA-256), то вы позволяете злоумышленнику вмешиваться в ваши данные, которые не являются безопасными. Поскольку вы должны проверить MAC-адрес перед выпуском открытого текста, чтобы избежать проблем с безопасностью, вы столкнетесь с той же проблемой, что и с AEAD. По сути, AEAD — это просто стандартный алгоритм шифрования со встроенным MAC.
Я попробую, спасибо!
Используйте бинарный поток для записи: learn.microsoft.com/en-us/dotnet/api/…