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

Уведомление

Icon
Error

Опции
К последнему сообщению К первому непрочитанному
Offline mcseemcher  
#1 Оставлено : 22 апреля 2020 г. 8:11:42(UTC)
mcseemcher

Статус: Новичок

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

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

Стоит задача подписать pdf-файл(хэш файла), взял пример из документации itext 7 C4_09_DeferredSigning.java

1. На сервере создаю pdf с пустой подписью
Код:
    public void emptySignature(String src, String dest, String fieldname)
            throws IOException, GeneralSecurityException {
        PdfReader reader = new PdfReader(src);
        PdfSigner signer = new PdfSigner(reader, new FileOutputStream(dest), new StampingProperties());
        PdfSignatureAppearance appearance = signer.getSignatureAppearance();
        appearance
                .setPageRect(new Rectangle(36, 748, 200, 100))
                .setPageNumber(1);
                //.setCertificate(chain[0]);
        signer.setFieldName(fieldname);
        IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.Adobe_PPKLite,
                PdfName.Adbe_pkcs7_detached);
 
        signer.signExternalContainer(external, 8192);
    }  

2. Передаю base64 клиенту, там делаю хэш
Код:
        var oHashedData = cadesplugin.CreateObject("CAdESCOM.HashedData");
        oHashedData.Algorithm = cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256;
        oHashedData.DataEncoding = cadesplugin.CADESCOM_BASE64_TO_BINARY;
        oHashedData.Hash(dataInBase64);
        var sHashValue = oHashedData.Value;

3. Подписываю на клиенте
Код:
var oSigner = cadesplugin.CreateObject("CAdESCOM.CPSigner");    
    oSigner.Certificate = certObject;
    var oSignedData = cadesplugin.CreateObject("CAdESCOM.CadesSignedData");
    var oHashedData = cadesplugin.CreateObject("CAdESCOM.HashedData");
    oHashedData.Algorithm = cadesplugin.CADESCOM_HASH_ALGORITHM_CP_GOST_3411_2012_256;
    oHashedData.DataEncoding = 0x01;
    oHashedData.SetHashValue(dataToSign);
    var Signature = oSignedData.SignHash(oHashedData, oSigner, CADESCOM_CADES_BES);
    return Signature;

4. Передаю подпись на сервер, на сервере вставляю в заготовленный файл pdf
Код:
    public void createSignature(String src, String dest, String fieldName, String signature)
            throws IOException, GeneralSecurityException {
    	
    	byte[] decodedBytes = Base64.getDecoder().decode(signature);
    	
        PdfReader reader = new PdfReader(src);
        try(FileOutputStream os = new FileOutputStream(dest)) {
            PdfSigner signer = new PdfSigner(reader, os, new StampingProperties());
 
            MyExternalSignatureContainer external = new MyExternalSignatureContainer(null, null);
            external.setSignature(decodedBytes);
 
            signer.signDeferred(signer.getDocument(), fieldName, os, external);
        }
    }
 
    class MyExternalSignatureContainer implements IExternalSignatureContainer {
 
        protected PrivateKey pk;
        protected Certificate[] chain;
        private byte[] signature;
        public void setSignature(byte[] decodedBytes) {
        	this.signature = decodedBytes;
        }
 
        public MyExternalSignatureContainer(PrivateKey pk, Certificate[] chain) {
            this.pk = pk;
            this.chain = chain;
        }
 
        public void modifySigningDictionary(PdfDictionary signDic) {
        }

		@Override
		public byte[] sign(InputStream arg0) throws GeneralSecurityException {
			return this.signature;
		}
    }  


Я нашел аналогичные решенные задачи, например, здесь и здесь и, как мне кажется, последовательность действий верная. Но в результате я пытаюсь проверить подпись через Adobe Reader с плагином и получаю ошибку "Ошибка при проверке - неподдерживаемый алгоритм".

Пожалуйста, подскажите, в чем может быть проблема?
Поддерживается ли itext7 или нужно обязательно использовать itext5.5?

Спасибо
Offline Андрей *  
#2 Оставлено : 22 апреля 2020 г. 9:22:50(UTC)
Андрей *

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

Группы: Участники
Зарегистрирован: 26.07.2011(UTC)
Сообщений: 12,680
Мужчина
Российская Федерация

