Login Registre-se
Assinar ConsultarNfseRpsEnvio ( NFS-e ) sem a Tag "Id" [ Resolvido ]  XML
Índice dos Fóruns » NF-e / NFS-e / CT-e / CF-e / Certificados Digitais
Autor Mensagem
Rafael_oliveira

JavaC Membro

Membro desde: 07/04/2016 17:11:53
Mensagens: 7
Offline

Bom dia a todos.

Preciso assinar o xml : ConsultarNfseRpsEnvio , mas o mesmo não tem a tag "Id" , o código que utilizo é este :

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.OutputStream;
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.swing.JOptionPane;
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.jcp.xml.dsig.internal.dom.XMLDSigRI;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class Assinar {

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";
private static File arquivo;
private static String prefixoDoId;
public void assinar(String caminhoXml, String caminhoCertificado, String senha, String caminhoXmlNovo) throws Exception {
/*
* Operação
* '1' - EnviarLoteRpsEnvio
* '2' - CANCELAMENTO
*/
BufferedReader in = new BufferedReader(new FileReader("J:/RP-GRF/NFSE-JR/ESTAB-100/PARAMETRO/Operacao.txt"));
String tipo = in.readLine();

String tag = "";
if (tipo.equals("1")) {
tag = "LoteRps";
} else if (tipo.equals("2")) {
tag = "InfPedidoCancelamento";
} else if (tipo.equals("3")) {
tag = "ConsultarLoteRpsEnvio";
} else if (tipo.equals("4")) {
tag = "ConsultarSituacaoLoteRpsEnvio";
} else if (tipo.equals("5")) {
tag = "ConsultarNfseRpsEnvio";
}

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document docs = builder.parse(new File(caminhoXml));

NodeList elementos = docs.getElementsByTagName(tag);
Element e = (Element) elementos.item(0);
String id = e.getAttribute("Id");
e.setIdAttribute("Id", true);

XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM", new XMLDSigRI());

ArrayList<Transform> transformList = new ArrayList<Transform>();
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(caminhoCertificado), senha.toCharArray());
Enumeration<String> 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(senha.toCharArray()));

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

KeyInfoFactory kif = fac.getKeyInfoFactory();
List<X509Certificate> x509Content = new ArrayList<X509Certificate>();

x509Content.add(cert);
X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

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

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

signature.sign(dsc);

OutputStream os = new FileOutputStream(caminhoXmlNovo);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(docs), new StreamResult(os));

NodeList nl = docs.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);

}

