Ключевое слово в защите информации
КЛЮЧЕВОЕ СЛОВО
в защите информации
Получить ГОСТ TLS-сертификат для домена (SSL-сертификат)
Добро пожаловать, Гость! Чтобы использовать все возможности Вход или Регистрация.

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline Noskov Roman  
#1 Оставлено : 17 августа 2018 г. 18:33:18(UTC)
Noskov Roman

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2018(UTC)
Сообщений: 14
Российская Федерация

Сказал(а) «Спасибо»: 2 раз
Добрый день, коллеги!

Стоит задача расшифрования очень больших файлов (размеры порядка нескольких десятков ГБ) и последующего снятия подписи (присоединенная подпись в упаковке PKCS7/CMS) и ее проверки при помощи JCP 2.0.39014. В условиях ограниченности по оперативной памяти, необходимо работать c файлами в режиме потоков.

Если с расшифрованием больших объемов данных при помощи объекта класса envelopedSignature, конструктор которого принимает в качестве аргумента InputStream, проблем не составляет (один из вариантов перегруженного метода decrypt так же возвращается InputStream) и все работает как надо, то со снятием подписи и ее проверке возникает ряд проблем.

1) Не нашел подходящего варианта в примерах для снятия подписи, кроме как следующего варианта:

Код:

    public byte[] unsign(InputStream dataStream) throws Asn1Exception, IOException {
        Asn1BerDecodeBuffer dbuf = new Asn1BerDecodeBuffer(dataStream);
        final ContentInfo all = new ContentInfo();
        all.decode(dbuf);
        final SignedData cms = (SignedData) all.content;
        byte[] text = null;
        if (cms.encapContentInfo.eContent != null) {
            text = cms.encapContentInfo.eContent.value;
        }
        return text;
    }

По очевидным причинам данный способ не подходит.
Вместо этого приходится использовать объект класса CMSSignedDataParser, один из конструкторов которого принимает в качестве одного из аргументов поток данных в виде InputStream, из библиотеки bouncycastle. Из данного объекта вытягиваются подписанные данные в виде InputStream. Вроде бы решение и рабочее, но хотелось бы решение из коробки JCP.

2) Для проверки подписи маленьких файлов очень хорошо и удобно подходит использование объекта CAdESSignature, один из конструкторов которого опять же принимает в аргументах данные в InputStream, однако при создании такого объекта во время работы с большим файлом возникает исключительная ситуация java.lang.OutOfMemoryError: Java heap space. После небольшого количества экспериментов и анализа пришел к выводу, что во время создания объекта под капотом происходит попытка вычитать файл полностью в память.
В одном из примеров (LargeFileTest из пакета CMS_samples), идущих в комплекте с jcp, приводится пример проверки подписи, но складывается ощущение, что проверяются только сертификаты подписантов. Поэтому вопрос, является ли это достаточной и полной проверкой подписи? Есть ли решение в составе jcp для проверки присоединенной подписи больших файлов?



Возможно, я до чего-то не докопался, пропустил по невнимательности или под неправильным соусом готовлю. Прошу подсказать и направить на путь истинный, как с помощью средств JCP реализовать поставленные задачи. И ответить, возможное ли вообще такое.
Буду рад любым ответам и помощи в любом виде!
Спасибо

P.S. для разработки тестовые данные подписывались и шифровались с помощью КриптоАРМ, который без проблем проглатывал объемы сырых данных порядка 50 Гб

UPD LargeFileTest из пакета CMS_samples тоже вываливается с OutOfMemoryError, но уже при попытке генерации подписи

Отредактировано пользователем 21 августа 2018 г. 10:09:29(UTC)  | Причина: Не указана

Offline Евгений Афанасьев  
#2 Оставлено : 24 августа 2018 г. 10:15:15(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,910
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Здравствуйте.
Действительно, при подписи/проверке больших объемов с помощью CAdESSignature возникает OutOfMemoryError. Спасибо, ошибка исправлена, изменение войдет в следующий релиз. Пока можно использовать вариант raw-подписи с помощью CAdESSignature. Конструктор CAdESSignature принимает также параметр rawSignature (конструктор с двумя параметрами - detached и rawSignature), который означает, что в метод update() объекта класса CAdESSignature будут переданы не данные, а хеш, который вы можете вычислить сами (MessageDigest -> update()...update()...digest() -> CAdESSignature s = new CAdESSignature(true|false, true) -> s.update(<digest>)).
Пример LargeFileTest только создает и проверяет подпись, цепочка сертификатов не проверяется, подпись формируется CMS (LargeFileTest использует GostDigestCalculatorProvider, в котором ошибка).
thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
Noskov Roman оставлено 28.08.2018(UTC)
Offline Noskov Roman  
#3 Оставлено : 28 августа 2018 г. 15:09:29(UTC)
Noskov Roman

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2018(UTC)
Сообщений: 14
Российская Федерация

