1
Fala galera.
I am trying to send an NFTS to Salvador City Hall via Webservice in Java. (I am using their Test endpoint before sending)
I sign the NFTS tag and store the byte array in the tag, then sign the whole XML, but am getting the following error: 1057 Rejection: Signature differs from calculated
I’ve done a lot of research, I’ve seen a few here on the forum, but I couldn’t get it right.
Does anyone have any idea how to solve this problem? Or what I’m doing wrong.
This error message is about signing all XML or just the NFTS tag?
Follows 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;
}
}