I tried validate signature if i change something in file and add more than one signature. I got error like this:
xades4j.verification.ReferenceValueException: Reference '' cannot be validated
at xades4j.verification.XadesVerifierImpl.doCoreVerification(XadesVerifierImpl.java:306)
at xades4j.verification.XadesVerifierImpl.verify(XadesVerifierImpl.java:188)
at XAdESSignature.verifyBes(XAdESSignature.java:227)
at XAdESSignature.signWithoutIDEnveloped(XAdESSignature.java:127)
at XAdESSignature.main(XAdESSignature.java:75)
this is my code:
Validate Signature
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new FileReader("F:/keystore/example_signed.xml")));
DOMHelper.useIdAsXmlId(doc.getDocumentElement());
NodeList nl = doc.getElementsByTagNameNS(Constants.SignatureSpecNS, Constants._TAG_SIGNATURE);
new FileSystemDirectoryCertStore("F:/keystore/");
KeyStore ks;
try (FileInputStream fis = new FileInputStream("F:/keystore/xml_encrypt.p12")) {
ks = KeyStore.getInstance("jks");
ks.load(fis, "password".toCharArray());
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
aliases.nextElement();
}
}
CertificateValidationProvider provider = new PKIXCertificateValidationProvider(
ks, false);
XadesVerificationProfile profile = new XadesVerificationProfile(provider);
Element sigElem = (Element) nl.item(0);
//XAdESVerificationResult r = profile.newVerifier().verify(sigElem, null);
XadesVerifier verifier = profile.newVerifier();
XAdESVerificationResult r = verifier.verify(sigElem, null); // error on this line
//////////////////// Get document ///////////////////
File fXmlFile = new File(path);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
///////////////////// Output document ////////////////
// Prepare the output file
File outFile = new File(outputPath);
outFile.getParentFile().mkdirs();
outFile.createNewFile();
FileOutputStream fos = new FileOutputStream(outFile);
StreamResult result = new StreamResult(fos);
// Write the DOM document to the file
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(source, result);
fos.close();
//////////////////// Sign document///////////////////
Element elementToSign = sourceDoc.getDocumentElement();
String refUri;
if (elementToSign.hasAttribute("Id")) {
refUri = '#' + elementToSign.getAttribute("Id");
} else {
if (elementToSign.getParentNode().getNodeType() != Node.DOCUMENT_NODE) {
throw new IllegalArgumentException("Element without Id must be the document root");
}
refUri = "";
}
DataObjectDesc dataObjRef = new DataObjectReference(refUri)
.withTransform(new EnvelopedSignatureTransform())
.withCommitmentType(CommitmentTypeProperty.proofOfApproval());
SignedDataObjects obj = new SignedDataObjects(dataObjRef);//.withCommitmentType(AllDataObjsCommitmentTypeProperty.proofOfOrigin());
signer.sign(obj, signatureParent);
///////////////// My signature on xml ///////////////////
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Id="xmldsig-11726720-b544-4fa5-92fb-2564ef07d286">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference Id="xmldsig-11726720-b544-4fa5-92fb-2564ef07d286-ref0" URI="">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>A5Z3NT1vAgPSy7sPwdDvvJDo0+723yrmcrl1tJD3aQc=</ds:DigestValue>
</ds:Reference>
<ds:Reference Type="http://uri.etsi.org/01903#SignedProperties" URI="#xmldsig-11726720-b544-4fa5-92fb-2564ef07d286-signedprops">
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>05y3i/p7/JmDAFQatD2EmClNNAvMBSVXBkEnYPS/zYA=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue Id="xmldsig-11726720-b544-4fa5-92fb-2564ef07d286-sigvalue">
CMC5c43tlxky4Nxme0szAl0yfywF+EQ9KOenOPoKAokoo3/RrcNsyglhPWl5FHmUr/2TV8hYqjHs
39yIYcs508FBFZ9IYFDLciEpssm+zfB9XDc36quhHbMZ+2iF0XtR0qpAGXucSJFu1s1WW0fyn+UM
epxvKcr/d9AeM2sIZzYhqp7xAw4jFfRJwaoS31VsZFOA5QWwRjp0k7Ew+CuhzWuVADWfDb8VsfbV
lTafjS/Ck0l43OfmG8LjzjsrIMaTyUN8aaTvuGSYamQs2peuXOnjCZRD/E/jmOcjLW9QR8UYBItt
RXIzUknywGXqQfUwoAQdJd/gMavwf/XBEPrcAw==
</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>
MIIDezCCAmOgAwIBAgIEVhg1GDANBgkqhkiG9w0BAQsFADBuMQswCQYDVQQGEwJVUzEQMA4GA1UE
CBMHQmFuZ2tvazEQMA4GA1UEBxMHQmFuZ2tvazEaMBgGA1UEChMRVGhhaXRpemVucyBDbyBMdGQx
CzAJBgNVBAsTAklUMRIwEAYDVQQDEwlTa3l0aXplbnMwHhcNMTcwNjE2MDQzNTQyWhcNMTgwNjEx
MDQzNTQyWjBuMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQmFuZ2tvazEQMA4GA1UEBxMHQmFuZ2tv
azEaMBgGA1UEChMRVGhhaXRpemVucyBDbyBMdGQxCzAJBgNVBAsTAklUMRIwEAYDVQQDEwlTa3l0
aXplbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCOQfTbec5Rfj8OcJzY8dalGgjj
zyVCmsEYN9etGJAT4JX0sqqv5W7Jd1t4biyiSwI/2RVS3OhRh2XRoUD24mvT5N8YNF5TmtJDEg6T
oj1RPfLER8MleHUj8qIB8NhBUwetT7BSb3GsxZBjbYX5RhBEorY2AsD3lpUAwXdH8cLLMqRHef0Y
esqwAensxcOVvkUJYFOw+ktnzPcMDjmR4SujCwqm+i0A18iDR8oZzS4iPiEHq/kF7NJoYlzLc3XU
vL1TBJgZJrZKNsdfvxUztbAk3M0Z43pmalbxerPPGlWzVqg0B3kkpR4H9eM671UNbdS7pSOdKvQ0
aAEa63+P1qwjAgMBAAGjITAfMB0GA1UdDgQWBBTj60GUpJy35/k/ezlKFEwHeDqH4jANBgkqhkiG
9w0BAQsFAAOCAQEAF/5Y8pldXPkyKGChcVc42lxRRlxN0ZfSrJAbChzeIQZN8ZL2Bnd7irfflEYy
ph3gdw6ae7WQlTOedTCklBButXyg6rKBb84GiG4pnu8SWhIQrKU0FSm5nSYWJ7J+DPFqf06MRVEO
G4gaNoeH25Kmgnx94JJyQ/4PZbR2FR96E+ep0UfDhuZaL8T9Mw4uc0qMUC/FT6HSEL4kxrJV5R86
0kXfB3DZyR50qQTShEzAmlUfnv/b2dOHgNVJlnkXf8sFFRvpXY3WjYkoTQy2u/1rt3e1b4jQwFWg
q/b/aTBoy1bBr2Sto1p8I1dFnykBy1ki3XcY2b9pueWFiaLCG0wT7Q==
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
....
</ds:Signature>
I'm newbie xades4j. Thank in advance.
It seems that you have a Reference
element with an empty URI. For this kind of URIs, the way to obtain the signed data object contents is "application specific". In xades4j you can specify it using SignatureSpecificVerificationOptions
EDIT: the "application specific" way is actually for references where the URI attribute is omitted and there can be at most one of those in a signature. Having an empty reference means that the reference covers the whole XML resource. Depending on how you're adding an additional signature, the actual input for the reference validation may change and it could fail.
Can you show how you're creating the XML document?