06.04.2007 12:35:09Увеличение объема подписанных/зашифрованных данных... Ответов: 9
Максим
Подписываю и шифрую файлы используя CAPICOM на C#.
Перед подписью перегоняю содерживое файла в Base64, т.к. методы CAPICOM'а принимают именно строковые аргументы,а бинарные данные в C#-строках хранить нельзя.

Проблема:
После перекодировки файла в Base64 и установки ЭЦП размер файла увеличивается ~4 раза.
После шифрования объем данных увеличивается в 10! раз от исходного.

Это нормально для ГОСТ алгоритмов ЭЦП/шифрования или какие то ошибки реализации?
Можно ли как то "сократить увеличение" объема подписываемых/шифруемых данных?
 
Ответы:
06.04.2007 13:52:43Максим
И вот еще. Пытаюсь зашифровать подписанный файл, размер (после подписи) 45 МБ.

При вызове метода Encrypt машина задумывается, а потом вылетает исключение:
Not enough storage is available to process this command.

С чем такое может быть связано?

Мой код почти полностью копирует ваш VBS-пример шифрования через CAPICOM из SDK, но на C#.
Ваш код отрабатывает нормально на этом подписанном файле, мой валится :(

Пожалуйста, помогите разобраться!
09.04.2007 11:31:10Василий
Алгоритмы не при чём.

Кодирование в base64 не должно увеличивать объём данных более чем в 2-3 раза. Правда, нужно учесть, что, после кодирования исходных данных и подписи их результат снова кодируется в base64 (с увеличением размера), потом шифрование и кодирование результата снова в base64.

Попробуйте для контроля размера подписать и зашифровать ваш исходный файл с использованием готового приложения - КриптоАРМ (дистрибутив http://www.cryptopro.ru/CryptoPro/products/crypto-arm/trusteddesktop_ru_2_5_1_35.exe, лицензия на 30 дней бесплатная). После установки просто в контекстном меню на файле выберите "Подписать и зашифровать" и кодировку base64.
Потом ту же операцию проделайте на файле, который закодирован вами в base64.
09.04.2007 12:44:14Максим
Спасибо, Василий!

Что касается увеличения размера - ваши VBS-примеры подписи/шифрования из SDK дают такой же результат, если прогнать через них файл кодированный в Base64. С этим вроде ясно.

Полагяю мне подошел бы альтернативный вариант (пока правда не опробывал): делать detached-подпись и шифрование файла. Сама подпись невелика по размеру, а с громоздкими результатами шифрования придется мириться. Я прав?

Но вот вторая часть моего вопроса:
Почему при вызове с C# метода Encrypt происоходит эксепшен (Not enough storage is available to process this command.)? Для тех же исходных данный, ваши VBS-примеры нормально все шифруют. Возможно это особенность распределения памяти .NET-средой. Кстатьи, судя по показаниям Диспетчера задач, мой процесс при шифровании файла ~50 MB кушат под гиг памяти. Как с этим можно бороться?

Может можно было бы шифровать большие файлы кусками, но... В моем случае подпись и последующее шифрование используется в системе электронного документооборота. Будет ли считаться юридически значимой передача документа, который был подписан, затем нарезан и кусками зашифрован (и наоборот получателем)? Ведь при этом как бы нарушается "целостность" подписанного документа.

Какие вообще есть варианты шифрования больших файлов (десятки МБ)?
09.04.2007 13:00:25Василий
Вопрос - Вы используете CSP 3.0? Если да - КС1 или КС2?

Про шифрование кусками - там не совсем так. Исходные данные не режутся для шифрования по отдельности, шифрование работает в специальном режиме (есть флажок, указывающий, что данный кусок - не последний). От способа разделения результат шифрования не зависит (при одинаковых ключах).
Собственно, шифрование и не предназначено для обеспечения юридической значимости - оно только для защиты от несанкционированного доступа (НСД). Даже если Вы реально будете шифровать каждый кусок отдельно и передавать их независимо.
Вся юридическая сторона - на ЭЦП.
09.04.2007 13:13:24Максим
Да CSP 3.0 через CAPICOM. Пардон, а что есть КС1 / КС2? :)

Для метода EnvelopedData.Encrypt никаких аргументов, задаюших режим шифрования. Вы имеете ввиду CryptoAPI?
Если всетаки и через CAPICOM шифровать как то блоками можно, пожалуйста, подскажите как!

Что шифрование "не для юридической значимости" - это тоже понятно. Я имеел ввиду вручную разбивать подписанный файл на блоки (нарушение целостности) каждый из них шифровать отдельно - "склеивает" уже получатель.
09.04.2007 14:24:48Василий
КС1 или 2 - вариант исполнения. КС2 более защищённый вариант (ключи хранятся в "Службе хранения ключей" и не передаются приложению). При этом, данные (для обработки при ЭЦП и шифровании) и результаты передаются от приложения к службе по RPC (что может вызвать непредвиденные накладные расходы при неправильно выбранном режиме подписи или шифрования).
В панели CSP (cpconfig.cpl) на вкладке Общие написано - КС1 или КС2.
09.04.2007 14:36:03Максим
Спасибо за разъяснения, Василий! Используется КС1.

Скажите, для CAPICOM можно задать решим ширования блоками небольшой длины? Или придется спустится к CryptoAPI?
Подозреваю, что у меня шифрование происходит надо всем буфером целиком (10-ки МБ), и из за этого процесс потребляет столько памяти и случается Not enough storage...
09.04.2007 19:02:59Василий
По-видимому, нельзя.
Придётся использовать CryptoAPI или собственный COM с нужными свойствами.
10.04.2007 9:31:50Максим
"Придётся использовать CryptoAPI или собственный COM с нужными свойствами" - вот и я об этом уже думаю.

Спасибо, Василий!