WebService of the City of Salvador, error: 1057 Rejection: Signature differs from calculated

1

Talk to people.

I'm trying to send an NFTS to Salvador's City Hall via WebService in Java. (I'm using their Test endpoint before submitting)

I researched a lot, I saw some here in the forum, but I could not solve it.

Does anyone have any idea how to solve this problem? Or what I'm doing wrong.

Is this error message about the whole XML signature or NFTS tag only?

Follow my code:

PedidoEnvioLoteNFTS pedidoLote = repository.getLoteNfts();

String mensagem = Conversor.marshal(pedidoLote);

String xmlAssinado = new CriadorAssinaturaDigital().assinarNotaFiscalPrefeituraSalvador(mensagem);

xmlAssinado = xmlAssinado.replaceAll("\r\n", "");  

xmlAssinado = xmlAssinado.replaceAll("\<\?xml(.+?)\?\>", "").trim();

TesteEnvioLoteNFTSRequest request = new TesteEnvioLoteNFTSRequest();

request.setMensagemXML(xmlAssinado);

TesteEnvioLoteNFTSResponse response = getPort().testeEnvioLoteNFTS(request);

public class Conversor {

    public static String marshal(PedidoEnvioLoteNFTS pedidoLote) throws JAXBException {

            StringWriter stringWriter = new StringWriter();

            JAXBContext jaxbContext = JAXBContext.newInstance(PedidoEnvioLoteNFTS.class);

            Marshaller jaxbMarshaller = jaxbContext.createMarshaller();

            jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

            QName qName = new QName("PedidoEnvioLoteNFTS");
            JAXBElement<PedidoEnvioLoteNFTS> root = new JAXBElement<PedidoEnvioLoteNFTS>(qName, PedidoEnvioLoteNFTS.class, pedidoLote);

            jaxbMarshaller.marshal(root, stringWriter);

            String result = stringWriter.toString();

            return result;
    }

}

public class CriadorAssinaturaDigital {

   public String assinarNotaFiscalPrefeituraSalvador(String xml) throws Exception {

        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();

        Document doc = factory.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes()));

        doc.getDocumentElement().removeAttribute("xmlns:ns2");

        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

        ArrayList transformList = new ArrayList();
        TransformParameterSpec tps = null;
        Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED, tps);
        Transform c14NTransform = fac.newTransform("http://www.w3.org/TR/2001/REC-xml-c14n-20010315", tps);
        transformList.add(envelopedTransform);
        transformList.add(c14NTransform);

        String separador = File.separator;

        String caminhoCertificado = CAMINHO_CERTIFICADO; 

        String senhaCertificado = SENHA;

        KeyStore ks = KeyStore.getInstance("PKCS12");            
        ks.load(new FileInputStream(caminhoCertificado), senhaCertificado.toCharArray());

        KeyStore.PrivateKeyEntry pkEntry = null;
        Enumeration aliasesEnum = ks.aliases();
        PrivateKey privateKey = null;
        while (aliasesEnum.hasMoreElements()) {
            String alias = (String) aliasesEnum.nextElement();
            System.out.println(alias);
            if (ks.isKeyEntry(alias)) {
                pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(senhaCertificado.toCharArray()));
                privateKey = pkEntry.getPrivateKey();
                break;
            }
        }

        X509Certificate cert = (X509Certificate) pkEntry.getCertificate();
        KeyInfoFactory kif = fac.getKeyInfoFactory();
        List x509Content = new ArrayList();
        x509Content.add(cert);
        X509Data xd = kif.newX509Data(x509Content);
        KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

        for (int i = 0; i < doc.getDocumentElement().getElementsByTagName("NFTS").getLength(); i++) {
            assinarNFTS(fac, transformList, privateKey, ki, doc, i);
        }

        Reference ref = fac.newReference("", 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));
        XMLSignature signature = fac.newXMLSignature(si, ki);

        DOMSignContext dsc = new DOMSignContext(privateKey, doc.getDocumentElement());
        signature.sign(dsc);

        doc.getDocumentElement().setAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
        doc.getDocumentElement().setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");

        ByteArrayOutputStream os = new ByteArrayOutputStream();
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer trans = tf.newTransformer();
        trans.transform(new DOMSource(doc), new StreamResult(os));

        return os.toString();
    }

    private void assinarNFTS(XMLSignatureFactory fac, ArrayList transformList, PrivateKey privateKey, KeyInfo ki, Document doc, int i) throws Exception {

            Element assinatura = (Element) doc.createElement("Assinatura");

            assinatura.setTextContent(signASCII(doc.getDocumentElement().getElementsByTagName("NFTS").item(i).getTextContent().getBytes()));

            ((Element) doc.getDocumentElement().getElementsByTagName("NFTS").item(i)).appendChild(assinatura);
    }

}

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "mensagemXML"
})
@XmlRootElement(name = "TesteEnvioLoteNFTSRequest")
public class TesteEnvioLoteNFTSRequest {

    @XmlElement(name = "MensagemXML")
    protected String mensagemXML;

    /**
     * Gets the value of the mensagemXML property.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getMensagemXML() {
        return mensagemXML;
    }

    /**
     * Sets the value of the mensagemXML property.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setMensagemXML(String value) {
        this.mensagemXML = value;
    }

}
    
asked by anonymous 11.06.2018 / 04:38

0 answers