Topic
13 replies Latest Post - ‏2013-03-08T10:43:00Z by JPdev
SystemAdmin
SystemAdmin
2262 Posts
ACCEPTED ANSWER

Pinned topic javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

‏2012-11-30T13:05:14Z |
Hi
I am trying to run a Java program (JRE ver: JRE 1.6.0 IBM J9 2.4) to sign XML documents on AIX box.
The program is failing with below error:

javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: Can't resolve ID: '123456' in ''
at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.calculateDigestValue(ReferenceImpl.java:327)
at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.sign(ReferenceImpl.java:237)
at com.ibm.xml.crypto.dsig.dom.XMLSignatureImpl.sign(XMLSignatureImpl.java:158)
at com.test.util.XMLSign.main(XMLSign.java:224)
Caused by: javax.xml.crypto.URIReferenceException: Can't resolve ID: 'XCUS201211230804231' in ''
at com.ibm.xml.crypto.dsig.dom.URIDereferencerImpl.dereference(URIDereferencerImpl.java:206)
at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.calculateDigestValue(ReferenceImpl.java:285)
... 3 more
javax.xml.crypto.URIReferenceException: Can't resolve ID: 'XCUS201211230804231' in ''
at com.ibm.xml.crypto.dsig.dom.URIDereferencerImpl.dereference(URIDereferencerImpl.java:206)
at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.calculateDigestValue(ReferenceImpl.java:285)
at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.sign(ReferenceImpl.java:237)
at com.ibm.xml.crypto.dsig.dom.XMLSignatureImpl.sign(XMLSignatureImpl.java:158)
at com.test.util.XMLSign.main(XMLSign.java:224)
javax.xml.crypto.URIReferenceException: Can't resolve ID: 'XCUS201211230804231' in ''
at com.ibm.xml.crypto.dsig.dom.URIDereferencerImpl.dereference(URIDereferencerImpl.java:206)
at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.calculateDigestValue(ReferenceImpl.java:285)
at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.sign(ReferenceImpl.java:237)
at com.ibm.xml.crypto.dsig.dom.XMLSignatureImpl.sign(XMLSignatureImpl.java:158)
at com.test.util.XMLSign.main(XMLSign.java:224)

When I run the same code on Solaris it is working fine.
The Key is different on both the boxes. WOuld it matter?

XML Sign jar used: ibmxmlcrypto.jar

Please let me know if anyone have faced this error..

My Program:

import javax.xml.crypto.*;
import javax.xml.crypto.dom.*;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.*;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.*;
import java.util.*;
import java.security.*;
import java.security.cert.*;
import java.io.*;
import javax.xml.parsers.*;
import org.w3c.dom.*;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
import javax.xml.transform.Transformer;

XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse
(new FileInputStream(input));
String uri="";
Node node =doc.getElementsByTagName("Request").item(0);
if (node instanceof Element && node.hasAttributes())
{
NamedNodeMap attrs = node.getAttributes();
for (int a = 0; a < attrs.getLength(); a++) {
Attr attribute = (Attr) attrs.item(a);
if (attribute.getName().toUpperCase().equals("ID"))
uri= "#"+attribute.getValue();
}
}
Reference ref = fac.newReference
(uri, fac.newDigestMethod(DigestMethod.SHA1, null),
Collections.singletonList
(fac.newTransform
(Transform.ENVELOPED, (TransformParameterSpec) null)),
null, null);

// Create the SignedInfo.
SignedInfo si = fac.newSignedInfo
(fac.newCanonicalizationMethod
(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null),
fac.newSignatureMethod(sigmeth, null),
Collections.singletonList(ref));

