Question

I am trying to sign an XML document with a private key and a certificate which are retrieved from the database correctly. This private key and certificate where given to me so I am not quite sure about the provider equivalence in Java. For signing the XML document I used this tutorial

The code I implemented for doing this is the following:

        PrivateKey pk = null;
        javax.security.cert.X509Certificate cert = null;
        try{
            ByteArrayInputStream bis = new ByteArrayInputStream(keyCer.getLlave());
            ObjectInput in = new ObjectInputStream(bis);
            pk = (PrivateKey) in.readObject(); 
            bis.close();

            bis = new ByteArrayInputStream(keyCer.getCertificado());
            in = new ObjectInputStream(bis);
            cert = (javax.security.cert.X509Certificate) in.readObject(); 
            bis.close();

            keyCer.setCertB64(Base64.encodeBase64String(cert.getEncoded()));

            DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
            dbfac.setNamespaceAware(true);
            DocumentBuilder docBuilder;
            docBuilder = dbfac.newDocumentBuilder();
            DOMImplementation domImpl = docBuilder.getDOMImplementation();
            Document doc = domImpl.createDocument("http://cancelacfd.sat.gob.mx", "Cancelacion", null);
            doc.setXmlVersion("1.0");
            doc.setXmlStandalone(true);

            Element cancelacion = doc.getDocumentElement();
            cancelacion.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xsd","http://www.w3.org/2001/XMLSchema");
            cancelacion.setAttributeNS("http://www.w3.org/2000/xmlns/","xmlns:xsi","http://www.w3.org/2001/XMLSchema-instance");
            cancelacion.setAttribute("RfcEmisor", rfc);
            cancelacion.setAttribute("Fecha", fecha);

            Element folios = doc.createElement("Folios");
            cancelacion.appendChild(folios);
            for (int i=0; i<uuid.length; i++) {
                Element u = doc.createElement("UUID");
                u.setTextContent(uuid[i]);
                folios.appendChild(u);
            }

            DOMSignContext dsc = new DOMSignContext (pk, doc.getDocumentElement()); 
            XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

            Reference ref = fac.newReference ("", fac.newDigestMethod(DigestMethod.SHA1, null), 
                        Collections.singletonList
                        (fac.newTransform(Transform.ENVELOPED,
                        (TransformParameterSpec) null)), null, null);

            SignedInfo si = fac.newSignedInfo
                      (fac.newCanonicalizationMethod
                        (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
                          (C14NMethodParameterSpec) null),
                        fac.newSignatureMethod(SignatureMethod.DSA_SHA1, null),
                        Collections.singletonList(ref)); 

            KeyInfoFactory kif = fac.getKeyInfoFactory();
            KeyValue kv = kif.newKeyValue(cert.getPublicKey());
            KeyInfo ki = kif.newKeyInfo(Collections.singletonList(kv)); 

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

            signature.sign(dsc);

            TransformerFactory transfac = TransformerFactory.newInstance();
            Transformer trans = transfac.newTransformer();
            trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
            trans.setOutputProperty(OutputKeys.VERSION, "1.0");
            trans.setOutputProperty(OutputKeys.INDENT, "yes");

            //CREAR STRING DEL ARBOL XML
            StringWriter sw = new StringWriter();
            StreamResult result = new StreamResult(sw);
            DOMSource source = new DOMSource(doc);
            trans.transform(source, result);
            String xmlString = sw.toString();
            System.out.println(xmlString);

           } catch (Exception e) {
               e.printStackTrace();
           }

When running the program I get the following exception:

javax.xml.crypto.dsig.XMLSignatureException: java.security.InvalidKeyException: No installed provider supports this key: sun.security.rsa.RSAPrivateCrtKeyImpl
     [java]     at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(Unknown Source)
     [java]     at prueba.cancelaciones.CancelaFE.doPost(CancelaFE.java:140)
     [java]     at prueba.cancelaciones.CancelaFE.doGet(CancelaFE.java:66)
     [java]     at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
     [java]     at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
     [java]     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
     [java]     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
     [java]     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
     [java]     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
     [java]     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
     [java]     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
     [java]     at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:541)
     [java]     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
     [java]     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:383)
     [java]     at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
     [java]     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:188)
     [java]     at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:166)
     [java]     at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:288)
     [java]     at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
     [java]     at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
     [java]     at java.lang.Thread.run(Unknown Source)
     [java] Caused by: java.security.InvalidKeyException: No installed provider supports this key: sun.security.rsa.RSAPrivateCrtKeyImpl
     [java]     at java.security.Signature$Delegate.chooseProvider(Unknown Source)
     [java]     at java.security.Signature$Delegate.engineInitSign(Unknown Source)
     [java]     at java.security.Signature.initSign(Unknown Source)
     [java]     at org.jcp.xml.dsig.internal.dom.DOMSignatureMethod.sign(Unknown Source)
     [java]     ... 21 more

Any suggestions?

Was it helpful?

Solution

The problem was mine, I was specifying wrongly the Signature Method. It should be:

SignedInfo si = fac.newSignedInfo
                      (fac.newCanonicalizationMethod
                        (CanonicalizationMethod.INCLUSIVE_WITH_COMMENTS,
                          (C14NMethodParameterSpec) null),
                        fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
                        Collections.singletonList(ref)); 

OTHER TIPS

Maybe you need to install a JCE/JCA provider like that which can be found at BouncyCastle. Just a guess though.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top