0 Replies Latest reply on Jul 2, 2013 10:21 PM by CInglez

    Problem signing xml after java update (7u25)

    CInglez

      Hi.

       

      I have a signing code that used to work until our last java update to 7u25. The code is:

       

      [code]

       

      package cte.xmlSigner;

       

       

      import java.io.FileInputStream;

      import java.io.StringReader;

      import java.io.StringWriter;

       

       

      import java.security.KeyStore;

      import java.security.Provider;

      import java.security.cert.X509Certificate;

       

       

      import java.util.ArrayList;

      import java.util.Collections;

      import java.util.Enumeration;

      import java.util.List;

       

       

      import javax.xml.crypto.dsig.CanonicalizationMethod;

      import javax.xml.crypto.dsig.DigestMethod;

      import javax.xml.crypto.dsig.Reference;

      import javax.xml.crypto.dsig.SignatureMethod;

      import javax.xml.crypto.dsig.SignedInfo;

      import javax.xml.crypto.dsig.Transform;

      import javax.xml.crypto.dsig.XMLSignature;

      import javax.xml.crypto.dsig.XMLSignatureFactory;

      import javax.xml.crypto.dsig.dom.DOMSignContext;

      import javax.xml.crypto.dsig.dom.DOMValidateContext;

      import javax.xml.crypto.dsig.keyinfo.KeyInfo;

      import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;

      import javax.xml.crypto.dsig.keyinfo.X509Data;

      import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;

      import javax.xml.crypto.dsig.spec.TransformParameterSpec;

      import javax.xml.parsers.DocumentBuilder;

      import javax.xml.parsers.DocumentBuilderFactory;

      import javax.xml.transform.Transformer;

      import javax.xml.transform.TransformerFactory;

      import javax.xml.transform.dom.DOMSource;

      import javax.xml.transform.stream.StreamResult;

       

       

      import org.w3c.dom.Document;

      import org.w3c.dom.Element;

      import org.w3c.dom.Node;

      import org.w3c.dom.NodeList;

       

       

      import org.xml.sax.InputSource;

       

       

       

       

      public class cteXmlSigner{

         

         

          private static final String C14N_TRANSFORM_METHOD = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";

         

          private static final String PROVIDER_CLASS_NAME = "org.jcp.xml.dsig.internal.dom.XMLDSigRI";

          private static final String PROVIDER_NAME = "jsr105Provider";

             

          public String cteAssinar(String xmlFile, String tipo, String certPath, String certPasswd) throws Exception

          {

          // tipo

          // 'CTE' - CTE 

          // 'CAN' - CANCELAMENTO

          // 'INU' - INUTILIZACAO

          //

       

       

            String tag = "";

         

            if(tipo.equals("CTE"))

              tag = "infCte";

            else if (tipo.equals("CAN"))

              tag = "infCanc";

            else if (tipo.equals("INU"))

              tag = "infInut";

           

            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

            factory.setNamespaceAware(false);

            DocumentBuilder builder = factory.newDocumentBuilder();

            Document docs = builder.parse(new InputSource(new StringReader(xmlFile)));

       

            NodeList elements = docs.getElementsByTagName(tag);

            Element el = (Element) elements.item(0);

       

            String id = el.getAttribute("Id");     

           

            String providerName = System.getProperty(PROVIDER_NAME, PROVIDER_CLASS_NAME);

            XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM", (Provider) Class.forName(providerName).newInstance());

         

            ArrayList transformList = new ArrayList();

            TransformParameterSpec tps = null;

            Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED,tps);

            Transform c14NTransform = fac.newTransform(C14N_TRANSFORM_METHOD, tps);

            transformList.add(envelopedTransform);

            transformList.add(c14NTransform);

         

            Reference ref = fac.newReference("#" + id, fac.newDigestMethod(DigestMethod.SHA1, null), transformList, null, null);

         

            SignedInfo si = fac

            .newSignedInfo(fac.newCanonicalizationMethod(

            CanonicalizationMethod.INCLUSIVE,

            (C14NMethodParameterSpec) null), fac

            .newSignatureMethod(SignatureMethod.RSA_SHA1, null),

            Collections.singletonList(ref));

         

            KeyStore ks = KeyStore.getInstance("PKCS12");

            ks.load(new FileInputStream(certPath), certPasswd.toCharArray());

            Enumeration aliasesEnum = ks.aliases();

            String alias = "";

            while (aliasesEnum.hasMoreElements()) {

              alias = (String) aliasesEnum.nextElement();

              if (ks.isKeyEntry(alias)) {

              break;

              }

            }

         

            KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(certPasswd.toCharArray()));

         

            X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

         

            KeyInfoFactory kif = fac.getKeyInfoFactory();

            List x509Content = new ArrayList();

         

            x509Content.add(cert);

            X509Data xd = kif.newX509Data(x509Content);

            KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

         

            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

            dbf.setNamespaceAware(true);

            Document doc = dbf.newDocumentBuilder().parse(new InputSource(new StringReader(xmlFile)))

       

            DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc.getDocumentElement());

       

            XMLSignature signature = fac.newXMLSignature(si, ki);

         

            signature.sign(dsc);

         

            StringWriter stringWriter = new StringWriter();

            Transformer transformer = TransformerFactory.newInstance().newTransformer();

            transformer.transform(new DOMSource(doc), new StreamResult(stringWriter));

            String signedXml = stringWriter.toString();

           

            NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");

         

            if (nl.getLength() == 0) {

            throw new Exception("Cannot find Signature element");

            }

            DOMValidateContext valContext = new DOMValidateContext( new X509KeySelector(ks), nl.item(0));

       

            XMLSignature signatures = fac.unmarshalXMLSignature(valContext);

       

            boolean coreValidity = signatures.validate(valContext);

       

            if (coreValidity == false) {

              return "Falha na Assinatura!";

            } else {

              return signedXml;

            }

          }

       

       

       

       

      }

       

      [/code]

       

      After the update, I receive the stack:

       

      javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: com.sun.org.apache.xml.internal.security.utils.resolver.ResourceResolverException: Cannot resolve element with ID 1

        at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(DOMReference.java:412)

        at org.jcp.xml.dsig.internal.dom.DOMReference.digest(DOMReference.java:338)

        at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(DOMXMLSignature.java:471)

        at org.jcp.xml.dsig.internal.dom.DOMXMLSign

       

      Downgrading the java version, it works again, but I think it is not a reasonable solution. What could be a workaround? Already tried

      [code]

              el.setIdAttribute("Id", true);

      [/code]

       

      but it did not help.

       

      Any ideas?

       

      Thanks in advance