Добрый день! Пишу интеграцию с есиа по opendid connect на java. Назрел вопрос по проверки подписи маркера доступа/идентификации. Вкратце что сказано в методических указания по поводу проверки подписи:
Маркер доступа/идентификации выглядит как HEADER.PAYLOAD.SIGNATURE в формате Base64Url. SIGNATURE представляет собой подпись в формате PKCS#7 detached signature в кодировке UTF-8 от значений первых двух частей маркера доступа (HEADER.PAYLOAD). Необходимо осуществить проверку данной электронной подписи с использованием сертификата ключа проверки электронной подписи ЕСИА.
Собственно сами вопросы:
Как сделать эту проверку подписи если есть только сама подпись строки(signature) и сама строка которую подписывали (header.payload)?
Откуда взять сертификата ключа проверки электронной подписи ЕСИА (Видел подобный вопрос на stackoverflow но ответов нет)?
Или может эта часть signature имеет в себе какие-то данные сертификата и ключа, и можно как то проверить? если да то как это сделать?
Я так понял что pkcs7 хранит в себе сертификат, и просто этим сертификатом проверяешь эту подпись(то есть себя ж), возможно я что-то я понял не так.. Вот код:
public boolean verify(byte[] data) {
try {
CMSSignedData cmsSignedData = new CMSSignedData(data);
// получаем список сертификатов, которые содержатся в файле
Store<X509CertificateHolder> certs = cmsSignedData.getCertificates();
// p7s файл может содержать данные, которые были подписаны, то есть ваш pdf файл
byte[] content = (byte[]) cmsSignedData.getSignedContent().getContent();
// проходимся по списку подписей, обычно одна подпись, но стандарт поддерживает множество подписей
for (SignerInformation si : cmsSignedData.getSignerInfos()) {
// список всех атрибутов, подписанных вместе с файлом
AttributeTable signedAttributes = si.getSignedAttributes();
// атрибут с именем
Attribute attrSurname = signedAttributes.get(new ASN1ObjectIdentifier("2.5.4.4"));
// атрибут с именем 2
Attribute attrGivenName = signedAttributes.get(new ASN1ObjectIdentifier("2.5.4.42"));
// атрибут с датой подписи
Attribute attrSigningTime = signedAttributes.get(new ASN1ObjectIdentifier("1.2.840.113549.1.9.5"));
// выводим дату подписи
System.out.println(attrSigningTime.getAttributeValues()[0].toString());
// возможно некоторые атрибуты не были частью подписи, формат поддерживает и такие
//AttributeTable unsignedAttributes = si.getUnsignedAttributes();
// получаем идентификатор сертификата, которым подписаны данные
SignerId signerId = si.getSID();
// ищем сертификат в коллекции по идентификатору
Collection certCollection = certs.getMatches(signerId);
// выбираем первый сертификат, здесь не должно быть больше одного
Iterator certIt = certCollection.iterator();
X509CertificateHolder certHolder = (X509CertificateHolder) certIt.next();
// создаем Verifier на основании сертификата, Verifier использует публичный ключ сертификата
SignerInformationVerifier verifier = new JcaSimpleSignerInfoVerifierBuilder().build(certHolder);
// проверяем подпись
return si.verify(verifier);
}
} catch (CertificateException | OperatorCreationException | CMSException e) {
logger.error(e);
}
return false;
}
Как я понял byte[] content может не содержать самих данных которые подписывает а может и содержать. Так же Attribute *** написаны чисто для проверки. И еще маркер состоит из header.payload.signature в формате base64url, поэтому signature надо декодировать примерно так:
byte[] data = Base64.getUrlDecoder().decode(a);
И уже эту data надо отправлять в эту функцию public boolean verify(byte[] data). Возможно это решение не верное, я точно не знаю. Если это правильно/неправильно то напишите что все ок или подскажите как правильно.
Как в Java получить FolderlastModified()? Вариант рекурсивного просмотра каталога в глубину и взятие даты последнего файла не подходит, так как каталог...
Как указать относительный путь для embedded Firebird? Вот так не работает: jdbc:firebirdsql://localhost/examfdb
Имеется listView, в который по клику на item добавляется imageПри втором клике на другой item изображение вновь подставляется, а с первого item'a изображение...