Статус: Участник
Группы: Участники
Зарегистрирован: 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)
| Причина: Не указана
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 3,962 Откуда: Крипто-Про Сказал(а) «Спасибо»: 20 раз Поблагодарили: 703 раз в 664 постах
|
Здравствуйте. Автор: Capfunny signature.update(docbytes);
Подпись, скорее всего, сделана на атрибуты подписи. Проверка должна выполняться по ним, а не по данным. Примеры есть в файле CMSVerify в пакете CMS_samples архива samples_sources.jar, или можно использовать библиотеку CAdES (примеры там же в пакете CAdES). |
|
1 пользователь поблагодарил Евгений Афанасьев за этот пост.
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 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 - полученная подпись. Исходные данные из моего примера получены именно так.
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 21.09.2018(UTC) Сообщений: 24 Сказал(а) «Спасибо»: 9 раз
|
Опять же, если валидация подписи происходит по её атрибутам, то как тогда понять, что исходный документ, который присылается отдельно, не был изменен?!
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 3,962 Откуда: Крипто-Про Сказал(а) «Спасибо»: 20 раз Поблагодарили: 703 раз в 664 постах
|
"сгенерированная с помощью представленной ниже команды подпись, может верифицироваться по атрибутам, а не по документу, по которому она сгенерирована" - полагаю, да. В CMSVerify есть одноименная функция проверки, попробуйте ее. "как тогда понять, что исходный документ, который присылается отдельно, не был изменен" - в атрибутах есть хеш данных, он сравнивается с хешом данных, переданных для проверки. Эта проверка также есть в CMSVerify.
|
|
1 пользователь поблагодарил Евгений Афанасьев за этот пост.
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 21.09.2018(UTC) Сообщений: 24 Сказал(а) «Спасибо»: 9 раз
|
Евгений Афанасьев, спасибо, вы были правы на счет верификации по атрибутам! Как сравнит хэш документа, и контрольный хэш, хранящийся в подписи - тоже нашел. Остался последний вопрос: как-то можно из самой подписи узнать алгоритм, по которому нужно инициализировать объект Signature? В цитате помечен как "???" Цитата: final Signature signature = Signature.getInstance( ??? , providerName);
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 3,962 Откуда: Крипто-Про Сказал(а) «Спасибо»: 20 раз Поблагодарили: 703 раз в 664 постах
|
Где-то в структуре info.signature, там же, где и голая подпись sign. |
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 21.09.2018(UTC) Сообщений: 24 Сказал(а) «Спасибо»: 9 раз
|
Автор: Евгений Афанасьев Где-то в структуре info.signature, там же, где и голая подпись sign. Евгений, в указанной вами структуре никакой информации по о типе подписи не нашел :( В итоге некоторые документы мне приходят подписанными по стандарту, указанному в переменной JCP.GOST_SIGN_2012_256_NAME, некоторые - JCP.GOST_EL_SIGN_NAME. Как сделать автоматическое определение стандарта для правильной инициализации объекта Signature, я не понимаю :(
|
|
|
|
Статус: Сотрудник
Группы: Участники
Зарегистрирован: 06.12.2008(UTC) Сообщений: 3,962 Откуда: Крипто-Про Сказал(а) «Спасибо»: 20 раз Поблагодарили: 703 раз в 664 постах
|
Алгоритм находится в другом месте, если посмотреть пример CMS, где происходит формирование, то он помещается в поле подписанта (elements[0] - i-ый SignerInfo, i = 0) cms.signerInfos.elements[0].signatureAlgorithm = new SignatureAlgorithmIdentifier(new OID(signOid).value); // signOid - искомый OID алгоритма подписи |
|
|
|
|
Статус: Участник
Группы: Участники
Зарегистрирован: 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. Такого примера я к сожалению не нашел :(
|
|
|
|
Быстрый переход
Вы не можете создавать новые темы в этом форуме.
Вы не можете отвечать в этом форуме.
Вы не можете удалять Ваши сообщения в этом форуме.
Вы не можете редактировать Ваши сообщения в этом форуме.
Вы не можете создавать опросы в этом форуме.
Вы не можете голосовать в этом форуме.
Important Information:
The Форум КриптоПро uses cookies. By continuing to browse this site, you are agreeing to our use of cookies.
More Details
Close