XML signature cannot resolve element with ID XXXX solution

Source: Internet
Author: User



Recently with the bank to do the interface, the XML file needs to do a sign-and-check operation, the local development environment is the version of Mac 10.10,JDK is 1.6.0.65. A little sign code, has been error, but a long time can not find a solution, the online information is very small, the error record as follows:


 
 
 1 javax.xml.crypto.URIReferenceException: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID FIQReq
 2 Exception in thread "main" java.lang.RuntimeException: javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID FIQReq
 3 at util.xml.XMLSigner.sign(XMLSigner.java:111)
 4 at test.TestSign.main(TestSign.java:34)
 5 Caused by: javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID FIQReq
 6 at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(DOMReference.java:412)
 7 at org.jcp.xml.dsig.internal.dom.DOMReference.digest(DOMReference.java:338)
 8 at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(DOMXMLSignature.java:471)
 9 at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:367)
10 at util.xml.XMLSigner.sign(XMLSigner.java:108)
11 ... 1 more
12 Caused by: javax.xml.crypto.URIReferenceException: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID FIQReq
13 at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(DOMURIDereferencer.java:124)
14 at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(DOMReference.java:404)
15 ... 5 more
16 Caused by: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID FIQReq
17 at com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment.engineResolve(ResolverFragment.java:90)
18 at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.resolve(ResourceResolver.java:283)
19 at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(DOMURIDereferencer.java:117)
20 ... 6 more

The only thing that's more right is this bug record: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8017171



The problem is caused by the id attribute of the XML document node can not be located to the corresponding node, so when the signature will be prompted to not resolve the ID, then how can I let him according to the ID of my node, parse and locate the corresponding node, let us first look at the code in my project:



The first is the XML file to be signed:


 
 1 javax.xml.crypto.URIReferenceException: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID FIQReq
 2 Exception in thread "main" java.lang.RuntimeException: javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID FIQReq
 3 at util.xml.XMLSigner.sign(XMLSigner.java:111)
 4 at test.TestSign.main(TestSign.java:34)
 5 Caused by: javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID FIQReq
 6 at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(DOMReference.java:412)
 7 at org.jcp.xml.dsig.internal.dom.DOMReference.digest(DOMReference.java:338)
 8 at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(DOMXMLSignature.java:471)
 9 at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:367)
10 at util.xml.XMLSigner.sign(XMLSigner.java:108)
11 ... 1 more
12 Caused by: javax.xml.crypto.URIReferenceException: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID FIQReq
13 at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(DOMURIDereferencer.java:124)
14 at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(DOMReference.java:404)
15 ... 5 more
16 Caused by: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID FIQReq
17 at com.sun.org.apache.xml.internal.security.utils.resolver.implementations.ResolverFragment.engineResolve(ResolverFragment.java:90)
18 at com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolver.resolve(ResourceResolver.java:283)
19 at org.jcp.xml.dsig.internal.dom.DOMURIDereferencer.dereference(DOMURIDereferencer.java:117)
20 ... 6 more


Code to add:


 
1 public void sign(Document doc, PrivateKey privateKey, String referenceId, Node signNode) {
 2 if(!isInit){
 3 throw new RuntimeException("XMLSigner is not init !");
 4 }
 5 try{
 6 //Create a <Reference> element that references the node with the specified ID, the <Signature> element will not be counted
 7 Reference refToRootDoc = signFactory.newReference("#"+referenceId,
 8 sha1DigMethod, Collections.singletonList(envelopedTransform), null, null);
 9 //Create a <SignedInfo> element
10 SignedInfo signedInfo = signFactory.newSignedInfo(c14nWithCommentMethod,
11 rsa_sha1SigMethod, Collections.singletonList(refToRootDoc));
12 //Create a signature instance
13 XMLSignature signature = signFactory.newXMLSignature(signedInfo, null);
14 //Create a signature context, generate on the specified node
15 DOMSignContext dsc = new DOMSignContext(privateKey, signNode);
16 / / set the signature domain namespace prefix
17 if (defaultNamespacePrefix != null) {
18 dsc.setDefaultNamespacePrefix(defaultNamespacePrefix);21 }
22 //Signature
23 signature.sign(dsc);
24 }catch(Exception e){
25 System.out.println(e.getMessage());
26 throw new RuntimeException(e);
27 }
28 }