// Load the KeyStore and get the signing key and certificate.
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(keypath), keypass.toCharArray());
KeyStore.PrivateKeyEntry keyEntry =
(KeyStore.PrivateKeyEntry) ks.getEntry
(keyname, new KeyStore.PasswordProtection(keypass.toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
// Create a DOMSignContext and specify the RSA PrivateKey and
// location of the resulting XMLSignature's parent element.

DOMSignContext dsc = new DOMSignContext
(keyEntry.getPrivateKey(), doc.getDocumentElement());
// Create the XMLSignature
XMLSignature signature = fac.newXMLSignature(si, ki);

// Marshal, generate, and sign the enveloped signature.
//#####--> Error is happening here ####
signature.sign(dsc);

#############################################
Decompiled code from URIReferenceException:
#############################################
String uri;
String id;
Node node;
Document targetDoc;
TransformContext tcontext = (TransformContext)context.get(TransformContext.class);
String uriRef = reference.getURI();
if (uriRef == null) {
throw new URIReferenceException("Null URI is not supported by this implementation. Implement your own URIDereferencer.");
}

if (context instanceof DOMSignContext)
node = ((DOMSignContext)context).getParent();
if (node.getNodeType() != 9)
node = node.getOwnerDocument();
Document thisDoc = (Document)node;

int ind = uriRef.indexOf(35);
if (ind >= 0) {
uri = uriRef.substring(0, ind);
id = uriRef.substring(ind + 1);
if (id.length() == 0)
id = null;
}

Element targetNode = resolveId((DOMCryptoContext)context, thisDoc, targetDoc, id);
if (targetNode == null)
throw new URIReferenceException("Can't resolve ID: '" + id + "' in '" + uri + "'");

if (tcontext != null)
tcontext.mightFixTree(targetNode);
return TransformUtil.toNodeSet(targetNode, false);
}

public static Element resolveId(DOMCryptoContext idMap, Document thisDoc, Document doc, String id)
{
if ((doc == thisDoc) && (idMap != null)) {
el = idMap.getElementById(id);
if (el != null)
return el;
}
Thanks in Advance.....

Thanks and Regards
Sameer
Updated on 2013-03-08T10:43:00Z at 2013-03-08T10:43:00Z by JPdev
  • SystemAdmin
    SystemAdmin
    2262 Posts
    ACCEPTED ANSWER

    Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

    ‏2012-11-30T14:40:47Z  in response to SystemAdmin
    Hi
    I am trying to run a Java program (JRE ver: JRE 1.6.0 IBM J9 2.4) to sign XML documents on AIX box.
    The program is failing with below error:

    javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: Can't resolve ID: 'XCUS201211230804231' in ''
    at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.calculateDigestValue(ReferenceImpl.java:327)
    at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.sign(ReferenceImpl.java:237)
    at com.ibm.xml.crypto.dsig.dom.XMLSignatureImpl.sign(XMLSignatureImpl.java:158)
    at com.test.util.XMLSign.main(XMLSign.java:224)
    Caused by: javax.xml.crypto.URIReferenceException: Can't resolve ID: 'XCUS201211230804231' in ''
    at com.ibm.xml.crypto.dsig.dom.URIDereferencerImpl.dereference(URIDereferencerImpl.java:206)
    at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.calculateDigestValue(ReferenceImpl.java:285)
    ... 3 more
    javax.xml.crypto.URIReferenceException: Can't resolve ID: 'XCUS201211230804231' in ''
    at com.ibm.xml.crypto.dsig.dom.URIDereferencerImpl.dereference(URIDereferencerImpl.java:206)
    at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.calculateDigestValue(ReferenceImpl.java:285)
    at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.sign(ReferenceImpl.java:237)
    at com.ibm.xml.crypto.dsig.dom.XMLSignatureImpl.sign(XMLSignatureImpl.java:158)
    at com.test.util.XMLSign.main(XMLSign.java:224)
    javax.xml.crypto.URIReferenceException: Can't resolve ID: 'XCUS201211230804231' in ''
    at com.ibm.xml.crypto.dsig.dom.URIDereferencerImpl.dereference(URIDereferencerImpl.java:206)
    at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.calculateDigestValue(ReferenceImpl.java:285)
    at com.ibm.xml.crypto.dsig.dom.ReferenceImpl.sign(ReferenceImpl.java:237)
    at com.ibm.xml.crypto.dsig.dom.XMLSignatureImpl.sign(XMLSignatureImpl.java:158)
    at com.test.util.XMLSign.main(XMLSign.java:224)

    When I run the same code on Solaris it is working fine.
    The Key is SAME on both Solaris and AIX.

    XML Sign jar used: ibmxmlcrypto.jar

    Please let me know if anyone have faced this error..

    My Program:

    import javax.xml.crypto.*;
    import javax.xml.crypto.dom.*;
    import javax.xml.crypto.dsig.*;
    import javax.xml.crypto.dsig.dom.*;
    import javax.xml.crypto.dsig.keyinfo.*;
    import javax.xml.crypto.dsig.spec.*;
    import java.util.*;
    import java.security.*;
    import java.security.cert.*;
    import java.io.*;
    import javax.xml.parsers.*;
    import org.w3c.dom.*;
    import javax.xml.transform.TransformerFactory;
    import javax.xml.transform.dom.*;
    import javax.xml.transform.stream.*;
    import javax.xml.transform.Transformer;

    XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    dbf.setNamespaceAware(true);
    Document doc = dbf.newDocumentBuilder().parse
    (new FileInputStream(input));
    String uri="";
    Node node =doc.getElementsByTagName("Request").item(0);
    if (node instanceof Element && node.hasAttributes())
    {
    NamedNodeMap attrs = node.getAttributes();
    for (int a = 0; a < attrs.getLength(); a++) {
    Attr attribute = (Attr) attrs.item(a);
    if (attribute.getName().toUpperCase().equals("ID"))
    uri= "#"+attribute.getValue();
    }
    }
    Reference ref = fac.newReference
    (uri, fac.newDigestMethod(DigestMethod.SHA1, null),
    Collections.singletonList
    (fac.newTransform
    (Transform.ENVELOPED, (TransformParameterSpec) null)),
    null, null);

    // Create the SignedInfo.
    SignedInfo si = fac.newSignedInfo
    (fac.newCanonicalizationMethod
    (CanonicalizationMethod.INCLUSIVE,
    (C14NMethodParameterSpec) null),
    fac.newSignatureMethod(sigmeth, null),
    Collections.singletonList(ref));

    // Load the KeyStore and get the signing key and certificate.
    KeyStore ks = KeyStore.getInstance("JKS");
    ks.load(new FileInputStream(keypath), keypass.toCharArray());
    KeyStore.PrivateKeyEntry keyEntry =
    (KeyStore.PrivateKeyEntry) ks.getEntry
    (keyname, new KeyStore.PasswordProtection(keypass.toCharArray()));
    X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

    // Create the KeyInfo containing the X509Data.
    KeyInfoFactory kif = fac.getKeyInfoFactory();
    List x509Content = new ArrayList();
    x509Content.add(cert.getSubjectX500Principal().getName());
    x509Content.add(cert);
    X509Data xd = kif.newX509Data(x509Content);
    KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
    // Create a DOMSignContext and specify the RSA PrivateKey and
    // location of the resulting XMLSignature's parent element.

    DOMSignContext dsc = new DOMSignContext
    (keyEntry.getPrivateKey(), doc.getDocumentElement());
    // Create the XMLSignature
    XMLSignature signature = fac.newXMLSignature(si, ki);

    // Marshal, generate, and sign the enveloped signature.
    //#####--> Error is happening here ####
    signature.sign(dsc);
    #############################################
    Decompiled code from URIReferenceException:
    #############################################
    String uri;
    String id;
    Node node;
    Document targetDoc;
    TransformContext tcontext = (TransformContext)context.get(TransformContext.class);
    String uriRef = reference.getURI();
    if (uriRef == null) {
    throw new URIReferenceException("Null URI is not supported by this implementation. Implement your own URIDereferencer.");
    }

    if (context instanceof DOMSignContext)
    node = ((DOMSignContext)context).getParent();
    if (node.getNodeType() != 9)
    node = node.getOwnerDocument();
    Document thisDoc = (Document)node;

    int ind = uriRef.indexOf(35);
    if (ind >= 0) {
    uri = uriRef.substring(0, ind);
    id = uriRef.substring(ind + 1);
    if (id.length() == 0)
    id = null;
    }

    Element targetNode = resolveId((DOMCryptoContext)context, thisDoc, targetDoc, id);
    if (targetNode == null)
    throw new URIReferenceException("Can't resolve ID: '" + id + "' in '" + uri + "'");

    if (tcontext != null)
    tcontext.mightFixTree(targetNode);
    return TransformUtil.toNodeSet(targetNode, false);
    }

    public static Element resolveId(DOMCryptoContext idMap, Document thisDoc, Document doc, String id)
    {
    if ((doc == thisDoc) && (idMap != null)) {
    el = idMap.getElementById(id);
    if (el != null)
    return el;
    }
    Thanks in Advance.....

    Thanks and Regards
    Sameer
  • JPdev
    JPdev
    18 Posts
    ACCEPTED ANSWER

    Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

    ‏2012-11-30T15:24:24Z  in response to SystemAdmin
    Hello,
    Why to use javax.xml.crypto.* ???

    I think it's better to use java.security.* as you can sign any type of documents even Jar, Zip ...
    I have this kind of app. and perhaps this work on JDK IBM to do that you want:
    1) Generate a Key pair (DSA or RSA) with a SecureRandom
    2) Create a Signature Object & initialize it with your private key
    3) Update and Sign data from the file you want to sign
    4) Generate the signature for all the data(s) that was read and save it to a file
    5) Save the Public Key.getEncoded() (step 1) to a file
    That all you need (import also java.io.*) and it's not necessary to generate a KeyStore.

    Of course you need also an application that is able to check if the data has not been corrupted or modified during a transfer, to do that you read the file signature then the keyfile against the data file.

    Regards
    JPdev
    • SystemAdmin
      SystemAdmin
      2262 Posts
      ACCEPTED ANSWER

      Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

      ‏2012-11-30T15:48:10Z  in response to JPdev
      Thanks JPDev

      Is there any issue with using javax.xml.crypto.*
      Right now if I adopt this approach, I ll have to get the security key generation modified. And unfortunately don't have enough time as this would mean I have to change in prod env too where I have to promote this code.
      Please let me know if you can suspect anything with the above code.

      Thanks
      Sameer
      • JPdev
        JPdev
        18 Posts
        ACCEPTED ANSWER

        Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

        ‏2012-11-30T17:01:43Z  in response to SystemAdmin
        Well,
        I don't think there is a problem with your code as it is running on Solaris, but
        the java SE Oracle/sun API is handling xml.crypto.* not the same way as java SE IBM and this occurs in many cases.
        The rule is don't assume an app java Sun is directly running on java IBM for this very special cases as Keystore and crypto.

        JPdev
        • SystemAdmin
          SystemAdmin
          2262 Posts
          ACCEPTED ANSWER

          Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

          ‏2012-11-30T17:23:34Z  in response to JPdev
          Hi JPDev

          Thanks again..
          I will try to do using java.security.
          The keys are in KeyStore...saved as mykeystore.jks (retrieved by keyname/keypass)
          I guess using SecureRandom, is just change in API
          If you can provide some sample code, it will be really helpful.

          Thanks
          Sameer
      • JPdev
        JPdev
        18 Posts
        ACCEPTED ANSWER

        Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

        ‏2012-11-30T17:39:44Z  in response to SystemAdmin
        Hello,
        You can also use your keystore in step one, in this case you don't need to save the public key.
        Exceptionally i give you my code

        import java.io.*;
        import java.security.*;

        public class DataSigner {

        /**
        * @param args the command line arguments
        * (1) FileName to be signed.
        * (2) Signature output file.
        * (3) Public Key output file.
        */
        public static void main(String[] args) {
        /* generate a DSA signature */
        if (args.length != 3) {
        Usage();
        System.exit(1);
        }

        // do all the job
        try {
        // Generate a Key pair
        KeyPairGenerator keyGen =
        KeyPairGenerator.getInstance("DSA");
        SecureRandom random =
        SecureRandom.getInstance("SHA1PRNG");
        keyGen.initialize(1024, random);

        KeyPair pair = keyGen.generateKeyPair();
        PrivateKey priv = pair.getPrivate();
        PublicKey pub = pair.getPublic();

        // create A Signature Object & initialize it with our private key
        Signature dsa = Signature.getInstance("SHA1withDSA");
        dsa.initSign(priv);

        // update and Sign data(s)
        FileInputStream fis = new FileInputStream(args[0]);
        try (BufferedInputStream bufin = new BufferedInputStream(fis)) {
        byte[] buffer = new byte1024;
        int len;
        while (bufin.available() != 0) {
        len = bufin.read(buffer);
        dsa.update(buffer, 0, len);
        }
        }
        // generate the signature for all the data(s) that was read.
        byte[] theSign = dsa.sign();
        try (FileOutputStream sigfos = new FileOutputStream(args[1])) {
        sigfos.write(theSign);
        sigfos.flush();
        }

        // save the Public Key to the file.
        byte[] theKey = pub.getEncoded();
        try (FileOutputStream keyfos = new FileOutputStream(args[2])) {
        keyfos.write(theKey);
        keyfos.flush();
        }
        } catch (NoSuchAlgorithmException | InvalidKeyException | IOException | SignatureException ex) {
        System.out.println(ex.getMessage());
        ex.printStackTrace();
        }
        }

        private static void Usage() {
        System.out.println("Usage: DataSigner FileNameToSign" +
        " SignatureOutputFileName" +
        " PublicKeyOutputFileName");
        }
        }
        WARNING you must change the code for the two inner try and the final catch, this is a very
        special syntax used with Oracle/sun java SE 7 !!

        Hope this solve your problem.
        JPdev
        • SystemAdmin
          SystemAdmin
          2262 Posts
          ACCEPTED ANSWER

          Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

          ‏2012-12-03T08:16:45Z  in response to JPdev
          Thanks JPDev

          Thanks a lot for sharing a sample.
          I am testing this...will let you know if there are any issues.

          Thanks
          Sameer
          • JPdev
            JPdev
            18 Posts
            ACCEPTED ANSWER

            Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

            ‏2012-12-03T10:46:09Z  in response to SystemAdmin
            HI
            Let me know if this code is running on JAVA IBM.
            Signaling an error in the statement => byte[] buffer = new byte1024; of course you must read
            byte[] buffer = new byte1024 (a copy/paste error ?)

            JPdev
            • SystemAdmin
              SystemAdmin
              2262 Posts
              ACCEPTED ANSWER

              Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

              ‏2012-12-03T17:50:30Z  in response to JPdev
              Hi JPDev

              Came to know that the issue on AIX with javax.xml.crypto is that the signing fails when a uri is provided. If we sign the whole document it is not an issue.

              In std API, have you tried to pass uri reference of xml / other documents ?? And then sign only one element of a tag..rather than full document.

              Thanks
              Sameer Nag
              • JPdev
                JPdev
                18 Posts
                ACCEPTED ANSWER

                Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

                ‏2012-12-04T09:14:20Z  in response to SystemAdmin
                Hello,
                If i understand you want to sign only a PART of your document.
                I never try this, but i think you must parse only our PART, then store it in a buffer
                and sign it as a whole document.
                This must work.

                JPdev
  • SystemAdmin
    SystemAdmin
    2262 Posts
    ACCEPTED ANSWER

    Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

    ‏2012-12-06T08:15:17Z  in response to SystemAdmin
    Hi JPDev

    I got the solution finally..after researching net on various forums/sites..I could get the solution from this comment posted by someone:

    "Thanks, thats what I figured as the "ID" attribute in the Assertion need not be interpreted as an xml id by Santuario, even though thats how it was working.

    Its just that the sudden change in the behavior was confusing (depending on the XMLSignatureFactory instance that gets picked up from the classpath you can get different behavior (i.e. between what is included in Java 6 internally and xmlsec 1.5.x).

    For e.g. I ran into this when I upgraded my wss4j lib from 1.6.3 to 1.6.5 (which seemed to upgrade the xmlsec lib from 1.4.5 to 1.5.1) and suddenly working code broke).

    Anyway, for others who encounter this, I resolved this by explicitly setting the "ID" attribute as an element id attribute like this:

    Element rootEl = doc.getDocumentElement();
    rootEl.setIdAttribute("ID", true);
    "

    So, I added following line in the code and it worked:

    Element e1 =(Element)doc.getElementsByTagName("<elementNamethatHasID>").item(0);
    e1.setIdAttribute("ID", true);

    Again, thanks very much for your help.

    hope this post will help others.

    Thanks
    Sameer
  • SystemAdmin
    SystemAdmin
    2262 Posts
    ACCEPTED ANSWER

    Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

    ‏2013-03-07T11:36:30Z  in response to SystemAdmin
    Please let me know if you can suspect anything with the above code.

    _________________
    http://www.mmoggg.de/
    http://www.mmoggg.de/Diablo-3-gold/
    http://www.saferunescapegold.com/
    http://www.mmoggg.de/Guild-Wars-2/
    • JPdev
      JPdev
      18 Posts
      ACCEPTED ANSWER

      Re: javax.xml.crypto.URIReferenceException: Can't resolve ID. AIX box issue !!!

      ‏2013-03-08T10:43:00Z  in response to SystemAdmin
      Hi,
      what that ?? all your URL ref. are BLACKLISTED with MALWARE!!
      MyWOT and TrendMicro.
      For any DON'T go to these websites.