Сказал(а) «Спасибо»: 2 раз
Автор: Евгений Афанасьев Перейти к цитате
Здравствуйте.
Действительно, при подписи/проверке больших объемов с помощью CAdESSignature возникает OutOfMemoryError. Спасибо, ошибка исправлена, изменение войдет в следующий релиз. Пока можно использовать вариант raw-подписи с помощью CAdESSignature. Конструктор CAdESSignature принимает также параметр rawSignature (конструктор с двумя параметрами - detached и rawSignature), который означает, что в метод update() объекта класса CAdESSignature будут переданы не данные, а хеш, который вы можете вычислить сами (MessageDigest -> update()...update()...digest() -> CAdESSignature s = new CAdESSignature(true|false, true) -> s.update(<digest>)).
Пример LargeFileTest только создает и проверяет подпись, цепочка сертификатов не проверяется, подпись формируется CMS (LargeFileTest использует GostDigestCalculatorProvider, в котором ошибка).


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

Так же интересует момент получения подписанных данных из CMS сообщения, описанный в первом пункте. Есть ли готовое решение из коробки JCP для получение подписанных данных в виде стрима? И следом хочу задать связный, как мне кажется, вопрос. Возможно ли одновременное получение подписанных данных и проверка подписи, используя один InputStream, если не брать в рассмотрение проблему, связанную с переполнением хипа джавы? Как я понял из примеров/документации/собственных наблюдений, при попытке проверить подпись и вытащить данные, комбинируя озвученные мной в предыдущем сообщении подходы, стрим полностью вычитывается на одном из шагов, поэтому во время второго процесса возникает проблема, что стрим уже пуст или даже закрыт.

Спасибо
Offline Евгений Афанасьев  
#4 Оставлено : 28 августа 2018 г. 15:14:13(UTC)
Евгений Афанасьев

Статус: Сотрудник

Группы: Участники
Зарегистрирован: 06.12.2008(UTC)
Сообщений: 3,910
Российская Федерация
Откуда: Крипто-Про

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Автор: Noskov Roman Перейти к цитате

Евгений, благодарю за ответ, а также за предложенный альтернативный вариант подписи в данной ситуации, но, к сожалению, если я правильно вас понял, то озвученный подход в условиях имеющейся задачи не подходит, т.к. подписывается изначальное сообщение, а не его хеш.
Так же интересует момент получения подписанных данных из CMS сообщения, описанный в первом пункте. Есть ли готовое решение из коробки JCP для получение подписанных данных в виде стрима? И следом хочу задать связный, как мне кажется, вопрос. Возможно ли одновременное получение подписанных данных и проверка подписи, используя один InputStream, если не брать в рассмотрение проблему, связанную с переполнением хипа джавы? Как я понял из примеров/документации/собственных наблюдений, при попытке проверить подпись и вытащить данные, комбинируя озвученные мной в предыдущем сообщении подходы, стрим полностью вычитывается на одном из шагов, поэтому во время второго процесса возникает проблема, что стрим уже пуст или даже закрыт.

Мне показалось, что это решение вам подходит - подпись хеша, который вы сами посчитаете (эта же задача выполнялась бы в CAdESSignature при передачи данных порциями, если бы не ошибка).
К сожалению, в текущей реализации пока нет возможности получить данные в виде потока. Как вы верно заметили, поток данных закрывается в одной из стадий декодирования подписи. Мы работаем над устранением проблемы.

thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
Noskov Roman оставлено 28.08.2018(UTC)
Offline Noskov Roman  
#5 Оставлено : 28 августа 2018 г. 16:23:51(UTC)
Noskov Roman

Статус: Участник

Группы: Участники
Зарегистрирован: 17.08.2018(UTC)
Сообщений: 14
Российская Федерация

Сказал(а) «Спасибо»: 2 раз
Автор: Евгений Афанасьев Перейти к цитате

Мне показалось, что это решение вам подходит - подпись хеша, который вы сами посчитаете (эта же задача выполнялась бы в CAdESSignature при передачи данных порциями, если бы не ошибка).
К сожалению, в текущей реализации пока нет возможности получить данные в виде потока. Как вы верно заметили, поток данных закрывается в одной из стадий декодирования подписи. Мы работаем над устранением проблемы.


Как альтернативное решение во избежание проблемы с большими объемами данных вышеописанный подход хороший, я согласен. Но, к сожалению, поставщиком данных является сторонняя организация и данный вариант подписи у них используется давно. Поэтому нет возможности изменить подпись самого сообщения на подпись его хеша. Собственно поэтому я так и выразился, что в рамках имеющейся задачи, данный способ не совсем подходит :(

Все равно, спасибо за помощь! Будем ждать новых релизов J

RSS Лента  Atom Лента
Пользователи, просматривающие эту тему
Быстрый переход  
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.