Method outside the XML document tree, the private key that needs to do the add-on processing, the ID of the node that needs to be signed, here is the ID content of the fiqreq node in the XML above (fiqreq), and a node is the signature generated by the the parent element of SignedInfo, which is to write the signedinfo node under that node.



Executing this code will then report the error code as shown above.



In the http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8017171 described above, there are three suggestions for resolution:




There are 3 potential workarounds that you can apply:

1. Use a validating schema which will register the elements with ID references.

2. Register the ID elements with the DOMValidateContext.setIdAttributeNS method before validating the signature

3. Implement a custom URIDereferencer which can find these references and override the builtin URIDereferencer with the DOMValidateContext.setURIDereferencer method.


But it does not seem particularly intuitive to solve the problem at once. But the direction of the problem was given, and the point I took to solve the problem was the second one:



2. Register the ID elements with the Domvalidatecontext.setidattributens method before validating the signature


The tag code described above, although there is no Domvalidatecontext object participation, but there is domsigncontext, he also has setidattributens method, so we are to make a fuss in this way:



Add the following two code on the add-on code above to resolve the problem:



element element = (Element) Doc.getelementsbytagname (Referenceid). Item (0null, "id");


The whole code after adding these two lines of code becomes:


 
/**
     * XML signature
     * <p>Signatures are embedded in the specified node using inline mode</p>
     * @param doc XML document
     * @param privateKey private key
     * @param referenceId The element identifier to be signed
     * @param signNode generates the signed node
     */
    Public void sign(Document doc, PrivateKey privateKey, String referenceId, Node signNode) {
        If(!isInit){
            Throw new RuntimeException("XMLSigner is not init !");
        }
        Try{
            //Create a <Reference> element that references the node with the specified ID, the <Signature> element will not be counted
            Reference refToRootDoc = signFactory.newReference("#"+referenceId,
                    sha1DigMethod, Collections.singletonList(envelopedTransform), null, null);
            //Create a <SignedInfo> element
            SignedInfo signedInfo = signFactory.newSignedInfo(c14nWithCommentMethod,
                    rsa_sha1SigMethod, Collections.singletonList(refToRootDoc));
            / / Create a signature instance
            XMLSignature signature = signFactory.newXMLSignature(signedInfo, null);
            / / Create a signature context, generated on the specified node
            DOMSignContext dsc = new DOMSignContext(privateKey, signNode);
            / / Set the signature domain namespace prefix
            If (defaultNamespacePrefix != null) {
                dsc.setDefaultNamespacePrefix(defaultNamespacePrefix);
                Element element = (Element)doc.getElementsByTagName(referenceId).item(0);
                dsc.setIdAttributeNS(element, null, "id");
            }
            //signature
            Signature.sign(dsc);
        }catch(Exception e){
            System.out.println(e.getMessage());
            Throw new RuntimeException(e);
        }
    }


After you run the program again, the problem is resolved.






Specific instructions for adding and signing instructions, see the following documents:



Http://www.apihome.cn/api/java/XMLSignatureFactory.html (English)



Http://docs.oracle.com/javase/6/docs/technotes/guides/security/xmldsig/XMLDigitalSignature.html (English, but the introduction of more detailed, directly copied out can be)






XML signature cannot resolve element with ID XXXX solution


Alibaba Cloud Hot Products

Elastic Compute Service (ECS) Dedicated Host (DDH) ApsaraDB RDS for MySQL (RDS) ApsaraDB for PolarDB(PolarDB) AnalyticDB for PostgreSQL (ADB for PG)
AnalyticDB for MySQL(ADB for MySQL) Data Transmission Service (DTS) Server Load Balancer (SLB) Global Accelerator (GA) Cloud Enterprise Network (CEN)
Object Storage Service (OSS) Content Delivery Network (CDN) Short Message Service (SMS) Container Service for Kubernetes (ACK) Data Lake Analytics (DLA)

ApsaraDB for Redis (Redis)

ApsaraDB for MongoDB (MongoDB) NAT Gateway VPN Gateway Cloud Firewall
Anti-DDoS Web Application Firewall (WAF) Log Service DataWorks MaxCompute
Elastic MapReduce (EMR) Elasticsearch

Alibaba Cloud Free Trail

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.