public static void main(String[] args) throws Exception {
try {

BufferedReader in = new BufferedReader(new FileReader("J:/RP-GRF/NFSE-JR/ESTAB-100/PARAMETRO/Operacao.txt"));
String tipo = in.readLine();

String caminhoXml = "";
String arquivoXmlNovo = "";
if (tipo.equals("1")) {
caminhoXml = "J:/RP-GRF/NFSE-JR/ESTAB-100/XML/NFSE.xml";
arquivoXmlNovo = "J:/RP-GRF/NFSE-JR/ESTAB-100/XML/NFSEassinado.xml";
} else if (tipo.equals("2")) {
caminhoXml = "J:/RP-GRF/NFSE-JR/ESTAB-100/XML/NFSEcanc.xml";
arquivoXmlNovo = "J:/RP-GRF/NFSE-JR/ESTAB-100/XML/NFSEcancAssinado.xml";
} else if (tipo.equals("3")) {
caminhoXml = "J:/RP-GRF/NFSE-JR/ESTAB-100/XML/NFSEconsulta.xml";
arquivoXmlNovo = "J:/RP-GRF/NFSE-JR/ESTAB-100/XML/NFSEconsultaAssinado.xml";
} else if (tipo.equals("4")) {
caminhoXml = "J:/RP-GRF/NFSE-JR/ESTAB-100/XML/NFSEconsultaSituacao.xml";
arquivoXmlNovo = "J:/RP-GRF/NFSE-JR/ESTAB-100/XML/NFSEconsultaSituacaoAssinado.xml";
} else if (tipo.equals("5")) {
caminhoXml = "J:/RP-GRF/NFSE-JR/ESTAB-100/XML/NFSEconsultaRps.xml";
arquivoXmlNovo = "J:/RP-GRF/NFSE-JR/ESTAB-100/XML/NFSEconsultaRpsAssinado.xml";
}

String caminhoCertificado = "J:/RP-GRF/NFSE-JR/ESTAB-100/CERTIFICADOS/JRCOMERCIO.pfx ";
String senha = "123456";

File file = new File(caminhoXml);
if (!file.exists()) {
// JOptionPane.showMessageDialog(null, "Arquivo " + caminhoXml + " não encontrado!", "RPSYSTEM", JOptionPane.INFORMATION_MESSAGE);
System.out.println("Arquivo " + caminhoXml + " não encontrado!");
arquivo = new File("J:/RP-GRF/NFSE-JR/ESTAB-100/RETORNO/Assinatura.txt"); //Grava o arquivo txt com o retorno
FileOutputStream out = new FileOutputStream(arquivo, true);
String texto = "Assinatura: Erro arquivo " + caminhoXml + " não encontrado!";
texto += "\r\n";
out.write(texto.getBytes());
out.close();
return;

}
file = new File(caminhoCertificado);
if (!file.exists()) {
// JOptionPane.showMessageDialog(null, "Arquivo " + caminhoCertificado + " não encontrado!", "RPSYSTEM", JOptionPane.INFORMATION_MESSAGE);
System.out.println("Arquivo " + caminhoCertificado + " não encontrado!");
arquivo = new File("J:/RP-GRF/NFSE-JR/ESTAB-100/RETORNO/Assinatura.txt");
FileOutputStream out = new FileOutputStream(arquivo, true);
String texto = "Assinatura: Erro arquivo " + caminhoCertificado + " não encontrado!";
texto += "\r\n";
out.write(texto.getBytes());
out.close();
return;

}

Assinar t = new Assinar();
t.assinar(caminhoXml, caminhoCertificado, senha, arquivoXmlNovo);
// JOptionPane.showMessageDialog(null, "Arquivo xml assinado com sucesso!", "RPSYSTEM", JOptionPane.INFORMATION_MESSAGE);
System.out.println("Arquivo xml assinado com sucesso!");
arquivo = new File("J:/RP-GRF/NFSE-JR/ESTAB-100/RETORNO/Assinatura.txt");
FileOutputStream out = new FileOutputStream(arquivo, true);
if (tipo.equals("1")) {
String texto = "Assinatura da NFSE: Arquivo xml assinado com sucesso";
texto += "\r\n";
out.write(texto.getBytes());
out.close();
return;
} else if (tipo.equals("2")) {
String texto = "Assinatura do Cancelamento da NFSE: Arquivo xml assinado com sucesso";
texto += "\r\n";
out.write(texto.getBytes());
out.close();
return;
} else if (tipo.equals("3")) {
String texto = "Assinatura da Consulta da NFSE: Arquivo xml assinado com sucesso";
texto += "\r\n";
out.write(texto.getBytes());
out.close();
} else if (tipo.equals("4")) {
String texto = "Assinatura da Consulta da Situação: Arquivo xml assinado com sucesso";
texto += "\r\n";
out.write(texto.getBytes());
out.close();
} else if (tipo.equals("5")) {
String texto = "Assinatura da Consulta por RPS: Arquivo xml assinado com sucesso";
texto += "\r\n";
out.write(texto.getBytes());
out.close();
}


} catch (Exception e) {
// JOptionPane.showMessageDialog(null, "Erro ao tentar assinar arquivo xml! \n\n" + e.toString(), "RPSYSTEM", JOptionPane.INFORMATION_MESSAGE);
System.out.println("Erro ao tentar assinar arquivo xml! \n\n" + e.toString());
arquivo = new File("J:/RP-GRF/NFSE-JR/ESTAB-100/RETORNO/Assinatura.txt");
FileOutputStream out = new FileOutputStream(arquivo, true);
String texto = "Assinatura: Erro ao tentar assinar arquivo xml!" + e.toString();
texto += "\r\n";
out.write(texto.getBytes());
out.close();
return;
}
}
}


Utilizando a opção 5 com esse xml:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><ConsultarNfseRpsEnvio xmlns:tipos = "http://www.ginfes.com.br/tipos_v03.xsd" xmlns="http://www.ginfes.com.br/servico_consultar_nfse_rps_envio_v03.xsd"><IdentificacaoRps xmlns="http://www.ginfes.com.br/servico_consultar_nfse_rps_envio_v03.xsd"><Numero xmlns="http://www.ginfes.com.br/tipos_v03.xsd">11</Numero><Serie xmlns="http://www.ginfes.com.br/tipos_v03.xsd">1</Serie><Tipo xmlns="http://www.ginfes.com.br/tipos_v03.xsd">1</Tipo></IdentificacaoRps><Prestador><Cnpj xmlns="http://www.ginfes.com.br/tipos_v03.xsd">Num CNPJ</Cnpj><InscricaoMunicipal xmlns="http://www.ginfes.com.br/tipos_v03.xsd"> Num IM </InscricaoMunicipal></Prestador></ConsultarNfseRpsEnvio>

Retorna esse erro por não ter a Id em nenhum nó: " Erro ao tentar assinar arquivo xml!

org.w3c.dom.DOMException: NOT_FOUND_ERR: Houve uma tentativa de fazer referência a um nó em um contexto no qual ele não existe. "

Já tentei inserí-la na tag " ConsultarNfseRpsEnvio " , assina normalmente, mas não consigo enviar, por erro de schema.

Poderiam me auxiliar nesse caso?

Esta mensagem foi editada 1 vez. Última atualização foi em 21/01/2019 14:19:06

Rafael_oliveira

JavaC Membro

Membro desde: 07/04/2016 17:11:53
Mensagens: 7
Offline

Após algumas horas quebrando a cabeça, consegui.

Fica a resolução caso alguém precise posteriormente.

Mudei os campos para "xmlns" : " String id = e.getAttribute("xmlns");
e.setIdAttribute("xmlns", true); "

e:

Reference ref = fac.newReference("",fac.newDigestMethod(DigestMethod.SHA1, null), transformList, null, null);
 
Índice dos Fóruns » NF-e / NFS-e / CT-e / CF-e / Certificados Digitais
Ir para:   
Powered by JForum 2.1.9 © JForum Team