Сказал «Спасибо»: 500 раз
Поблагодарили: 2043 раз в 1584 постах
Здравствуйте.
Какая версия Криптопро csp на клиенте?
Техническую поддержку оказываем тут
Наша база знаний
Offline mcseemcher  
#3 Оставлено : 22 апреля 2020 г. 9:27:49(UTC)
mcseemcher

Статус: Новичок

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

Сказал(а) «Спасибо»: 2 раз
Автор: Андрей * Перейти к цитате
Здравствуйте.
Какая версия Криптопро csp на клиенте?


Версия продукта: 4.0.9944
Версия ядра СКЗИ: 4.0.9017 КС1
Offline mcseemcher  
#4 Оставлено : 22 апреля 2020 г. 10:18:49(UTC)
mcseemcher

Статус: Новичок

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

Сказал(а) «Спасибо»: 2 раз
Мне кажется, я как-то неправильно формирую подпись потому, что в Adobe Reader нет никакой читабельной информации, кроме времени подписи:
ошибка

Добавил в код подписания oSigner.Options = cadesplugin.CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN, но это ничего не дало.
Offline mcseemcher  
#5 Оставлено : 22 апреля 2020 г. 15:44:29(UTC)
mcseemcher

Статус: Новичок

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

Сказал(а) «Спасибо»: 2 раз
Переписал все на версию itextpdf_patched-5.5.5

Создание пустой подписи и получение байтов для подписи
Код:
    public byte[] emptySignature(String src, String dest, String fieldname)
            throws IOException, GeneralSecurityException, DocumentException {
    	
        PdfReader reader = new PdfReader(src);
        FileOutputStream os = new FileOutputStream(dest);
        PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
        PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
        appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, fieldname);
        ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
        MakeSignature.signExternalContainer(appearance, external, 8192);
        
        byte[] data = IOUtils.toByteArray(appearance.getRangeStream());
        
        reader.close();
        
        return data;
    	
    }


Добавление подписи в предварительно заготовленный pdf
Код:
    public void createSignature(String src, String dest, String fieldName, String signature)
            throws IOException, GeneralSecurityException, DocumentException {
    	
        PdfReader reader = new PdfReader(src);
        FileOutputStream os = new FileOutputStream(dest);
        
        byte[] decodedBytes = Base64.getDecoder().decode(signature);
        
        ExternalSignatureContainer external = new MyExternalSignatureContainer(decodedBytes);
        MakeSignature.signDeferred(reader, fieldName, os, external);
        
        reader.close();
    }
    class MyExternalSignatureContainer implements ExternalSignatureContainer {
 
        protected PrivateKey pk;
        protected Certificate[] chain;
        private byte[] signature;
        public MyExternalSignatureContainer(byte[] decodedBytes) {
			this.signature = decodedBytes;
		}

		public void setSignature(byte[] decodedBytes) {
        	this.signature = decodedBytes;
        }

		@Override
		public byte[] sign(InputStream arg0) throws GeneralSecurityException {
			return this.signature;
		}

		@Override
		public void modifySigningDictionary(PdfDictionary arg0) {
			// TODO Auto-generated method stub
			
		}
    }



Сообщение в Adobe Reader не изменилось.


Offline mcseemcher  
#6 Оставлено : 23 апреля 2020 г. 12:26:21(UTC)
mcseemcher

Статус: Новичок

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

Сказал(а) «Спасибо»: 2 раз
Видимо, я настолько обзорно ставлю задачу или настолько далек от понимания того, что делаю, что моя проблема не получает отклика.

Попробую сформулировать более конкретные вопросы, которые потенциально может помочь продвинуться. Пожалуйста, помогите с консультацией.

1. При формировании контейнера подписи в pdf критично ли заполнение поля Certificate (appearance.setCertificate) и прочих полей (Reason, Location)?
2. Если заполнение поля Certificate обязательно, как получить сертификат на сервере, если подпись происходит на клиенте?
3. Если цепь сертификатов зашивается в подпись (CAPICOM_CERTIFICATE_INCLUDE_WHOLE_CHAIN), можно ли её вытащить из подписи на сервере, чтобы вставить в appearance? И нужно ли это?

Заранее благодарен за ответы
Offline mcseemcher  
#7 Оставлено : 24 апреля 2020 г. 11:09:07(UTC)
mcseemcher

Статус: Новичок

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

Сказал(а) «Спасибо»: 2 раз
Разобрался. На самом деле код, описанный выше верный и работает (на момент написания проверял код, который на версии itext 5.5 patched).

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