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

Уведомление

Icon
Error

2 Страницы12>
Опции
К последнему сообщению К первому непрочитанному
Offline Capfunny  
#1 Оставлено : 21 сентября 2018 г. 16:56:08(UTC)
Capfunny

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

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

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

От заказчика приходит пакет следующей структуры: подписанный докумет (xml), закодированный в Base64, цифровая подпись, которой подписан данный документ, содержащая сертификат с открытым ключом для верификации. Подпись тоже завернута в Base64, впрочем предполагаю, что она упакована в Base64 ещё при генерации.
Нужно заметить, что заказчик сгенерировал эту подпись с помощью утилиты cryptcp из пакета CSP.

Пытаюсь верифицировать подпись документа с помощью кода, представленного ниже. В итоге верификация не проходит.
Подскажите пожалуйста, что что я делаю не так? Уже всю голову сломал!
Полная версия кода в приложенном файле. TestSignature.java.zip (4kb) загружен 4 раз(а).

Цитата:
static void VerifaySignature(String document, String signdata, String signName, String providerName){

try {

final byte[] docbytes = Base64.decode(document);
final Decoder decoder = new Decoder();
final byte[] signbytes = decoder.decodeBuffer(signature);
final Asn1BerDecodeBuffer asnBuf = new Asn1BerDecodeBuffer(signbytes);
final ContentInfo ci = new ContentInfo();
ci.decode(asnBuf);
final SignedData cms = (SignedData) ci.content;

final Certificate[] certs = readCertificates(ci);
Certificate certificate = null;
int pos = -1;
if (certs.length > 0){
pos = 0;
certificate = certs[pos];
}
else{
throw new Exception("Сертификакт не найден!");
}

final SignerInfo info = cms.signerInfos.elements[pos];
final byte[] sign = info.signature.value;
final Signature signature = Signature.getInstance(signName, providerName);
signature.initVerify(certificate);
signature.update(docbytes);

boolean result = signature.verify(sign);

if (result) {
System.out.println("Вадидация подписи прошла успешно!");
}
else {
System.out.println("Не удалось валидировать подпись!");
}
}
catch (Exception e)
{
System.out.println("Ошибки:");
System.out.println(e.fillInStackTrace());
}

}

Отредактировано пользователем 24 сентября 2018 г. 16:49:52(UTC)  | Причина: Не указана

Offline Евгений Афанасьев  
#2 Оставлено : 21 сентября 2018 г. 17:27:02(UTC)
Евгений Афанасьев

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

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

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

signature.update(docbytes);

Подпись, скорее всего, сделана на атрибуты подписи. Проверка должна выполняться по ним, а не по данным. Примеры есть в файле CMSVerify в пакете CMS_samples архива samples_sources.jar, или можно использовать библиотеку CAdES (примеры там же в пакете CAdES).
thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
Capfunny оставлено 21.09.2018(UTC)
Offline Capfunny  
#3 Оставлено : 21 сентября 2018 г. 17:34:30(UTC)
Capfunny

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

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

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

signature.update(docbytes);

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


Спасибо, Евгений!

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

Пример команды для генерации:

Цитата:
cryptcp -vsignf /tmp/document.txt -f /tmp/document.txt.sgn


- document.txt - файл с документом в формате UTF-8;
- document.txt.sgn - полученная подпись.

Исходные данные из моего примера получены именно так.

Offline Capfunny  
#4 Оставлено : 21 сентября 2018 г. 17:50:04(UTC)
Capfunny

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

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

Сказал(а) «Спасибо»: 9 раз
Опять же, если валидация подписи происходит по её атрибутам, то как тогда понять, что исходный документ, который присылается отдельно, не был изменен?!
Offline Евгений Афанасьев  
#5 Оставлено : 21 сентября 2018 г. 18:23:40(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
"сгенерированная с помощью представленной ниже команды подпись, может верифицироваться по атрибутам, а не по документу, по которому она сгенерирована" - полагаю, да. В CMSVerify есть одноименная функция проверки, попробуйте ее.
"как тогда понять, что исходный документ, который присылается отдельно, не был изменен" - в атрибутах есть хеш данных, он сравнивается с хешом данных, переданных для проверки. Эта проверка также есть в CMSVerify.
thanks 1 пользователь поблагодарил Евгений Афанасьев за этот пост.
Capfunny оставлено 21.09.2018(UTC)
Offline Capfunny  
#6 Оставлено : 21 сентября 2018 г. 19:13:52(UTC)
Capfunny

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

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

Сказал(а) «Спасибо»: 9 раз
Евгений Афанасьев, спасибо, вы были правы на счет верификации по атрибутам!
Как сравнит хэш документа, и контрольный хэш, хранящийся в подписи - тоже нашел.

Остался последний вопрос: как-то можно из самой подписи узнать алгоритм, по которому нужно инициализировать объект Signature?
В цитате помечен как "???"

Цитата:
final Signature signature = Signature.getInstance( ??? , providerName);


Offline Евгений Афанасьев  
#7 Оставлено : 21 сентября 2018 г. 20:51:22(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Где-то в структуре info.signature, там же, где и голая подпись sign.
Offline Capfunny  
#8 Оставлено : 24 сентября 2018 г. 11:01:28(UTC)
Capfunny

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

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

Сказал(а) «Спасибо»: 9 раз
Автор: Евгений Афанасьев Перейти к цитате
Где-то в структуре info.signature, там же, где и голая подпись sign.


Евгений, в указанной вами структуре никакой информации по о типе подписи не нашел :(
В итоге некоторые документы мне приходят подписанными по стандарту, указанному в переменной JCP.GOST_SIGN_2012_256_NAME,
некоторые - JCP.GOST_EL_SIGN_NAME.
Как сделать автоматическое определение стандарта для правильной инициализации объекта Signature, я не понимаю :(
Offline Евгений Афанасьев  
#9 Оставлено : 24 сентября 2018 г. 11:05:20(UTC)
Евгений Афанасьев

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

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

Сказал(а) «Спасибо»: 20 раз
Поблагодарили: 685 раз в 646 постах
Алгоритм находится в другом месте, если посмотреть пример CMS, где происходит формирование, то он помещается в поле подписанта (elements[0] - i-ый SignerInfo, i = 0)
cms.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(signOid).value); // signOid - искомый OID алгоритма подписи
Offline Capfunny  
#10 Оставлено : 24 сентября 2018 г. 12:49:34(UTC)
Capfunny

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

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

Сказал(а) «Спасибо»: 9 раз
Автор: Евгений Афанасьев Перейти к цитате
Алгоритм находится в другом месте, если посмотреть пример CMS, где происходит формирование, то он помещается в поле подписанта (elements[0] - i-ый SignerInfo, i = 0)
cms.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(signOid).value); // signOid - искомый OID алгоритма подписи


Евгений, хорошо, из атрибута cms.signerInfos.elements[0].signatureAlgorithm я получу строку OID цифровой подписи. А как по нему определить константу для инициализации объекта Signature? Там именно строковая константа с именем алгоритма: "GOST3411withGOST3410EL", "GOST3411_2012_256withGOST3410_2012_256" и т.п.:

Signature signature = Signature.getInstance(signAlg,...); ???

Дело в том, что чтобы правильно верифицировать подпись, мне нужно получить правильный инстанс объекта Signature, а для этого требуется именно константа signAlg!
Для разных подписей она разная, то есть её нужно как-то определять в runtime, и видимо именно по OID. Такого примера я к сожалению не нашел :(




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