Подпись счетчика недействительна (xades4j)
Я должен подписать и затем подписать некоторые XML с подписью. Это мой код:
private String singXadesEnveloped(String mode, Document document, Certificate[] certificateChain, PrivateKey signingKey, String mimeType, String encoding)
throws XAdES4jException, ClassCastException, UnsupportedEncodingException, ClassNotFoundException,
InstantiationException, IllegalAccessException {
try {
DataObjectDesc desc = null;
KeyingDataProvider kp = new StaticKeyingDataProvider(certificateChain, signingKey);
BasicSignatureOptionsProvider bop=new BasicSignatureOptionsProvider() {
public boolean signSigningCertificate() {
// TODO Auto-generated method stub
return false;
}
public boolean includeSigningCertificate() {
// TODO Auto-generated method stub
return true;
}
public boolean includePublicKey() {
// TODO Auto-generated method stub
return true;
}
};
//System.out.println("bop.includePublic="+bop.includePublicKey());
XadesSigningProfile sp = new XadesBesSigningProfile(kp).withTimeStampTokenProvider(CertumFreeTimeStampProvider.class).withBasicSignatureOptionsProvider(bop);
XadesSigner signer = sp.newSigner();
desc = new DataObjectReference("")
.withDataObjectFormat(new DataObjectFormatProperty(mimeType, encoding))
.withTransform(new EnvelopedSignatureTransform());
SignedDataObjects dataObjects = new SignedDataObjects(desc)
.withCommitmentType(AllDataObjsCommitmentTypeProperty.proofOfOrigin());
Element el = document.getDocumentElement();
//System.out.println("element="+el.getNodeName());
XadesSignatureResult sign = signer.sign(dataObjects, el);
String signed_xml = serializeDocument(document);
//System.out.println("\n\nPodpisany xml:\n"+signed_xml+"\n\n");
XadesSignatureFormatExtender extender = new XadesFormatExtenderProfile().getFormatExtender();
Element sigElem = sign.getSignature().getElement();
//System.out.println("\n\nTag do podpisu:"+sigElem.getNodeName()+"\n\n");
XMLSignature sig = new XMLSignature(sigElem, sigElem.getOwnerDocument().getBaseURI());
XadesSigningProfile profile = new XadesBesSigningProfile(kp).withTimeStampTokenProvider(CertumFreeTimeStampProvider.class).withBasicSignatureOptionsProvider(bop);
final XadesSigner counterSigner = profile.newSigner();
// .withTransform(new ExclusiveCanonicalXMLWithoutComments());
//System.out.println("\n\nNode sygnatury: "+sig.getElement().getNodeName()+"\n\n");
Collection<UnsignedSignatureProperty> usp = new ArrayList(1);
usp.add(new CounterSignatureProperty(counterSigner));
extender.enrichSignature(sig, new UnsignedProperties(usp));
} catch (XMLSignatureException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (XMLSecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*-----------------------------------------------------*/
//alternatywny sposób realizowania podpisu
//new Enveloped(signer).sign(document.getDocumentElement());
DOMSource domSource = new DOMSource(document);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer;
try {
transformer = tf.newTransformer();
transformer.transform(domSource, result);
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println("\n\nsignXades signed before serializedocument: \n\n" + writer.toString());
//return serializeDocument(signed_document);
return writer.toString();
}
Он подписывает мой xml и добавляет встречную подпись. К сожалению, когда я проверяю свой xml, подпись очень хорошо работает, но встречная подпись - нет (Дайджест подписи не равен дайджесту из данных файла).
Что не так с моим кодом? Это XML с подписью и встречной подписью:
2 ответа
Информация разбросана по комментариям, поэтому я выкладываю окончательный ответ здесь. Используемый сторонний инструмент (вероятно, Sigilum Sign, вы можете подтвердить?) Нуждается в http://uri.etsi.org/01903#CountersignedSignature
значение на Type
из основных Reference
во встречной подписи. Спецификация XAdES гласит, что эта ссылка не является обязательной в этом случае использования встречных подписей, что означает, что сторонний инструмент должен их принимать. Тем не менее, последняя версия xades4j всегда включает элемент.
Если вы получили последнюю версию xades4j на Maven, это должно быть исправлено. Если вы получили двоичные файлы в разделе загрузок на веб-сайте xades4j, пожалуйста, получите их снова, так как пакет имел небольшую несогласованность.
Если проблема "Дайджест подписи не совпадает с дайджестом из данных файла", сертификаты не помогают. Тем не менее, я проверил вашу подпись с другим программным обеспечением. Дайджесты и значение подписи в встречной подписи выглядят нормально. Не могли бы вы получить хэшированные значения, используемые в приложении для проверки?
Хэшированный большой двоичный объект для значения подписи, подписанного в встречной подписи:
<ds:SignatureValue xmlns:adr="http://crd.gov.pl/xml/schematy/adres/2008/05/09/" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:inst="http://crd.gov.pl/xml/schematy/instytucja/2008/05/09/" xmlns:iso639-2="http://lcweb.loc.gov/standards/iso639-2/" xmlns:meta="http://crd.gov.pl/xml/schematy/meta/2008/05/09/" xmlns:oso="http://crd.gov.pl/xml/schematy/osoba/2008/05/09/" xmlns:str="http://crd.gov.pl/xml/schematy/struktura/2008/05/09/" xmlns:wnio="http://epuap.gov.pl/FeResourceServlet/wzor_lokalny/twmud37012/Wniosek_odpowiedzi/" Id="xmldsig-2d270d0c-76d2-4638-9e5a-fc149b383552-sigvalue">
orHos56IR77hfwBp2bas3L9E9X4K/oVAyRCkW/00gxon5ZEKCmmT5GhT/Bty6AOC5MsMwDKSgFbe
ysO7kqg5DuSOFPGocR3cBszH4w25Uoouk/0mxKU6BdTKl8Ud/N2RA/rUhvYBvH+JDjOrp+mtEmym
skBfxHssfzecGXQFtzskJLCMaxIhBQIw8RIOkREzFNozCCEw8uo9GEuzyfRC3EypVy8hL1p/qG2z
Ytf2lEJ4EastuCN5etHQSSVT4I9yeJulTj58e4d2IjtcVjJlpV1yetysv0R7E3cJ9YWaL4vH3Yhx
DtVIepegelZa37omW3GMtvIEDa6bdBx8WyMJLA==
</ds:SignatureValue>
Возможная причина сбоя в приложении проверки состоит в том, что вы не используете алгоритмы канонизации в встречной подписи. Я не знаком с xades4J, но я думаю, что его API не позволяет добавлять алгоритм канонизации к встречной подписи.