Assinaturas de arquivos xml da NFe

136 respostas
J

Boa tarde a todos
Aqui na empresa estamos tendo problemas para assinar o xml para o envio dos dados da NFe. O web service da receita sempre retorna o erro:
297 Rejeição: Assinatura difere do calculado
Acho que o erro está no campo SignatureValue da assinatura. Alguém conseguiu fazer a assinatura funcionar?

Abaixo está o código que usei: (encontrei o código aqui no forum e adaptei)

public static String sign(String xml) {
		OutputStream os = null;
		String CANONICALIZE_METHOD = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
		String C14N_TRANSFORM_METHOD = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
		String PROVIDER_CLASS_NAME = "org.jcp.xml.dsig.internal.dom.XMLDSigRI";
		String PROVIDER_NAME = "jsr105Provider";
		ByteArrayInputStream inXML = new ByteArrayInputStream(xml.getBytes());
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory
					.newInstance();
			factory.setNamespaceAware(false);
			// Obtem DOM do documento
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document doc = builder.parse(inXML);

			// Obtem elemento do documento a ser assinado, será criado uma
			// REFERENCE para o mesmo
			NodeList elements = doc.getElementsByTagName("infNFe");
			org.w3c.dom.Element el = (org.w3c.dom.Element) elements.item(0);
			String id = el.getAttribute("Id");

			// Cria uma factory representando o elemento XML Signature, a partir
			// dela serão criados as parte desse elemento
			String providerName = System.getProperty(PROVIDER_NAME,
					PROVIDER_CLASS_NAME);
			XMLSignatureFactory signatureFactory = XMLSignatureFactory
					.getInstance("DOM", (Provider) Class.forName(providerName)
							.newInstance());

			// Cria método de Digest e canonicalização
			DigestMethod digestMethod = signatureFactory.newDigestMethod(
					DigestMethod.SHA1, null);
			C14NMethodParameterSpec c14NMethodParameterSpec = null;
			CanonicalizationMethod canonicalMethod = signatureFactory
					.newCanonicalizationMethod(CANONICALIZE_METHOD,
							c14NMethodParameterSpec);

			// Cria classe representando o Hash e algoritmo de criptografia a
			// ser aplicado
			SignatureMethod sm = signatureFactory.newSignatureMethod(
					SignatureMethod.RSA_SHA1, null);

			// Cria a lista de tranformações a serem aplicadas as referencias a
			// serem assinadas
			ArrayList transformList = new ArrayList();
			TransformParameterSpec tps = null;
			Transform envelopedTransform = signatureFactory.newTransform(
					Transform.ENVELOPED, tps);
			Transform c14NTransform = signatureFactory.newTransform(
					C14N_TRANSFORM_METHOD, tps);
			transformList.add(envelopedTransform);
			transformList.add(c14NTransform);

			// Cria referencia, parte do XML a ser assinado
			Reference ref = signatureFactory.newReference("#" + id,
					digestMethod, transformList, null, null);
			ArrayList refList = new ArrayList();
			refList.add(ref);

			SignedInfo signedInfo = signatureFactory.newSignedInfo(
					canonicalMethod, sm, refList);


			String configName = "/token.cfg";
			Provider p = new sun.security.pkcs11.SunPKCS11(configName);
			Security.addProvider(p);

			char[] pin = { 's', 'a', 'f', 'e', 'w', 'e', 'b' };
			KeyStore ks = KeyStore.getInstance("pkcs11");
			ks.load(null, pin);
			KeyStore.PrivateKeyEntry pkEntry = null;
			Enumeration aliasesEnum = ks.aliases();
			PrivateKey privateKey = null;
			String alias = "";
			while (aliasesEnum.hasMoreElements()) {
				alias = (String) aliasesEnum.nextElement();
				System.out.println(alias);
				if (ks.isKeyEntry(alias)) {
					privateKey = (PrivateKey) ks.getKey(alias, new String(
							"safeweb").toCharArray());
					break;
				}
			}
			Certificate certificate = ks.getCertificate(alias);

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

			KeyInfoFactory kif = signatureFactory.getKeyInfoFactory();
			X509Data x509Data = kif.newX509Data(Collections
					.singletonList(certificate));

			KeyInfo keyInfo = kif.newKeyInfo(Collections
					.singletonList(x509Data));

			XMLSignature signature = signatureFactory.newXMLSignature(
					signedInfo, keyInfo);
			signature.sign(dsc);

			os = new ByteArrayOutputStream();

			TransformerFactory tf = TransformerFactory.newInstance();
			Transformer trans = tf.newTransformer();
			trans.transform(new DOMSource(doc), new StreamResult(os));
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return os.toString();
	}

136 Respostas

J

conseguimos fazer funcionar aqui. Quem tiver duvidas é só pedir. Estamos pensando em fazer um tutorial pra nfe :-p (se ninguem for contra :-p)

Y

Bah, um tutorial seria muito bacana! Aqui na empresa temos planos para implementar a NFe nos próximos e ter um artigo sobre isso feito por alguém que já teve problemas e conseguiu resolver seria de muita valia! Pois você já tem noção dos problemas encontrados nesse processo.

V

Um tutorial de NFe seria legal. Eu apoio esta idéia.

C

Opa,

Conta ai o segredo de tostines…
Como vc conseguiu fazer funcionar?

J

Consegui terminar os métodos que eu queria. Fiz dois métodos que recebem uma string com o xml e retornam uma String como o xml assinado. O primeiro pega um enviNFe e assina todas as NFe dentro dele. O outro assina o elemento raíz do xml, servindo para o cancelamento e para a inutilização da nota.

aqui vai o método para assinar o enviNFe:

public static String assinarEnviNFe(String xml) throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true);
		DocumentBuilder builder = factory.newDocumentBuilder();
		// Document docs = builder.parse(new File(
		// "c:/xml/430802017886010001735500000000010000030371-nfe.xml"));
		Document doc = factory.newDocumentBuilder().parse(
				new ByteArrayInputStream(xml.getBytes()));

		// Create a DOM XMLSignatureFactory that will be used to
		// generate the enveloped signature.
		XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

		// Create a Reference to the enveloped document (in this case,
		// you are signing the whole document, so a URI of "" signifies
		// that, and also specify the SHA1 digest algorithm and
		// the ENVELOPED Transform.
		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);

		// Load the KeyStore and get the signing key and certificate.

		String configName = "/token.cfg";

		Provider p = new sun.security.pkcs11.SunPKCS11(configName);
		Security.addProvider(p);

		char[] pin = { 's', 'a', 'f', 'e', 'w', 'e', 'b' };
		KeyStore ks = KeyStore.getInstance("pkcs11", p);
		ks.load(null, pin);
		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(
								"safeweb".toCharArray()));
				privateKey = pkEntry.getPrivateKey();
				break;
			}
		}

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

		// Create the KeyInfo containing the X509Data.
		KeyInfoFactory kif = fac.getKeyInfoFactory();
		List x509Content = new ArrayList();
		// x509Content.add(cert.getSubjectX500Principal().getName());
		x509Content.add(cert);
		X509Data xd = kif.newX509Data(x509Content);
		KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

		for (int i = 0; i < doc.getDocumentElement()
				.getElementsByTagName("NFe").getLength(); i++) {
			assinarNFE(fac, transformList, privateKey, ki, doc, i);
		}
		// Output the resulting document.
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer trans = tf.newTransformer();
		trans.transform(new DOMSource(doc), new StreamResult(os));
		return os.toString();
	}

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

		// Obtem elemento do documento a ser assinado, será criado uma
		// REFERENCE para o mesmo
		NodeList elements = doc.getElementsByTagName("infNFe");
		Element el = (Element) elements.item(i);
		String id = el.getAttribute("Id");

		// doc.getDocumentElement().removeAttribute("xmlns:ns2");
		// ((Element)
		// doc.getDocumentElement().getElementsByTagName("NFe").item(0))
		// .setAttribute("xmlns", "http://www.portalfiscal.inf.br/nfe");

		// Create a DOM XMLSignatureFactory that will be used to
		// generate the enveloped signature.

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

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

		// Create the XMLSignature, but don't sign it yet.
		XMLSignature signature = fac.newXMLSignature(si, ki);

		// Marshal, generate, and sign the enveloped signature.
		// Create a DOMSignContext and specify the RSA PrivateKey and
		// location of the resulting XMLSignature's parent element.
		DOMSignContext dsc = new DOMSignContext(privateKey, doc
				.getDocumentElement().getElementsByTagName("NFe").item(i));
		signature.sign(dsc);

	}

este aqui assina o elemento raiz do xml:

public static String assinarRaiz(String xml) throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true);
		DocumentBuilder builder = factory.newDocumentBuilder();
		// Document docs = builder.parse(new File(
		// "c:/xml/430802017886010001735500000000010000030371-nfe.xml"));
		Document doc = factory.newDocumentBuilder().parse(
				new ByteArrayInputStream(xml.getBytes()));

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

		// NodeList elements = doc.getElementsByTagName("infNFe");
		Node element = doc.getDocumentElement().getFirstChild()
				.getNextSibling();
		// elements.getLength();
		Element el = (Element) element;
		// Element el =
		// doc.getDocumentElement().getFirstChild().getChildNodes();
		String id = el.getAttribute("Id");

		// Create a DOM XMLSignatureFactory that will be used to
		// generate the enveloped signature.
		XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

		// Create a Reference to the enveloped document (in this case,
		// you are signing the whole document, so a URI of "" signifies
		// that, and also specify the SHA1 digest algorithm and
		// the ENVELOPED Transform.
		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);

		// Load the KeyStore and get the signing key and certificate.

		String configName = "/token.cfg";

		Provider p = new sun.security.pkcs11.SunPKCS11(configName);
		Security.addProvider(p);

		char[] pin = { 's', 'a', 'f', 'e', 'w', 'e', 'b' };
		KeyStore ks = KeyStore.getInstance("pkcs11", p);
		ks.load(null, pin);
		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(
								"safeweb".toCharArray()));
				privateKey = pkEntry.getPrivateKey();
				break;
			}
		}

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

		// Create the KeyInfo containing the X509Data.
		KeyInfoFactory kif = fac.getKeyInfoFactory();
		List x509Content = new ArrayList();
		// x509Content.add(cert.getSubjectX500Principal().getName());
		x509Content.add(cert);
		X509Data xd = kif.newX509Data(x509Content);
		KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

		// doc.getDocumentElement().removeAttribute("xmlns:ns2");
		// ((Element)
		// doc.getDocumentElement().getElementsByTagName("NFe").item(0))
		// .setAttribute("xmlns", "http://www.portalfiscal.inf.br/nfe");

		// Create a DOM XMLSignatureFactory that will be used to
		// generate the enveloped signature.

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

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

		// Create the XMLSignature, but don't sign it yet.
		XMLSignature signature = fac.newXMLSignature(si, ki);

		// Marshal, generate, and sign the enveloped signature.
		// Create a DOMSignContext and specify the RSA PrivateKey and
		// location of the resulting XMLSignature's parent element.
		DOMSignContext dsc = new DOMSignContext(privateKey, doc
				.getDocumentElement());
		signature.sign(dsc);

		// Output the resulting document.
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer trans = tf.newTransformer();
		trans.transform(new DOMSource(doc), new StreamResult(os));
		return os.toString();
	}

uma coisa que temque cuidar muito é o cabeçalho do xml que temque tá desse jeito

<?xml version="1.0" encoding="UTF-8"?>
<cancNFe versao="1.07" xmlns="http://www.portalfiscal.inf.br/nfe">

ou seja, não pode ter o xmlns:ns2=“http://www.w3.org/2000/09/xmldsig#

o mesmo vale para o enviNFe:

<enviNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.10">
  <idLote>1</idLote> 
  <NFe xmlns="http://www.portalfiscal.inf.br/nfe">

nesse caso tanto o envi como cada nfe devem ter xmlns=“http://www.portalfiscal.inf.br/nfe” e o envi não pode ter o xmlns:ns2=“http://www.w3.org/2000/09/xmldsig#”. Se por acaso o xml estiver do jeito errado, pode usar esses códigos no assinador, ou criar outro método:

esse aqui remove o xmlns:ns2 do elemento raíz:

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

esse aqui adiciona o xmlns necessário a tag NFe:

((Element) doc.getDocumentElement().getElementsByTagName("NFe").item(i)).setAttribute("xmlns", "http://www.portalfiscal.inf.br/nfe");

Quem quiser verificar o xml pode usar esse site: http://www.sefaz.rs.gov.br/AAE_ROOT/NFE/SAT-WEB-NFE-VAL_1.asp Acho que ele só valida os certificados do Rio Grande do Sul, mas o bom é que ele verifica a estrutura do xml tb.

É isso por enquanto, qualquer coisa é só perguntar.

J

esqueci de colocar, esse são os imports da classe:

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.StringWriter;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
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.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;

Estou usando Java 5. então para usar os crypto eu tive que baixar o jwsdp-2.0 (java web server) e importar alguns jars dele. acho que foram esses:

/xmldsig/lib/xmldsig.jar" />
/jaxp/lib/jaxp-api.jar" />
/jaxp/lib/endorsed/dom.jar" />
/jaxp/lib/endorsed/xercesImpl.jar" />
/jwsdp-shared/lib/xmlsec.jar" />
/jaxp/lib/endorsed/xalan.jar" />

A
String configName = "/token.cfg";  
 Provider p = new sun.security.pkcs11.SunPKCS11(configName);  
 Security.addProvider(p);  
 char[] pin = { 's', 'a', 'f', 'e', 'w', 'e', 'b' };

Com relação ao codigo acima, gostaria de saber sobre esse arq. token.cfg que informação contem nesse arquivo, como faço para gerar esse arquivo ?
e com relação ao char[] pin que informação eu devo setar ?

E

ale,

Nesse arquivo temos informações sobre o driver do dispositivo pkcs11 instalado.

Segue exemplo:

name = Safenetikey2032

library = c:\windows\system32\dkck201.dll

beleza?

P

A

Olá,

Estou iniciando com SOAP tbm para um projeto de NFE. Alguém poderiam postar o código que transmite o arquivo após a assinatura?

Muito Obrigado!!

A

Bom dia pessoal,

Como fica o código acima quando tenho como certificado, um arquivo pfx (serasa)? Como uso o keytool para importar para um keystore e como ficaria o código que busca o certificado?

Orbigado!!!

R

Boa tarde pessoal,

Estou tentando assinar um XML da NFe usando o código acima, já consegui efetuar a conexão com o web-server usando o código abaixo:
[b]

System.setProperty(“java.protocol.handler.pkgs”,“com.sun.net.ssl.internal.www.protocol”);

Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
System.setProperty(“javax.net.ssl.keyStoreType”, “PKCS12”);

System.setProperty(“javax.net.ssl.keyStore”, verConf.getPathKeyPFX());

System.setProperty(“javax.net.ssl.keyStorePassword”, “xxxx”);
System.setProperty(“javax.net.ssl.trustStoreType”, “JKS”);

System.setProperty(“javax.net.ssl.trustStore”,verConf.getPathKeyJKS());

[/b]

Alguem já conseguiu assinar um XML NFe usando somente o arquivo .pfx ??

D

Eu consegui… veja a parte do certificado:

// Load the KeyStore and get the signing key and certificate.
		KeyStore ks = KeyStore.getInstance(Statics.getKeystoreType());
		FileInputStream fis = new FileInputStream(Statics.getKeystoreFile());
		//load the keystore
		ks.load(fis, Statics.getKeystorePassword().toCharArray());
		String alias = ks.aliases().nextElement();

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

		X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
		
		// Create the KeyInfo containing the X509Data.
		KeyInfoFactory kif = fac.getKeyInfoFactory();
		List<Serializable> x509Content = new ArrayList<Serializable>();
		x509Content.add(cert.getSubjectX500Principal().getName());
		x509Content.add(cert);
		X509Data xd = kif.newX509Data(x509Content);
		KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
		
		for (int i = 0; i < doc.getDocumentElement().getElementsByTagName("NFe").getLength(); i++) {
			assinarNFE(fac, transformList, keyEntry.getPrivateKey(), ki, doc, i);
		}

So que o retorno da sefaz de MT e o seguinte:

<?xml version="1.0" encoding="UTF-8"?>
<retConsReciNFe xmlns="http://www.portalfiscal.inf.br/nfe" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.portalfiscal.inf.br/nfe retConsReciNFe_v1.10.xsd" versao="1.10">
<tpAmb>2</tpAmb>
<verAplic>1.10</verAplic>
<nRec>510000000060267</nRec>
<cStat>104</cStat>
<xMotivo>Lote processado</xMotivo>
<cUF>51</cUF>
<protNFe versao="1.10">
<infProt>
<tpAmb>2</tpAmb>
<verAplic>1.10</verAplic>
<chNFe>510804926656110128505500012345678918</chNFe>
<dhRecbto>2008-05-05T19:33:00</dhRecbto>
<cStat>297</cStat>
<xMotivo>Rejeicao: Assinatura difere do calculado</xMotivo>
</infProt>
</protNFe>
</retConsReciNFe>
D

Será que o erro de rejeição tem a ver com encoding, ou algo do sentido?

A

Bom dia, vc validou seu XMl antes de conectar e enviar??
Acesse esse site e coloque seu XML para testar, ai verificará se ele está correto e se a assinatura está correta antes de conectar no web service.

http://www.sefaz.rs.gov.br/AAE_ROOT/NFE/SAT-WEB-NFE-VAL_1.asp

D

Bom dia…

Sim, eu validei o schema com um programa chamado XmlNotepad, ele é um schema válido. Segundo informações da sefaz-MT, o esquema está correto, eles dizem que o erro é na assinatura em si.

Quanto aquele validador da sefaz, nao rola pra mim pq a versao que a sefaz-mt usa e diferente…

A

E o programa Assinador do portal da nfe, aquele vc pode colocar os Schemas da tua versão e ele válida a assinatura, utlizava ele na versão PL005a, PL007…etc…

http://www.nfe.fazenda.gov.br/portal/assinador.aspx

abraços

V

developermaster:
Bom dia…

Sim, eu validei o schema com um programa chamado XmlNotepad, ele é um schema válido. Segundo informações da sefaz-MT, o esquema está correto, eles dizem que o erro é na assinatura em si.

Quanto aquele validador da sefaz, nao rola pra mim pq a versao que a sefaz-mt usa e diferente…

Eu trabalho com a sefaz-mt e eles estão com a versão 1.10.
Parece que já estão aceitando 1.12 também.

D

Pessoal, usei o assinador do RS, que usa .net pra assinar, e depois so transmiti com o meu programa em java, dai ele aceita o mardito!!!

Segui o codigo de Assinatura do pessoal aqui no forum, apenas adaptei pra usar um certificado em arquivo, alguem esta passando pelo mesmo ou tem alguma solucao?

Segue abaixo o codigo:

package com.developermaster.nfe.utils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.Serializable;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.xml.XMLConstants;
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.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.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class Util {	
		
	public static String getXmlContent(String xmlFile) {
		String retorno = "";
		try {
			BufferedReader reader = new BufferedReader(new FileReader(xmlFile));
			String aux = null;
			while ((aux = reader.readLine()) != null) {
				retorno += aux;
			}
			reader.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return retorno;
	}

	public static void GravaRetorno(String xmlFile, String conteudo) {
		try {
			FileOutputStream file = new FileOutputStream(xmlFile, false);
			file.write(conteudo.getBytes());
			file.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void ValidateXml(String xml, String xsd) {
		try {
            // Parse an XML document into a DOM tree.
            DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
            Document document = parser.parse(new File(xml));

            // Create a SchemaFactory capable of understanding WXS schemas.
            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

            // Load a WXS schema, represented by a Schema instance.
            Source schemaFile = new StreamSource(new File(xsd));
            Schema schema = factory.newSchema(schemaFile);

            // Create a Validator object, which can be used to validate
            // an instance document.
            Validator validator = schema.newValidator();

            // Validate the DOM tree.
            validator.validate(new DOMSource(document));

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
        	e.printStackTrace();
        } catch (IOException e) {
        	e.printStackTrace();
        }
	}
	
	public static String assinarEnviNFe(String xml) throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true);
		factory.setIgnoringElementContentWhitespace(true);
		DocumentBuilder builder = factory.newDocumentBuilder();
		// Document docs = builder.parse(new File(
		// "c:/xml/430802017886010001735500000000010000030371-nfe.xml"));
		Document doc = factory.newDocumentBuilder().parse(new File(xml));
		
		String providerName = System.getProperty("jsr105Provider", "org.jcp.xml.dsig.internal.dom.XMLDSigRI");

		// Create a DOM XMLSignatureFactory that will be used to
		// generate the enveloped signature.
		XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM",(Provider) Class.forName(providerName).newInstance());

		// Create a Reference to the enveloped document (in this case,
		// you are signing the whole document, so a URI of "" signifies
		// that, and also specify the SHA1 digest algorithm and
		// the ENVELOPED Transform.
		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(c14NTransform);
		transformList.add(envelopedTransform);

		// Load the KeyStore and get the signing key and certificate.
		KeyStore ks = KeyStore.getInstance(Statics.getKeystoreType());
		FileInputStream fis = new FileInputStream(Statics.getKeystoreFile());
		
		// load the keystore
		ks.load(fis, Statics.getKeystorePassword().toCharArray());
		
		KeyStore.PrivateKeyEntry keyEntry = null;
		
		while (ks.aliases().hasMoreElements()) {
			String alias = ks.aliases().nextElement();
			if (ks.isKeyEntry(alias)) {
				keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(Statics.getKeystorePassword().toCharArray()));
				break;
			}
		}
		
		X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

		// Create the KeyInfo containing the X509Data.
		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("NFe").getLength(); i++) {
			assinarNFE(fac, transformList, keyEntry.getPrivateKey(), ki, doc, i);
		}
		// Output the resulting document.
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer trans = tf.newTransformer();
		trans.transform(new DOMSource(doc), new StreamResult(os));
		return os.toString();
	}

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

		// Obtem elemento do documento a ser assinado, será criado uma
		// REFERENCE para o mesmo
		NodeList elements = doc.getElementsByTagName("infNFe");
		Element el = (Element) elements.item(i);
		String id = el.getAttribute("Id");

		// doc.getDocumentElement().removeAttribute("xmlns:ns2");
		// ((Element)
		// doc.getDocumentElement().getElementsByTagName("NFe").item(0))
		// .setAttribute("xmlns", "http://www.portalfiscal.inf.br/nfe");

		// Create a DOM XMLSignatureFactory that will be used to
		// generate the enveloped signature.

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

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

		// Create the XMLSignature, but don't sign it yet.
		XMLSignature signature = fac.newXMLSignature(si, ki);

		// Marshal, generate, and sign the enveloped signature.
		// Create a DOMSignContext and specify the RSA PrivateKey and
		// location of the resulting XMLSignature's parent element.
		DOMSignContext dsc = new DOMSignContext(privateKey, doc
				.getDocumentElement().getElementsByTagName("NFe").item(i));
		signature.sign(dsc);

	}
	
	public static String assinarRaiz(String xml) throws Exception {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		factory.setNamespaceAware(true);
		//DocumentBuilder builder = factory.newDocumentBuilder();
		// Document docs = builder.parse(new File(
		// "c:/xml/430802017886010001735500000000010000030371-nfe.xml"));
		Document doc = factory.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes()));

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

		// NodeList elements = doc.getElementsByTagName("infNFe");
		Node element = doc.getDocumentElement().getFirstChild().getNextSibling();
		// elements.getLength();
		Element el = (Element) element;
		
		String id = el.getAttribute("Id");

		// Create a DOM XMLSignatureFactory that will be used to
		// generate the enveloped signature.
		XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

		// Create a Reference to the enveloped document (in this case,
		// you are signing the whole document, so a URI of "" signifies
		// that, and also specify the SHA1 digest algorithm and
		// the ENVELOPED Transform.
		ArrayList<Transform> transformList = new ArrayList<Transform>();
		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);

		// Load the KeyStore and get the signing key and certificate.
		KeyStore ks = KeyStore.getInstance(Statics.getKeystoreType());
		FileInputStream fis = new FileInputStream(Statics.getKeystoreFile());
		//load the keystore
		ks.load(fis, Statics.getKeystorePassword().toCharArray());
		String alias = ks.aliases().nextElement();
		KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(Statics.getKeystorePassword().toCharArray()));

		//get the private key for signing.
		//PrivateKey privateKey = (PrivateKey) ks.getKey(privateKeyAlias, privateKeyPass.toCharArray());
		
		X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
		
		// Create the KeyInfo containing the X509Data.
		KeyInfoFactory kif = fac.getKeyInfoFactory();
		List<Serializable> x509Content = new ArrayList<Serializable>();
		x509Content.add(cert.getSubjectX500Principal().getName());
		x509Content.add(cert);
		X509Data xd = kif.newX509Data(x509Content);
		KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
		
		doc.getDocumentElement().removeAttribute("xmlns:ns2");
		// ((Element)
		// doc.getDocumentElement().getElementsByTagName("NFe").item(0))
		// .setAttribute("xmlns", "http://www.portalfiscal.inf.br/nfe");

		// Create a DOM XMLSignatureFactory that will be used to
		// generate the enveloped signature.

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

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

		// Create the XMLSignature, but don't sign it yet.
		XMLSignature signature = fac.newXMLSignature(si, ki);

		// Marshal, generate, and sign the enveloped signature.
		// Create a DOMSignContext and specify the RSA PrivateKey and
		// location of the resulting XMLSignature's parent element.
		DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc
				.getDocumentElement());
		signature.sign(dsc);

		// Output the resulting document.
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer trans = tf.newTransformer();
		trans.transform(new DOMSource(doc), new StreamResult(os));
		return os.toString();
	}
}
D

Entao, ninguem conseguiu assinar usando um arquivo pfx ou p12???

A

boa tarde!!!

Eu consegui assinar cada arquivo de nfe individualemente usando um arquivo PFX de certificado.
SEgue em anexo o código.

A

Bom dia pessoal,
Alguém já conseguiu fazer conexão, envio e retorno de xml de algum dos Web Services da NF-e. Se alguem tiver um exemplo ficaria grato se pudesse me enviar ou colocar no forum.
[email removido]

B

Alem das rotinas de assinatura da NFe, vocês também tem a implementação do cliente WebService?

Teria como postar aqui no tópico ou enviar para [email removido] ?

Obrigado

B

Como consigo gerar o arquivo pfx a partir do token?

Alguma dica?

D

O Arquivo pfx vc nao gera, ele é o certificado q vc tem de adquiri junto a uma autoridade certificadora.

Quanto ao consumo dos webservices, procure pelo AXIS, da apache.

A

Ola pessoal,
Alguém por acaso poderia me enviar o arquivo dkck201.dll, pois eu não consegui encontrar no windows vista :frowning:
Melhor, realmente é necessário o uso dessa dll, junto do exemplo postado?

Abraços,
Alexandre.

email: [email removido]

B

Pessoal, ao executar o código da assinatura da NFe que foi fornecido nos posts anteriores, me deparei com o seguinte erro:

Private keys must be instance of RSAPrivate(Crt)Key or have PKCS#8 encoding

Na parte de assinatura:

// Marshal, generate, and sign the enveloped signature.  
      // Create a DOMSignContext and specify the RSA PrivateKey and  
      // location of the resulting XMLSignature's parent element.  
      DOMSignContext dsc = new DOMSignContext(privateKey, doc.getElementsByTagName("NFe").item(i));  
      signature.sign(dsc);

Exception in thread "main" javax.xml.crypto.dsig.XMLSignatureException: java.security.InvalidKeyException: Private keys must be instance of RSAPrivate(Crt)Key or have PKCS#8 encoding at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:376) at com.chart.julianosott.NFEUtils.assinarNFE(NFEUtils.java:155) at com.chart.julianosott.NFEUtils.assinarEnviNFe(NFEUtils.java:115) at com.chart.testcases.TrustExample.main(TrustExample.java:75) Caused by: java.security.InvalidKeyException: Private keys must be instance of RSAPrivate(Crt)Key or have PKCS#8 encoding at sun.security.rsa.RSAKeyFactory.translatePrivateKey(RSAKeyFactory.java:246) at sun.security.rsa.RSAKeyFactory.engineTranslateKey(RSAKeyFactory.java:149) at sun.security.rsa.RSAKeyFactory.toRSAKey(RSAKeyFactory.java:79) at sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:90) at sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:84) at java.security.Signature$Delegate.init(Signature.java:1073) at java.security.Signature$Delegate.chooseProvider(Signature.java:1033) at java.security.Signature$Delegate.engineInitSign(Signature.java:1097) at java.security.Signature.initSign(Signature.java:480) at org.jcp.xml.dsig.internal.dom.DOMRSASignatureMethod.sign(DOMRSASignatureMethod.java:134) at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:373) ... 3 more java.security.InvalidKeyException: Private keys must be instance of RSAPrivate(Crt)Key or have PKCS#8 encoding at sun.security.rsa.RSAKeyFactory.translatePrivateKey(RSAKeyFactory.java:246) at sun.security.rsa.RSAKeyFactory.engineTranslateKey(RSAKeyFactory.java:149) at sun.security.rsa.RSAKeyFactory.toRSAKey(RSAKeyFactory.java:79) at sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:90) at sun.security.rsa.RSASignature.engineInitSign(RSASignature.java:84) at java.security.Signature$Delegate.init(Signature.java:1073) at java.security.Signature$Delegate.chooseProvider(Signature.java:1033) at java.security.Signature$Delegate.engineInitSign(Signature.java:1097) at java.security.Signature.initSign(Signature.java:480) at org.jcp.xml.dsig.internal.dom.DOMRSASignatureMethod.sign(DOMRSASignatureMethod.java:134) at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:373) at com.chart.julianosott.NFEUtils.assinarNFE(NFEUtils.java:155) at com.chart.julianosott.NFEUtils.assinarEnviNFe(NFEUtils.java:115) at com.chart.testcases.TrustExample.main(TrustExample.java:75)

Estou utilizando o JDK6, update 10. Alguém obteve o mesmo erro ou sabe como resolvê-lo?

J

.

T

Boa tarde pessoal,

Queria a ajuda de vocês para fazer a chamada do web service e o envio do meu xml pra eles.
Como vcs fizeram isso???

Tou começando nisso agora e tou quebrando a cabeça aki, se alguém puder me ajudar…

T

Bem pessoal,

Depois de alguns dias rachando o crânio, consegui adaptar um método para assinatura de XML’s para envio de NF-e.
Fiz o uso dele no arquivo disponibilizado para teste no site:
E coloquei no link:
para validar a assinatura e foi tudo ok!!

RELEMBRANDO: ele assina o XML, mas com base nos dados que este já tem. Para assiná-lo você já deve estar com a chave de acesso OK e todos os campos validados. ELE REALMENTE SÓ ASSINA O XML.

Enfim, tá ae o código:

import java.security.*;
import java.security.Certificate;
import java.security.cert.*;
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.*;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;



public class TratadorCertificado{
	/*
	 * 	Classe para tratamento de certificados. Deve fazer a manipulacao
	 * dos certificados exportando chaves, assinando XML's e demais funcoes.
	 *
	 */	
	public static final String algoritmo= "RSA"; 
	public static final String algoritmoAssinatura= "MD5withRSA"; 
	private static final String C14N_TRANSFORM_METHOD = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
	public static File file= new File("Caminho da Keystore .jks");
	private static String alias="seu alias";
	private static char[] senha="sua senha".toCharArray(); 
	static XMLSignatureFactory sig;
	static X509Certificate cert;
	static KeyInfo ki; 
	static SignedInfo si;
	static KeyStore rep;
	
	public static PrivateKey getChavePrivada() throws Exception{
				
		InputStream entrada= new FileInputStream(file);
		rep.load(entrada, senha);
		entrada.close();
		Key chavePrivada= (Key) rep.getKey(alias, senha);
		if(chavePrivada instanceof PrivateKey){
			System.out.println("Chave Privada encontrada!");
			return (PrivateKey) chavePrivada;
		}
		return null;		
	}
	
	public static PublicKey getChavePublica() throws Exception{
			
		InputStream entrada= new FileInputStream(file);
		rep.load(entrada, senha);
		entrada.close();
		Key chave= (Key) rep.getKey(alias, senha);		
		java.security.Certificate cert= (java.security.Certificate) rep.getCertificate(alias);//O tipo de dado é declarado desse modo por haver ambigüidade (Classes assinadas com o mesmo nome "Certificate")
		PublicKey chavePublica= cert.getPublicKey();
		System.out.println("Chave Pública encontrada!");
		return chavePublica;		
	}
	
	public static boolean verificarAssinatura(PublicKey chave, byte[] buffer, byte[] assinado) throws Exception{
		
		Signature assinatura= Signature.getInstance(algoritmoAssinatura);
		assinatura.initVerify(chave);
		assinatura.update(buffer, 0, buffer.length);
		return assinatura.verify(assinado);
	}
	
	public static byte[] criarAssinatura(PrivateKey chavePrivada, byte[] buffer) throws Exception{
		
		Signature assinatura= Signature.getInstance(algoritmoAssinatura);		
		assinatura.initSign(chavePrivada);
		assinatura.update(buffer, 0, buffer.length);
		return assinatura.sign();
	}
	
	public static String getValidade(X509Certificate cert){
		try{
			cert.checkValidity();
			return "Certificado válido!";
		}
		catch(CertificateExpiredException e){
			return "Certificado expirado!";
		}
		catch(CertificateNotYetValidException e){
			return "Certificado inválido!";
		}		
	}	
	
	public static void getCertificado() throws Exception{					
		InputStream dado= new FileInputStream(file);		
		rep= KeyStore.getInstance("JKS");		
		rep.load(dado, senha);
		cert= (X509Certificate) rep.getCertificate(alias);
		String retorno= TratadorCertificado.getValidade(cert);
		System.out.println(retorno);		
	}	
	
	public static void assinarDocumento(String localDocumento) throws Exception{		
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setNamespaceAware(true);
		Document doc = dbf.newDocumentBuilder().parse
		    (new FileInputStream(localDocumento));
		System.out.println("Documento ok!");
		
		sig= XMLSignatureFactory.getInstance("DOM");
		
		ArrayList<Transform> transformList= new ArrayList<Transform>();
		Transform enveloped= sig.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
		Transform c14n= sig.newTransform(C14N_TRANSFORM_METHOD, (TransformParameterSpec) null);
		transformList.add(enveloped);
		transformList.add(c14n);
		
		NodeList elements = doc.getElementsByTagName("infNFe");
		org.w3c.dom.Element el = (org.w3c.dom.Element) elements.item(0);
		String id = el.getAttribute("Id");
		Reference r= sig.newReference		
		 ("#".concat(id), sig.newDigestMethod(DigestMethod.SHA1, null),
				  transformList,
				     null, null);
		si = sig.newSignedInfo(
			sig.newCanonicalizationMethod
				(CanonicalizationMethod.INCLUSIVE,
					(C14NMethodParameterSpec) null),
						sig.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
						Collections.singletonList(r)						
		);
		
		KeyInfoFactory kif = sig.getKeyInfoFactory();
		List x509Content = new ArrayList();		
		x509Content.add(cert);
		X509Data xd = kif.newX509Data(x509Content);
		ki = kif.newKeyInfo(Collections.singletonList(xd));		
		
		DOMSignContext dsc = new DOMSignContext
	    (getChavePrivada(), doc.getDocumentElement());
		XMLSignature signature = sig.newXMLSignature(si, ki);
		signature.sign(dsc);
		OutputStream os = new FileOutputStream("Nome do arquivo de saída");
		TransformerFactory tf = TransformerFactory.newInstance();
		Transformer trans = tf.newTransformer();
		trans.transform(new DOMSource(doc), new StreamResult(os));
		
	}
	
	public static void main(String[] args) {
		try{
			TratadorCertificado.getCertificado();			
			TratadorCertificado.assinarDocumento("Caminho da XML para ser assinada");
		}
		catch(Exception e){
			e.printStackTrace();
		}
	
	}
	
}

Qualquer dúvidam, entrem em contato via MP.

Obrigado a todos os colegas que têm postado as suas soluções aqui. Profissionais inexperientes como eu (3 semanas :stuck_out_tongue: ) aprendem muito a partir das dicas dos colegas.

Abraço,

Tiago Paulino.

F

alexandretalbert:
Olá,

Estou iniciando com SOAP tbm para um projeto de NFE. Alguém poderiam postar o código que transmite o arquivo após a assinatura?

Muito Obrigado!!

voce tera q implementar o webservice,
http://www.guj.com.br/posts/list/30/72325.java#553800
aqui tem o codigo com expemplo pra gerar as classes que acessam

abraço

V

Galera,

Estou seguindo o código do julianosott postado na primeira página desse tópico. Quando assino a minha nota fiscal ela esta vindo com a seguinte tag:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

Alguem sabe como que eu tiro essa propriedade standalone dessa tag?

Acho que é isso que esta quebrando as minhas pernas na hora do envio da nota fiscal.
Estou usando java 1.5_10.

V

Galera,

Achei aqui, se alguem passar por isso é so colocar assim:

doc.setXmlStandalone(true);
F

boa tarde pessoal
alguem sabe algo sobre isso???

http://nfe.sef.sc.gov.br/index.php?option=com_content&task=view&id=75&Itemid=54

abraço

P

julianosott:
Consegui terminar os métodos que eu queria. Fiz dois métodos que recebem uma string com o xml e retornam uma String como o xml assinado. O primeiro pega um enviNFe e assina todas as NFe dentro dele. O outro assina o elemento raíz do xml, servindo para o cancelamento e para a inutilização da nota.

aqui vai o método para assinar o enviNFe:

Quem quiser verificar o xml pode usar esse site: http://www.sefaz.rs.gov.br/AAE_ROOT/NFE/SAT-WEB-NFE-VAL_1.asp Acho que ele só valida os certificados do Rio Grande do Sul, mas o bom é que ele verifica a estrutura do xml tb.

É isso por enquanto, qualquer coisa é só perguntar.

Tenho tido casos estranhos de Assinatura invalida de uma nota dentro de lote com varias outras.
Explico os detalhes:

Uma nota x, gerada seu xml e assinada passa pelo validador tanto do site acima como no programa fornecido pela SEFAZ, o “AssinadorRS v2.1.0”.
Dentro do mesmo programa, gerando um lote com esta nota (ja validada pelo dito), o lote gerado resulta em “Assinatura INVALIDA”.

Prestem atencao ao detalhe que, sem sair do programa AssinadorRS v2.1.0, a nota avulsa valida e a mesma dentro de um lote nao valida.

O suporte da NFe me relatou na sua ultima resposta:
[i]
Pode estar acontecendo 2 erros:

  • o primeiro é o uso de algum caractere especial não permitido (< > & " ') - ver pg. 69 manual de integração - contribuinte.

A outra possibilidade é de a nota estar sendo alterada entre a assinatura e a transmissão da NF-e
[/i]

Duvida: se o xml da nota avulsa tivesse algum caracter nao permitido, teria validado no schema e na assinatura?
A segunda hipotese cai por agua, pelos testes que fiz.

Se alguem ja passou por isso ou se tiver alguma dica, por favor, retornem o quanto antes possivel.

Grato

Alencar
P.S.: Em anexo os result do AssinadorRS v2.1.0. Por motivos de sigilo, nao posso anexar os xml.

P

philler:

Tenho tido casos estranhos de Assinatura invalida de uma nota dentro de lote com varias outras.
Explico os detalhes:

Uma nota x, gerada seu xml e assinada passa pelo validador tanto do site acima como no programa fornecido pela SEFAZ, o “AssinadorRS v2.1.0”.
Dentro do mesmo programa, gerando um lote com esta nota (ja validada pelo dito), o lote gerado resulta em “Assinatura INVALIDA”.

Prestem atencao ao detalhe que, sem sair do programa AssinadorRS v2.1.0, a nota avulsa valida e a mesma dentro de um lote nao valida.

O suporte da NFe me relatou na sua ultima resposta:
[i]
Pode estar acontecendo 2 erros:

  • o primeiro é o uso de algum caractere especial não permitido (< > & " ') - ver pg. 69 manual de integração - contribuinte.

A outra possibilidade é de a nota estar sendo alterada entre a assinatura e a transmissão da NF-e
[/i]

Duvida: se o xml da nota avulsa tivesse algum caracter nao permitido, teria validado no schema e na assinatura?
A segunda hipotese cai por agua, pelos testes que fiz.

Se alguem ja passou por isso ou se tiver alguma dica, por favor, retornem o quanto antes possivel.

Grato

Alencar
P.S.: Em anexo os result do AssinadorRS v2.1.0. Por motivos de sigilo, nao posso anexar os xml.

Respondendo ao meu proprio email, descobri apos 2 dias intensos de testes.
Dentro do campo observacao da nota, constava algo do tipo “Entrega: Rua Etc, 123456”, onde entre o : e a primeira letra
tinha DOIS ESPACOS.
Tirando um deles tudo volta a funcionar.

Pergunto aos amigos: que b…ta de regra e’ esta que o usuario nao pode preencher um campo texto de 60 caracteres do jeito
que ele bem entende ou precisa?
Sao BURROCRACIAS assim que trancam um processo simples como a NFe.

Alencar

F

é realmente, a nf-e tem umas regras bem chatinhas… mas por outro lado é bom pra manter a integridade dos dados…

estou usando xstream pra gerar o xml, ele ja substitui os < > & e tals, pra nao dar problema no xml, isso é uma coisa útil, acredito que o jaxb tbm faça isso…

o que andou me encomodando, é o campo obs que no nosso sistema aceita \r\n (enter do windows) e no xml isso estava dando problema, tive de tratar usando o replaceALL do String…

abraço

F

boa tarde pessoal estou usado o iKey2032 que (pelo que entendi) usa a dll dkck201.dll

to com uns problemas…
ta dando (403)Forbiden quando vou acessar os webservice…

estou setando as propriedades assim:

System.setProperty("javax.net.ssl.keyStoreType", "pkcs11");
	        System.setProperty("javax.net.ssl.keyStorePassword", certPass);
	        Provider pr = new sun.security.pkcs11.SunPKCS11("token.cfg");	        
	        java.security.Security.addProvider(pr);

meu arquivo token.cfg ta assim

library=C:\WINDOWS\system32\dkck201.dll
name=Safenetikey2032

alguem sabe o que pode estar errado???
alguem ja usou esse token?

abraço!

P

f-schmitt:
boa tarde pessoal estou usado o iKey2032 que (pelo que entendi) usa a dll dkck201.dll

to com uns problemas…
ta dando (403)Forbiden quando vou acessar os webservice…

estou setando as propriedades assim:

System.setProperty("javax.net.ssl.keyStoreType", "pkcs11");
	        System.setProperty("javax.net.ssl.keyStorePassword", certPass);
	        Provider pr = new sun.security.pkcs11.SunPKCS11("token.cfg");	        
	        java.security.Security.addProvider(pr);

meu arquivo token.cfg ta assim

library=C:\WINDOWS\system32\dkck201.dll
name=Safenetikey2032

alguem sabe o que pode estar errado???
alguem ja usou esse token?

abraço!

Tente alterar para isso:

// configura o acesso dos certificados de validacao
			System.setProperty("javax.net.ssl.trustStoreType", "PKCS11");
			System.setProperty("javax.net.ssl.trustStore", "NONE");
			System.setProperty("javax.net.ssl.trustStoreProvider", "SunPKCS11-Safenetikey2032");
			System.setProperty("javax.net.ssl.trustStoreAlias", alias);
			System.setProperty("javax.net.ssl.trustStorePassword", passwd);

			// configura o acesso ao certificado do cliente
			System.setProperty("javax.net.ssl.keyStoreType", "PKCS11");
			System.setProperty("javax.net.ssl.keyStore", "NONE");
			System.setProperty("javax.net.ssl.keyStoreProvider", "SunPKCS11-Safenetikey2032");
			System.setProperty("javax.net.ssl.keyStoreAlias", alias);
			System.setProperty("javax.net.ssl.keyStorePassword", passwd);

Alencar

F

OPA, vou testar aqui…

o trust nao vou trocar pq ja uso assim, ok?

System.setProperty("javax.net.ssl.trustStoreType", "JKS");
System.setProperty("javax.net.ssl.trustStore", "jssecacerts");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

o que voce coloca no ALIAS?

VALEU!!!

F

troquei la

fiz assim:

System.setProperty("javax.net.ssl.keyStoreType", "PKCS11");
System.setProperty("javax.net.ssl.keyStore", "NONE");
System.setProperty("javax.net.ssl.keyStoreProvider", "SunPKCS11-Safenetikey2032");
System.setProperty("javax.net.ssl.keyStoreAlias", "Safenetikey2032");
System.setProperty("javax.net.ssl.keyStorePassword", certPass);

deu erro denovo
no debug
deu isso

[list]
keyStore is : NONE
keyStore type is : PKCS11
keyStore provider is : SunPKCS11-Safenetikey2032
init keystore
default context init failed: java.security.NoSuchProviderException: no such prov
ider: SunPKCS11-Safenetikey2032
[/list]

o card funcionou tao bem, agora o token ta me deixando preocupado…

P

Este erro é tipico quando o nome dentro do .cfg esta errado.
Tente algumas alteracoes neste nome, tipo name = Card, e no provider toque por SunPKCS11Card.
Sei que passei por isso e era no nome o problema.
O que acontece no caso java.security.NoSuchProviderException é porque nao encontrou a dll.

Alencar

E

pessoal alguem poderia me ajudar estou usando o codigo deixado acima mais estou com um pequeno problema em resolver este erro aqui

java.lang.NullPointerException

at TratadorCertificado.getValidade(TratadorCertificado.java:82)

at TratadorCertificado.getCertificado(TratadorCertificado.java:100)

at TratadorCertificado.main(TratadorCertificado.java:159)

ja aconteceu com alguem ?

P

evandromib:
pessoal alguem poderia me ajudar estou usando o codigo deixado acima mais estou com um pequeno problema em resolver este erro aqui

java.lang.NullPointerException

at TratadorCertificado.getValidade(TratadorCertificado.java:82)

at TratadorCertificado.getCertificado(TratadorCertificado.java:100)

at TratadorCertificado.main(TratadorCertificado.java:159)

ja aconteceu com alguem ?

Poderia especificar qual dos codigos acima voce esta usando?
Ja debugou para ver onde da o erro exatamente?

Alencar

E

o codigo postado pelo tspaulino

consegui ajustar alguns erros e wargings

mais estão aparecendo estes erros aqui qdo executo ele

java.io.IOException: Keystore was tampered with, or password was incorrect

at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:771)

at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:38)

at java.security.KeyStore.load(KeyStore.java:1185)

at TratadorCertificado.getCertificado(TratadorCertificado.java:121)

at TratadorCertificado.getCertificado(TratadorCertificado.java:121)

Caused by: java.security.UnrecoverableKeyException: Password verification failed

at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:769)

fiz todas as instalações e importações referentes a os certificados será que esta faltando mais coisas ?

A

reinaldoaraujo:
Boa tarde pessoal,

Estou tentando assinar um XML da NFe usando o código acima, já consegui efetuar a conexão com o web-server usando o código abaixo:
[b]

System.setProperty(“java.protocol.handler.pkgs”,“com.sun.net.ssl.internal.www.protocol”);

Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
System.setProperty(“javax.net.ssl.keyStoreType”, “PKCS12”);

System.setProperty(“javax.net.ssl.keyStore”, verConf.getPathKeyPFX());

System.setProperty(“javax.net.ssl.keyStorePassword”, “xxxx”);
System.setProperty(“javax.net.ssl.trustStoreType”, “JKS”);

System.setProperty(“javax.net.ssl.trustStore”,verConf.getPathKeyJKS());

[/b]

Alguem já conseguiu assinar um XML NFe usando somente o arquivo .pfx ??

O path que você usa é o completo do arquivo (/Users/ze/certificado.pfx) ou relativo ao classpath (/certs/certificado.pfx)?

A

ola
estou tendo problemas com a assinatura da nfe. (estou usando o codigo daqui http://www.guj.com.br/posts/list/30/83758.java)
eu envio o xml de lote vai tranquilo,ai qdo vou consultar
me retorma a seguinte msg: “Rejeição: Certificado Assinatura inválido”. estou consumindo o ws do PR
Agora eu queria saber… eu estou usando o certificado .pfx para fazer essa assinatura.
Tenho que fazer alguma coisa a mais com o certificado? apenas com o pfx da para fazer a assinatura normalmente??

abraço

P

alves.Felipe:
ola
estou tendo problemas com a assinatura da nfe. (estou usando o codigo daqui http://www.guj.com.br/posts/list/30/83758.java)
eu envio o xml de lote vai tranquilo,ai qdo vou consultar
me retorma a seguinte msg: “Rejeição: Certificado Assinatura inválido”. estou consumindo o ws do PR
Agora eu queria saber… eu estou usando o certificado .pfx para fazer essa assinatura.
Tenho que fazer alguma coisa a mais com o certificado? apenas com o pfx da para fazer a assinatura normalmente??

abraço

Tive este problema e era espacos entre palavras, tipo assim: “palavra palavra”.
O problema é os dois espacos (ou mais) entre palavras. Só pode ter um.

Alencar

F

Bom dia, somente com o pfx é o suficiente para assinar a nfe, para transmitir precisa de mais alguns certificados,
antes de enviar valide a NFe/Lote no site
http://www.sefaz.rs.gov.br/NFE/NFE-VAL.aspx
ai voce vai ter certeza se há algo de errado na

abraço

A

f-schmitt, esse foi o retorno…

Resultado da Validação do Schema e Conferência da Assinatura: 

PARSER XML: OK 
TIPO DE MENSAGEM: Lote NF-e 
SCHEMA: OK 
ASSINATURA XML: 
   Validando NOTA #1 do Lote NF-e: Assinatura ***INVÁLIDA*** 
   Validando NOTA #2 do Lote NF-e: Assinatura ***INVÁLIDA*** 
   Validando NOTA #3 do Lote NF-e: Assinatura ***INVÁLIDA*** 
   Validando NOTA #4 do Lote NF-e: Assinatura ***INVÁLIDA*** 
   Validando NOTA #5 do Lote NF-e: Assinatura ***INVÁLIDA*** 
   Validando NOTA #6 do Lote NF-e: Assinatura ***INVÁLIDA*** 
   Validando NOTA #7 do Lote NF-e: Assinatura ***INVÁLIDA*** 
   Validando NOTA #8 do Lote NF-e: Assinatura ***INVÁLIDA*** 
   Validando NOTA #9 do Lote NF-e: Assinatura ***INVÁLIDA*** 
   Validando NOTA #10 do Lote NF-e: Assinatura ***INVÁLIDA*** 
   Validando NOTA #11 do Lote NF-e: Assinatura ***INVÁLIDA***

para transmitir vai tranquilo…
o problema é a assinatura mesmo… pior que agora não tenho nem ideia do que pode ser…
o seu assinador vc fez com base nos códigos ja postados aqui no forum?

A

philler:
alves.Felipe:
ola
estou tendo problemas com a assinatura da nfe. (estou usando o codigo daqui http://www.guj.com.br/posts/list/30/83758.java)
eu envio o xml de lote vai tranquilo,ai qdo vou consultar
me retorma a seguinte msg: “Rejeição: Certificado Assinatura inválido”. estou consumindo o ws do PR
Agora eu queria saber… eu estou usando o certificado .pfx para fazer essa assinatura.
Tenho que fazer alguma coisa a mais com o certificado? apenas com o pfx da para fazer a assinatura normalmente??

abraço

Tive este problema e era espacos entre palavras, tipo assim: “palavra palavra”.
O problema é os dois espacos (ou mais) entre palavras. Só pode ter um.

Alencar

vou verificar isso tb…
mas como o f-schmitt disse para eu testar no sefaz / rs… e me retorno aquela msg… sera que ainda assim pode ser os espaços em branco?!

valeo

F

é, seu assinador está com problemas

poste seu xml ou me manda no email

nao, desenvolvi o assinardor aqui…

F

eu estou trabalhando com 1 nfe por lote, mto mais simples de controlar e não há vantagem nenhuma em fazer varias notas por lote…

P

Discordo do amigo. O lote é uma ferramenta muito valiosa quando se trata de faturamento
antecipado ao embarque (programado).
Vejamos: o faturista tem 20 pedidos para embarque as 15h.
Emite todas as notas no ERP e gera apenas um lote com todas elas.
Recebe apenas um retorno do lote e emite apenas uma vez todas as DANFES.

Vejam que, quando menciono “apenas uma vez” quero dizer em um só comando e nao
um comando por nota do lote. Isso é ganho de tempo com certeza.

Alencar

F

nesse cado voce coloca seu erp aos moldes da nfe, mas no nosso caso temos a carga que faz exatamente o que voce explicou…

e se uma dessas 20 notas for denegada ou algo errado, acho (claro que é minha opiniao) controlar o envio e o retorno de cada lote…

A

no meu caso não fica muito viavel criar um lote por nf…
philler, eu até achei uma String que tinha 2 espaços em branco… mas não é isso o problema não…

f-schmitt, tem mandei o xml e meu assinador por email… blz…

A

o problema que eu estava tendo é que depois de assinar o xml eu o gravava , e nessa hora eu alterava o xml… por isso
ficava errado a assinatura…
agora eu gravo eu não altero nada. mas antes de gravar eu transformo o Document para string e consumo o WS…
e agora foi… :slight_smile:

mas valeo pela força f-schmitt e philler …

F

Aproveitando o topico aqui, bom aqui estou eu tentando assinar uma NFe, peguei uns codigo aqui do forum, mexi pouca coisa só pra fazer um teste e to recebendo um erro:

javax.xml.crypto.dsig.XMLSignatureException: javax.xml.crypto.URIReferenceException: java.lang.NullPointerException
        at org.jcp.xml.dsig.internal.dom.DOMReference.dereference(DOMReference.java:352)
        at org.jcp.xml.dsig.internal.dom.DOMReference.digest(DOMReference.java:278)
        at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.digestReference(DOMXMLSignature.java:447)
        at org.jcp.xml.dsig.internal.dom.DOMXMLSignature.sign(DOMXMLSignature.java:343)

O erro acontece nesta linha:

DOMSignContext dsc = new DOMSignContext(privateKey, doc.getDocumentElement().getElementsByTagName("NFe").item(i));
        signature.sign(dsc);  //<=== Erro acontece nesta linha

e Eis todo o codigo que peguei aqui mesmo no GUJ.

public static String assinarEnviNFe(String xml, String certificado, String keyStorePass) throws Exception {
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        // Document docs = builder.parse(new File(
        // "c:/xml/430802017886010001735500000000010000030371-nfe.xml"));
        Document doc = factory.newDocumentBuilder().parse(
                new ByteArrayInputStream(xml.getBytes()));

        // Create a DOM XMLSignatureFactory that will be used to
        // generate the enveloped signature.
        XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");

        // Create a Reference to the enveloped document (in this case,
        // you are signing the whole document, so a URI of "" signifies
        // that, and also specify the SHA1 digest algorithm and
        // the ENVELOPED Transform.
        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);

        // Load the KeyStore and get the signing key and certificate.
        KeyStore ks = KeyStore.getInstance("PKCS12");     //MUDEI AQUI PRA PEGAR DIRETO O PFX
        FileInputStream fis = new FileInputStream(certificado);
        //load the keystore
        ks.load(fis, keyStorePass.toCharArray());
        String alias = ks.aliases().nextElement();

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

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

        // Create the KeyInfo containing the X509Data.
        KeyInfoFactory kif = fac.getKeyInfoFactory();
        List<Serializable> x509Content = new ArrayList<Serializable>();
        x509Content.add(cert.getSubjectX500Principal().getName());
        x509Content.add(cert);
        X509Data xd = kif.newX509Data(x509Content);
        KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

        for (int i = 0; i < doc.getDocumentElement().getElementsByTagName("NFe").getLength(); i++) {
            assinarNFE(fac, transformList, keyEntry.getPrivateKey(), ki, doc, i);
        }
        // Output the resulting document.
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer trans = tf.newTransformer();
        trans.transform(new DOMSource(doc), new StreamResult(os));
        return os.toString();
    }

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

        // Obtem elemento do documento a ser assinado, será criado uma
        // REFERENCE para o mesmo
        NodeList elements = doc.getElementsByTagName("infNFe");
        Element el = (Element) elements.item(i);
        String id = el.getAttribute("Id");

        // doc.getDocumentElement().removeAttribute("xmlns:ns2");
        // ((Element)
        // doc.getDocumentElement().getElementsByTagName("NFe").item(0))
        // .setAttribute("xmlns", "http://www.portalfiscal.inf.br/nfe");

        // Create a DOM XMLSignatureFactory that will be used to
        // generate the enveloped signature.

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

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

        // Create the XMLSignature, but don't sign it yet.
        XMLSignature signature = fac.newXMLSignature(si, ki);

        // Marshal, generate, and sign the enveloped signature.
        // Create a DOMSignContext and specify the RSA PrivateKey and
        // location of the resulting XMLSignature's parent element.
        DOMSignContext dsc = new DOMSignContext(privateKey, doc.getDocumentElement().getElementsByTagName("NFe").item(i));
        signature.sign(dsc);

    }

Uma coisa que mudei foi pegar direto o PFX, ao inves do JKS, to tentando fazer assim, sem criar JKS, seguindo o que o thingol disse aqui: http://www.guj.com.br/posts/list/15/87934.java

To meio perdido aqui com essa assinatura, alguem passou por isso?

F

olá, no seu XML tem um node chamado ?

P

Fred, pareceu-me que o seu problema esta na montagem do ID da tag:

Note que em <infNFe Id=… tem a String “NFe” seguida da chave de acesso da NFe.
É esta tag que o processo de assinatura busca para assinar o xml da nota.
javax.xml.crypto.URIReferenceException deu a entender que nao encontrou a tag com
o Id especificado neste trecho de codigo:

String id = el.getAttribute(“Id”);

Ou entao esta faltando o caracter “#” aqui (erro mais provavel):

Reference ref = fac.newReference("#" + id, fac.newDigestMethod(

DigestMethod.SHA1, null), transformList, null, null);

Alencar

F

Pior é que tem.

<?xml version="1.0" encoding="utf-8" ?> 
- <enviNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.10">
  <idLote>1</idLote> 
- <NFe xmlns="http://www.portalfiscal.inf.br/nfe">
- <infNFe xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Id="NFexxxxxxxxxx..." versao="1.10">
- <ide>

Só falta assinar pra mim concluir aqui.

F

philler:
Fred, pareceu-me que o seu problema esta na montagem do ID da tag:

Note que em <infNFe Id=… tem a String “NFe” seguida da chave de acesso da NFe.
É esta tag que o processo de assinatura busca para assinar o xml da nota.
javax.xml.crypto.URIReferenceException deu a entender que nao encontrou a tag com
o Id especificado neste trecho de codigo:

String id = el.getAttribute(“Id”);

Ou entao esta faltando o caracter “#” aqui (erro mais provavel):

Reference ref = fac.newReference("#" + id, fac.newDigestMethod(

DigestMethod.SHA1, null), transformList, null, null);

Alencar

BINGOOO!! Era o # faltando mesmo, coloquei e assinou na hora!! Valeu mesmo, estes errinhos podem nos tomar dias de trabalho.

Mas o que seria o # afinal? É que realmente nao tive tempo pra estudar a coisa a fundo e entender o que cada coisa faz, é um projeto pessoal e só tenho tempo de fazer a noite, e o prazo é pra ontem como dizem.

Bom agora vou validar la no site do rs pra ver se assinou legal hehe, Valeu ae galera pela força.

D

Pessoal,

alguém está trabalhando com o token ePass2000? Como eu configuro o arquivo .cfg pra esse token? Qual a dll que eu uso?

Obrigado a todos!

Daniel

A

dae galera…
minha situação é a seguinte: no ws do PR eu consigo conectar normalmente…apenas seto o meu certificado e o certificado que baixei da sefaz-pr e pronto…

agora estou tentando consultar o status do serviço do ws de contingência da receita… mas não consigo conectar… recebo a seguinte msg:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

ja tentei entrar em contato com o pessoal da receita ja faz 2 semanas e até agora não tive nenhuma resposta…

gostaria de saber se, assim como no ws do pr eu precisei baixar os certificados deles , eu preciso baixar algum certificado da receita para conseguir conectar…?? oq preciso fazer para conectar??

valeo
abraco

P

Deve estar faltando a cadeia de certificados para validar o certificado do
servidor da Receita.
No ws do Parana deu certo pois o teu certificado foi expedido pela mesma
entidade certificadora.

A

Era bem isso philler… eu que estava marcando…

agora eu consigo conectar no sefaz-pr e no SCAN , masss…
se rodando o programa eu tentar conectar nos 2…por ex. consultar 1º o status no SCAN e depois de pegar o retorno, setar os certificados do Sefaz-pr e fazer a consulta de status tb…na 2º consulta me retorna a mesma msg:

Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
acontece isso só qdo é para servidores diferentes…
eu só consigo consultar um de cada vez… rodar o programa, consultar um, ai finaliza o programa, ai rodo de volta e só ai consulta o outro…
entendem??
tem algum problema de setar

depois limpar

System.clearProperty("javax.net.ssl.trustStoreType");...
e setar novamente o certificado??

P

Nao sei te afirmar. Mas como é variavel de ambiente, creio que se voce setar
atraves de arquivos de configuracao, hora um hora outro, nao vai ter galho.
Com isso voce nao precisa fechar e reabrir o prg todo.
Reseta a variavel e instancia a classe novamente.

A

cara… não querendo abusar… hehe…mas da uma olhada como é minha classe q seta os certificados…

public void setPropertySefaz(int codFilial,int tipoEmissao,String caminhoCertificado)
	{
		System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");   
		Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());   

		if(System.getProperty("javax.net.ssl.keyStoreType")==null)
		{
			System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");   
			System.setProperty("javax.net.ssl.keyStore",caminhoCertificado+"certificado-mili-nfe.pfx");//Aqui vem o arquivo do certificado do seu cliente
			System.setProperty("javax.net.ssl.keyStorePassword", "x");//Aqui a senha deste certificado   
		}
		
               System.setProperty("javax.net.ssl.trustStoreType", "JKS");   
		System.setProperty("javax.net.ssl.trustStore", caminhoCertificado+"nfehomologado.keystore");//
		System.setProperty("javax.net.ssl.keyStorePassword", "x");//Aqui a senha deste certificado
}

isso que vc falou não é a mesma coisa que eu estou fazendo né? tem como passar um exemplo?

valewss

P

É a mesma coisa.
Do teu jeito nao funcionou?

A

ixe cara… ja vi que estou com problemas…
desse jeito funciona, mas só se eu não setar 2x…se não for para estados diferentes… entende?!
e pensando aqui…sera que não vai ter como 2 usuários, que emitem nfe para diferentes estados (por ex. pr e al), usarem a aplicação?
estou fazendo a aplicação web… mas vai ter gente do PR,AL e SC usando… to f…hehe
ninguém tem ai algumas sugestões?!?

P

O teu problema esta só no trustStore?
Se sim, porque voce nao coloca todos os certificados em um só JKS?

Se nao, eu é que nao entendi…

A

é isso mesmo… só no trustStore…

Se sim, porque voce nao coloca todos os certificados em um só JKS?

sabia que eu não tinha pensado nisso!!! hehe…
vou tentar jogar tudo num só keystore…
valeo de novo

A

po… batata … funcionou de primeira… haha…

nem preciso fazer todos aqueles ifs que tinha mostrado antes…
vou até tirar o codigo para ninguem querer copiar… heh

valeo…
abraco

E

Olá pessoal…

Sou desenvolvedora Java e C# e gostaria de divulgar a solução Open Source da minha empresa pra Nota Fiscal eletrônica.
Essa solução foi desenvolvida em C#, mas acredito que, como o C# é muito parecido com o Java (uma cópia, pra falar a verdade, hehe) irá ajudar quem estiver interessado em estudar ou até desenvolver uma solução Java pra nota fiscal eletrônica.

Segue o link para maiores informações: www.uninfe.com.br

Bom estudo para todos.

P

Pessoal, estou com dificuldades em extrair o CNPJ do certificado que assinou o xml.
Sei que a receita faz isso, pois eles testam se o CNPJ base do certificado é o mesmo
do CNPJ base do emitente.

Alguns certificados vem com o CNPJ logo apos o nome da empresa, por exemplo:
CN=ALGUMA EMPRESA LTDA:01001001000101

Nestes casos é só pegar o getNomeCertificado() e sacar o cnpj.
Mas tenho visto casos em que o CN nao vem com este valor.

Alguma luz por ai? De onde a SEFAZ tira a informacao?

Alencar

A

cara… ve se a resposta do thingol te ajuda nesse tópico ai

http://www.guj.com.br/posts/list/126975.java

M

Galera muito boa tarde!

HELP-ME :?

Não estou conseguindo validar a assinatura do xml em alguma notas e as mesmas são geradas no mesmo sistema.
Não consigo achar o erro alguém pode me ajudar?[color=darkblue] [/color]

P

Marilice:
Galera muito boa tarde!

HELP-ME :?

Não estou conseguindo validar a assinatura do xml em alguma notas e as mesmas são geradas no mesmo sistema.
Não consigo achar o erro alguém pode me ajudar?[color=darkblue] [/color]

Pode nos informar quais as msgs de erro?
Uma dica que ja posso lhe adiantar: Se tiver dois espacos entre palavras nao valida.
Ex.: “Rua Treze…”. Entre Rua e Treze tem dois espacos. Isso ocorre com muita frequencia en descricao de produtos
e observacoes.

Se nao for isso, manda as msgs de erro.

Alencar

M

Segue a mensagem

PARSER XML: OK
TIPO DE MENSAGEM: Distribuição da NF-e processada
SCHEMA: OK
ASSINATURA XML: Assinatura INVÁLIDA

P

Marilice:
Segue a mensagem

PARSER XML: OK
TIPO DE MENSAGEM: Distribuição da NF-e processada
SCHEMA: OK
ASSINATURA XML: Assinatura INVÁLIDA

Humm, assim fica dificil :slight_smile:

Por favor, envie um xml por aqui mesmo, assinado com erro.
Analiso ele para voce.

Alencar

M

Alencar

Obrigada por sua ajuda.

M

Alencar bom dia!

Aqui estou eu novamente, fiz as alterações conformE vc havia me orientado mas mesmo assim continua com o erro"ASSINATURA INVÁLIDA"

HELP-ME PLEASE

D

Cola o xml gerado pra gente ver e poder ajudar…

M

Vide mp

P

Marilice:
Alencar bom dia!

Aqui estou eu novamente, fiz as alterações conformE vc havia me orientado mas mesmo assim continua com o erro"ASSINATURA INVÁLIDA"

HELP-ME PLEASE

Manda novamente por email.
Desculpe a demora em responder. Por vezes nao estou online.

ALencar

M

Alencar muito bom dia!

Imagina ja agradeço pela atenção que todos me deram neste forum, mas cosegui resolver e gostaria de deixar a solução.

O problema estava na hora que gerava o xml a codificação estava como ANSI e o padrão é UTF-8, fiz o seguinte

Abri o arquivo xml no bloco de notas
Pedir para salvar como
Modifique a codificação de ANSI para UTF 8
Substitui o arquivo e pronto
Entrei no site sefaz rs
Assinatura válida

Um abraço a todos

A

eae camaradas, eu denovo, agora descobri que minha assinatura ta faltando uma tag, se alguem puder me ajudar agradeço, na validação acusa que falta a seguinte tag essa que coloco em negrito, essa realmente não consta na minha assinatura, mas sim nos xml nf-e de exemplo dareceita

abaixo lanço o cod. que uso pra assianr, saiu daqui mesmo do guj, são 2 classes obrigado.

package nfe.signature;

	import java.io.FileInputStream;
	import java.io.FileNotFoundException;
	import java.io.FileOutputStream;
	import java.io.IOException;
	import java.io.InputStream;
	import java.io.OutputStream;
	import java.security.KeyStore;
	import java.security.KeyStoreException;
	import java.security.NoSuchAlgorithmException;
	import java.security.PrivateKey;
	import java.security.UnrecoverableEntryException;
	import java.security.cert.CertificateException;
	import java.security.cert.X509Certificate;
	import java.util.ArrayList;
	import java.util.Collections;
	import java.util.Enumeration;
	import java.util.Iterator;

	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.DocumentBuilderFactory;
	import javax.xml.parsers.ParserConfigurationException;
	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.NodeList;
	import org.xml.sax.SAXException;


	public class AssinaXML {
		
		public static String keyStoreP12 = "PKCS12";
		public static String keyStoreJKS = "JKS";
		
		public static Reference ref = null;
		public static SignedInfo si = null;
		public static XMLSignature signature = null;
		public static DOMSignContext dsc = null;
		
		private String certificadoArquivo = "";
		private String certificadoSenha = "";
		private String arquivoEntrada = "";
		private String arquivoSaida = "";
		private String keyStore = "";
		
		public AssinaXML(String arquivoCertificado, String senhaCertificado,
				String arquivoEntradaXML, String arquivoSaidaXML, String keyStore){
			this.certificadoArquivo = arquivoCertificado;
			this.certificadoSenha = senhaCertificado;
			this.arquivoEntrada = arquivoEntradaXML;
			this.arquivoSaida = arquivoSaidaXML;
			this.keyStore = keyStore;
		}
			
		public static XMLSignature getSignature() {
			return signature;
		}

		public static void setSignature(XMLSignature signature) {
			AssinaXML.signature = signature;
		}

		public String getCertificadoArquivo() {
			return certificadoArquivo;
		}

		public void setCertificadoArquivo(String certificadoArquivo) {
			this.certificadoArquivo = certificadoArquivo;
		}

		public String getCertificadoSenha() {
			return certificadoSenha;
		}

		public void setCertificadoSenha(String certificadoSenha) {
			this.certificadoSenha = certificadoSenha;
		}

		public String getArquivoEntrada() {
			return arquivoEntrada;
		}

		public void setArquivoEntrada(String arquivoEntrada) {
			this.arquivoEntrada = arquivoEntrada;
		}

		public String getArquivoSaida() {
			return arquivoSaida;
		}

		public void setArquivoSaida(String arquivoSaida) {
			this.arquivoSaida = arquivoSaida;
		}
		
		public String getKeyStore() {
			return keyStore;
		}

		public void setKeyStore(String keyStore) {
			this.keyStore = keyStore;
		}

		@SuppressWarnings("unchecked")
		public void colocaCertificado(){
			XMLSignatureFactory fac = XMLSignatureFactory.getInstance("DOM");
			try {
				
				KeyStore ks = KeyStore.getInstance(getKeyStore());
				ks.load(new FileInputStream(getCertificadoArquivo()), getCertificadoSenha().toCharArray());			
				KeyStore.PrivateKeyEntry keyEntry = null;
				
				for(Enumeration e = ks.aliases(); e.hasMoreElements();){ 
					keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry((String) e.nextElement(),
								new KeyStore.PasswordProtection(getCertificadoSenha().toCharArray()));
				}
				
				X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
				KeyInfoFactory kif = fac.getKeyInfoFactory();
				ArrayList 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 FileInputStream(getArquivoEntrada()));
				  
				dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc.getDocumentElement());
				  	  
		        assinatura(fac, x509Content, keyEntry.getPrivateKey(), ki, doc);
				 
		        OutputStream os = new FileOutputStream(getArquivoSaida());
		          TransformerFactory tf = TransformerFactory.newInstance();
		          Transformer trans = tf.newTransformer();
		          trans.transform(new DOMSource(doc), new StreamResult(os));
				    
		          NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
				            		  
				  if (nl.getLength() == 0){
				     throw new Exception("Nao encontrou elemento (TAG) Signature!!!");
		          }

		          DOMValidateContext valContext = new DOMValidateContext(new X509KeySelector(), nl.item(0));
		          
		          XMLSignature signature1 = fac.unmarshalXMLSignature(valContext);

		          boolean coreValidity = signature1.validate(valContext);
				  
		          if (coreValidity == false) {
		             System.err.println("Signature failed core validation");
		             boolean sv = signature.getSignatureValue().validate(valContext);
		             System.out.println("signature validation status: " + sv);
		             if (sv == false) {
		                Iterator i = signature.getSignedInfo().getReferences().iterator();
		                for (int j=0; i.hasNext(); j++) {
		                    boolean refValid = ((Reference) i.next()).validate(valContext);
		                    System.out.println("ref["+j+"] validity status: " + refValid);
		                }
		             }
		          }
				  else {
		             System.out.println("Signature passed core validation");
		          }
				  
				  valContext.setProperty("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
				  XMLSignature signaturex = fac.unmarshalXMLSignature(valContext);
				  @SuppressWarnings("unused")
				boolean coreValidityx = signaturex.validate(valContext);
					
		          Iterator i = signature.getSignedInfo().getReferences().iterator();
				  for (int j=0; i.hasNext(); j++) {
					  @SuppressWarnings("unused")
					InputStream is = ((Reference) i.next()).getDigestInputStream();
				  }
				  
			} catch (KeyStoreException e) {				
				e.printStackTrace();
			} catch (NoSuchAlgorithmException e) {
				e.printStackTrace();
			} catch (CertificateException e) {
				e.printStackTrace();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			} catch (UnrecoverableEntryException e) {
				e.printStackTrace();
			} catch (SAXException e) {
				e.printStackTrace();
			} catch (ParserConfigurationException e) {
				e.printStackTrace();
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
		
		@SuppressWarnings("unchecked")
		private static void assinatura(XMLSignatureFactory fac,
	            ArrayList transformList,
	            PrivateKey privateKey,
	            KeyInfo ki,
	            Document doc
			    ) throws Exception {

			NodeList elements = doc.getElementsByTagName("infNFe");
			Element el = (org.w3c.dom.Element) elements.item(0);
			String id = el.getAttribute("Id");

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

			si = fac.newSignedInfo(fac.newCanonicalizationMethod(
	        CanonicalizationMethod.INCLUSIVE,
	       (C14NMethodParameterSpec) null),
		     fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
			     Collections.singletonList(ref));
			 
			DOMSignContext dsc = new DOMSignContext(privateKey,doc.getElementsByTagName("NFe").item(0));
			signature = fac.newXMLSignature(si, ki);
			signature.sign(dsc);
	}
		
		
		public static void main(String[] args) {
			AssinaXML ax3 = new AssinaXML("src/nfe/resources/Associacao.pfx", "associacao", 
					"src/nfe/resources/NF-e.xml",
					"src/nfe/resources/assinadas/NF-e.xml", AssinaXML.keyStoreP12);
			ax3.colocaCertificado();
		}

	}
package nfe.signature;

import java.security.Key;
import java.security.PublicKey;
import java.security.cert.X509Certificate;
import java.util.Iterator;

import javax.xml.crypto.AlgorithmMethod;
import javax.xml.crypto.KeySelector;
import javax.xml.crypto.KeySelectorException;
import javax.xml.crypto.KeySelectorResult;
import javax.xml.crypto.XMLCryptoContext;
import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.X509Data;

public class X509KeySelector extends KeySelector {
    
	@SuppressWarnings("unchecked")
	public KeySelectorResult select(KeyInfo keyInfo,
                                    KeySelector.Purpose purpose,
                                    AlgorithmMethod method,
                                    XMLCryptoContext context)
        throws KeySelectorException {
        Iterator ki = keyInfo.getContent().iterator();
        while (ki.hasNext()) {
            XMLStructure info = (XMLStructure) ki.next();
            if (!(info instanceof X509Data))
                continue;
            X509Data x509Data = (X509Data) info;
            Iterator xi = x509Data.getContent().iterator();
            while (xi.hasNext()) {
                Object o = xi.next();
                if (!(o instanceof X509Certificate))
                    continue;
                final PublicKey key = ((X509Certificate)o).getPublicKey();
                // Make sure the algorithm is compatible
                // with the method.
                if (algEquals(method.getAlgorithm(), key.getAlgorithm())) {
                    return new KeySelectorResult() {
                        public Key getKey() { return key; }
                    };
                }
            }
        }
        throw new KeySelectorException("No key found!");
    }

    static boolean algEquals(String algURI, String algName) {
        if ((algName.equalsIgnoreCase("DSA") &&
            algURI.equalsIgnoreCase(SignatureMethod.DSA_SHA1)) ||
            (algName.equalsIgnoreCase("RSA") &&
            algURI.equalsIgnoreCase(SignatureMethod.RSA_SHA1))) {
            return true;
        } else {
            return false;
        }
    }
}
P

Olha ai a parte do meu codigo que inclui as transformacoes exigidas:

// C14N_TRANSFORM_METHOD
			String C14N_TRANSFORM_METHOD = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
			// Cria a lista de tranformações a serem aplicadas as referencias a
			// serem assinadas
			ArrayList transforms = new ArrayList();
			TransformParameterSpec tps = null;
			Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED, tps);
			Transform c14NTransform = fac.newTransform(C14N_TRANSFORM_METHOD, tps);
			transforms.add(envelopedTransform);
			transforms.add(c14NTransform);

			// cria uma referencia ao envelope e define o algoritmo SHA1
			Reference ref = fac.newReference(URI, fac.newDigestMethod(
			    DigestMethod.SHA1, null), transforms, null, null);

Alencar

A

alves.Felipe:
o problema que eu estava tendo é que depois de assinar o xml eu o gravava , e nessa hora eu alterava o xml… por isso
ficava errado a assinatura…
agora eu gravo eu não altero nada. mas antes de gravar eu transformo o Document para string e consumo o WS…
e agora foi… :slight_smile:

mas valeo pela força f-schmitt e philler …

pode me explicar isso melhor manu, porque eu to com o mesmo rolo, se puder ajudar agradeço, abraços.

Validando NOTA #1 do Lote NF-e: Assinatura INVÁLIDA

P

Apos o processo de assinatura, uso as linhas de cmd abaixo para transformar o Document em String:

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

onde “doc” é o Document tratado.

E depois assim para salvar em disco:

public static boolean saveFile(String arqSaida, String conteudo) throws IOException {
		File file = new File(arqSaida);
		if (file.exists())
			file.delete();
		
		FileWriter fw = new FileWriter(file);
		fw.write(conteudo);
		fw.flush();
		fw.close();
		
		return true;
	}
G

Estou com o seguinte erro ao tentar assinar o xml:

java.lang.NullPointerException: signingKey cannot be null
        at javax.xml.crypto.dsig.dom.DOMSignContext.<init>(DOMSignContext.java:53)
        at br.com.peoplesolutions.nfeservice.assinador.TratadorCertificado.assinarDocumento(TratadorCertificado.java:151)
        at br.com.peoplesolutions.nfeservice.assinador.TratadorCertificado.main(TratadorCertificado.java:165)

Minha classe está assim:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.peoplesolutions.nfeservice.assinador;

/**
 *
 * @author Gilmar
 */
import java.security.*;
import java.security.Certificate;
import java.security.cert.*;
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.*;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class TratadorCertificado {
    /*
     * 	Classe para tratamento de certificados. Deve fazer a manipulacao
     * dos certificados exportando chaves, assinando XML's e demais funcoes.
     *
     */

    public static final String algoritmo = "RSA";
    public static final String algoritmoAssinatura = "MD5withRSA";
    private static final String C14N_TRANSFORM_METHOD = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
    public static File file = new File("c:\\meuKeystore.jks");
    private static String alias = "meuAlias";
    private static char[] senha = "senhaKeystore".toCharArray();
    static XMLSignatureFactory sig;
    static X509Certificate cert;
    static KeyInfo ki;
    static SignedInfo si;
    static KeyStore rep;

    public static PrivateKey getChavePrivada() throws Exception {
        
        InputStream entrada = new FileInputStream(file);
        rep.load(entrada, senha);
        entrada.close();
        Key chavePrivada = (Key) rep.getKey(alias, senha);


        if (chavePrivada instanceof PrivateKey) {
        System.out.println("Chave Privada encontrada!");
        return (PrivateKey) chavePrivada;
        } else {
        System.out.println("NULL");
        return null;  // Está retornando null
        }
        
        
    }

    public static PublicKey getChavePublica() throws Exception {

        InputStream entrada = new FileInputStream(file);
        rep.load(entrada, senha);
        entrada.close();
        Key chave = (Key) rep.getKey(alias, senha);
        java.security.Certificate cert = (java.security.Certificate) rep.getCertificate(alias);//O tipo de dado é declarado desse modo por haver ambigüidade (Classes assinadas com o mesmo nome "Certificate")
        PublicKey chavePublica = cert.getPublicKey();
        System.out.println("Chave Pública encontrada!");
        return chavePublica;





    }

    public static boolean verificarAssinatura(PublicKey chave, byte[] buffer, byte[] assinado) throws Exception {

        Signature assinatura = Signature.getInstance(algoritmoAssinatura);
        assinatura.initVerify(chave);
        assinatura.update(buffer, 0, buffer.length);
        return assinatura.verify(assinado);
    }

    public static byte[] criarAssinatura(PrivateKey chavePrivada, byte[] buffer) throws Exception {

        Signature assinatura = Signature.getInstance(algoritmoAssinatura);
        assinatura.initSign(chavePrivada);
        assinatura.update(buffer, 0, buffer.length);
        return assinatura.sign();
    }

    public static String getValidade(X509Certificate cert) {
        try {
            cert.checkValidity();
            return "Certificado válido!";
        } catch (CertificateExpiredException e) {
            return "Certificado expirado!";
        } catch (CertificateNotYetValidException e) {
            return "Certificado inválido!";
        }
    }

    public static void getCertificado() throws Exception {
        InputStream dado = new FileInputStream(file);
        rep = KeyStore.getInstance("JKS");
        rep.load(dado, senha);
        cert = (X509Certificate) rep.getCertificate(alias);
        String retorno = TratadorCertificado.getValidade(cert);
        System.out.println(retorno);
    }

    public static void assinarDocumento(String localDocumento) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(localDocumento));
        System.out.println("Documento ok!");

        sig = XMLSignatureFactory.getInstance("DOM");

        ArrayList<Transform> transformList = new ArrayList<Transform>();
        Transform enveloped = sig.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
        Transform c14n = sig.newTransform(C14N_TRANSFORM_METHOD, (TransformParameterSpec) null);
        transformList.add(enveloped);
        transformList.add(c14n);

        NodeList elements = doc.getElementsByTagName("infNFe");
        org.w3c.dom.Element el = (org.w3c.dom.Element) elements.item(0);
        String id = el.getAttribute("Id");
        Reference r = sig.newReference("#".concat(id), sig.newDigestMethod(DigestMethod.SHA1, null),
                transformList,
                null, null);
        si = sig.newSignedInfo(
                sig.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
                (C14NMethodParameterSpec) null),
                sig.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
                Collections.singletonList(r));

        KeyInfoFactory kif = sig.getKeyInfoFactory();
        List x509Content = new ArrayList();
        x509Content.add(cert);
        X509Data xd = kif.newX509Data(x509Content);
        ki = kif.newKeyInfo(Collections.singletonList(xd));

        DOMSignContext dsc = new DOMSignContext(getChavePrivada(), doc.getDocumentElement());
        XMLSignature signature = sig.newXMLSignature(si, ki);
        signature.sign(dsc);
        OutputStream os = new FileOutputStream("assinado.xml");
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer trans = tf.newTransformer();
        trans.transform(new DOMSource(doc), new StreamResult(os));

    }

    public static void main(String[] args) {

        try {
            TratadorCertificado.getCertificado();
            TratadorCertificado.assinarDocumento("C:\\Documents and Settings\\Gilmar\\Desktop\\35090850559251000189550010000000010004001100-nfe.xml");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

Meu certificado é do tipo .pfx

Estou usando essa ferramenta para criar o keystore http://yellowcat1.free.fr/index_ktl.html

Não sei se estou fazendo certo.
Tentei pela linha de comando e também não deu certo

P

Verifique se esta linha esta sendo executada:

System.out.println(“Chave Privada encontrada!”);

Pelo que entendi, vc esta tendo problemas em ler o jks.

Alencar

G

Consegui resolver de uma forma mais fácil graças a esses post do thingol http://www.guj.com.br/posts/list/15/87934.java

Usei o comando: keytool -list -storetype pkcs12 -keystore “Nfe emissor.pfx” e peguei o alias do meu .pfx

E mudei o método que pega a chave privada.

Ficou assim:

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.peoplesolutions.nfeservice.assinador;

/**
 *
 * @author Gilmar
 */
import java.security.*;
import java.security.Certificate;
import java.security.cert.*;
import java.io.*;
import java.util.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.keyinfo.*;
import javax.xml.crypto.dsig.spec.*;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class TratadorCertificado {
    /*
     * 	Classe para tratamento de certificados. Deve fazer a manipulacao
     * dos certificados exportando chaves, assinando XML's e demais funcoes.
     *
     */

    public static final String algoritmo = "RSA";
    public static final String algoritmoAssinatura = "MD5withRSA";
    private static final String C14N_TRANSFORM_METHOD = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
    public static File file = new File("c:\\NFe emissao.pfx");
    private static String alias = "7329c51b033a11c43842c2768e4974ea_9781a9e3-5b38-48a9-a28d-6443bfbf0f03"; // Esse foi o alias retornado pelo comando
    private static char[] senha = "senha_do_meu_arquivo.pfx".toCharArray();
    static XMLSignatureFactory sig;
    static X509Certificate cert;
    static KeyInfo ki;
    static SignedInfo si;
    static KeyStore rep;

    public static PrivateKey getChavePrivada() throws Exception {
        /*
        InputStream entrada = new FileInputStream(file);
        rep.load(entrada, senha);
        entrada.close();
        Key chavePrivada = (Key) rep.getKey(alias, senha);


        if (chavePrivada instanceof PrivateKey) {
        System.out.println("Chave Privada encontrada!");
        return (PrivateKey) chavePrivada;
        } else {
        System.out.println("NULLLLLLLL");
        return null;
        }
         */
        KeyStore ks = KeyStore.getInstance("PKCS12");
        FileInputStream fis = new FileInputStream(file);

//load the keystore
        ks.load(fis, senha);

//get the private key for signing.
        PrivateKey privateKey = (PrivateKey) ks.getKey(alias, senha);

        return privateKey;
    }

    public static PublicKey getChavePublica() throws Exception {
        KeyStore ks = KeyStore.getInstance("PKCS12");
        FileInputStream fis = new FileInputStream(file);

        //InputStream entrada = new FileInputStream(file);
        rep.load(fis, senha);
        fis.close();
        Key chave = (Key) rep.getKey(alias, senha);
        java.security.Certificate cert = (java.security.Certificate) rep.getCertificate(alias);//O tipo de dado é declarado desse modo por haver ambigüidade (Classes assinadas com o mesmo nome "Certificate")
        PublicKey chavePublica = cert.getPublicKey();
        System.out.println("Chave Pública encontrada!");
        return chavePublica;





    }

    public static boolean verificarAssinatura(PublicKey chave, byte[] buffer, byte[] assinado) throws Exception {

        Signature assinatura = Signature.getInstance(algoritmoAssinatura);
        assinatura.initVerify(chave);
        assinatura.update(buffer, 0, buffer.length);
        return assinatura.verify(assinado);
    }

    public static byte[] criarAssinatura(PrivateKey chavePrivada, byte[] buffer) throws Exception {

        Signature assinatura = Signature.getInstance(algoritmoAssinatura);
        assinatura.initSign(chavePrivada);
        assinatura.update(buffer, 0, buffer.length);
        return assinatura.sign();
    }

    public static String getValidade(X509Certificate cert) {
        try {
            cert.checkValidity();
            return "Certificado válido!";
        } catch (CertificateExpiredException e) {
            return "Certificado expirado!";
        } catch (CertificateNotYetValidException e) {
            return "Certificado inválido!";
        }
    }

    public static void getCertificado() throws Exception {
        InputStream dado = new FileInputStream(file);
        rep = KeyStore.getInstance("PKCS12");
        rep.load(dado, senha);
        cert = (X509Certificate) rep.getCertificate(alias);
        String retorno = TratadorCertificado.getValidade(cert);
        System.out.println(retorno);
    }

    public static void assinarDocumento(String localDocumento) throws Exception {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(localDocumento));
        System.out.println("Documento ok!");

        sig = XMLSignatureFactory.getInstance("DOM");

        ArrayList<Transform> transformList = new ArrayList<Transform>();
        Transform enveloped = sig.newTransform(Transform.ENVELOPED, (TransformParameterSpec) null);
        Transform c14n = sig.newTransform(C14N_TRANSFORM_METHOD, (TransformParameterSpec) null);
        transformList.add(enveloped);
        transformList.add(c14n);

        NodeList elements = doc.getElementsByTagName("infNFe");
        org.w3c.dom.Element el = (org.w3c.dom.Element) elements.item(0);
        String id = el.getAttribute("Id");
        Reference r = sig.newReference("#".concat(id), sig.newDigestMethod(DigestMethod.SHA1, null),
                transformList,
                null, null);
        si = sig.newSignedInfo(
                sig.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
                (C14NMethodParameterSpec) null),
                sig.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
                Collections.singletonList(r));

        KeyInfoFactory kif = sig.getKeyInfoFactory();
        List x509Content = new ArrayList();
        x509Content.add(cert);
        X509Data xd = kif.newX509Data(x509Content);
        ki = kif.newKeyInfo(Collections.singletonList(xd));

        DOMSignContext dsc = new DOMSignContext(getChavePrivada(), doc.getDocumentElement());
        XMLSignature signature = sig.newXMLSignature(si, ki);
        signature.sign(dsc);
        OutputStream os = new FileOutputStream("assinado.xml");
        TransformerFactory tf = TransformerFactory.newInstance();
        Transformer trans = tf.newTransformer();
        trans.transform(new DOMSource(doc), new StreamResult(os));

    }

    public static void main(String[] args) {

        try {
            TratadorCertificado.getCertificado();
            TratadorCertificado.assinarDocumento("C:\\Documents and Settings\\Gilmar\\Desktop\\35090850559251000189550010000000010004001100-nfe.xml");
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

O melhor de tudo foi que eu não precisei criar nenhum keystore.

Nada como vasculhar o fórum!!!

E

Boa Tarde Pessoal!

Achei que já havia finalizado a NFe, porém apareceu mais um erro que não consigo resolver.
A SEFAZ do Paraná obriga que eu coloque o namespace na tag NFe, como abaixo:

1 (...)

mas quando eu assino meu documento e transformo ele de um objeto Document para um objeto String,
eu estou perdendo este namespace, e o meu documento xml está ficando assim

1 (...)

Alguém sabe o que pod estar acontecendo?

P

Tente assim a saida:

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

Alencar

E

É exatamente assim que eu estou fazendo…

será q não existe uma outra maneira, ou alguma propriedade que seja necessário setar, pois de acordo com a norma da w3c eu não posso ter tags com o mesmo namespace sem um prefixo, já que prefixos não são permitidos segundo o Layout da NFe, deve haver alguma coisa que eu tenho que fazer para poder ter namespaces repetidos, e aí, alguém arrisca?

Att.

Ernani C.S.,
Desenvolvimento - Joinville/SC

P

Opa…

Pessoal estou com problemas em me comunicar com o ws… nao consigo tirar o erro:
unable to find valid certification path to requested target

O procedimento que usei:

  1. Baixei o Associacao.pfx da SEFAZ;
  2. Importei usando o próprio JRE (javaws) e exportei o arquivo Associacao.cer;
  3. pelo keytool adicionei o .cer no CAcerts na pasta security do JRE.
  4. Setei as variaveis do sistema assim:
...
System.setProperty("javax.net.ssl.trustStoreType", "JKS");    
System.setProperty("javax.net.ssl.trustStore", "associa");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");    
System.setProperty("javax.net.ssl.keyStore", "C:\temp\Associacao.pfx");
System.setProperty("javax.net.ssl.keyStorePassword", "associacao");

strRetorno = soapServico.nfeStatusServicoNF(cabecMsg, consStatServ);
...
  1. To com o maledito erro:

Mesmo se tentar chamar os outros métodos do WS, recebo o mesmo erro. Estou usando o eclipse e ele ta configurado para usar o JDK1.5.

Olhei dentro da classe que chama o metodo e o link eh “http://www.portalfiscal.inf.br/nfe/wsdl/NfeStatusServico”… o de vocês esta assim tb ?

Preciso configurar algum certificado do WS na minha máquina ?

Vlw!


Progredi mais um pouco… (eu acho rs)

Acertei o keytool para o certificado (arquivo .cer), mas agora to com o seguinte erro:

Caused by: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty at java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:183) at java.security.cert.PKIXParameters.<init>(PKIXParameters.java:103) at java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:87) at sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:54) ... 30 more

O que errei na hora de setar os parâmetros ?

E

O problema é o certificado.
Você não vai conseguir conectar os servidores da receita federal com este certificado, é necessário um certificado válido. Peça ele aos seus clientes ou compre um e-CNPJ, como fizemos aqui na empresa.

Olhe no site da certisign e dos correios (nos correios é mais barato)… o processo demora em torno de 96 horas, entre a compra do certificado e a autorização de uso.

Informe-se…

Outro problema é relacionado ao trustStore
ele está incorreto

System.setProperty("javax.net.ssl.trustStoreType", "JKS"); System.setProperty("javax.net.ssl.trustStore", "associa"); System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

Pesquise sobre SSL e o que é um trustStore você vai aprender…
procure por isso: montar JKS em java…

Para montar este trustStore JKS é necessário baixar as chaves públicas (.cer) das SEFAZ que você
pretende enviar notas… depois é só colocar tudo neste trustStore.
Este trustStore são os certificado que você vai aceitar, assim como tem no IE (lista de certificado aceitos, quer dizer que aquelas pessoas são confiáveis).

Att.

Ernani C.S.,
Desenvolvimento - Joinville/SC
PPINFO ERP - Sistema Web de Gestão Empresarial
http://www.ppinfo.com.br

P
ernanics:
O problema é o certificado. Você não vai conseguir conectar os servidores da receita federal com este certificado, é necessário um certificado válido. Peça ele aos seus clientes ou compre um e-CNPJ, como fizemos aqui na empresa.

Olhe no site da certisign e dos correios (nos correios é mais barato)... o processo demora em torno de 96 horas, entre a compra do certificado e a autorização de uso.

Informe-se...

Outro problema é relacionado ao trustStore
ele está incorreto

System.setProperty("javax.net.ssl.trustStoreType", "JKS");       
System.setProperty("javax.net.ssl.trustStore", "associa");   
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

Pesquise sobre SSL e o que é um trustStore você vai aprender...
procure por isso: montar JKS em java...

Para montar este trustStore JKS é necessário baixar as chaves públicas (.cer) das SEFAZ que você
pretende enviar notas... depois é só colocar tudo neste trustStore.
Este trustStore são os certificado que você vai aceitar, assim como tem no IE (lista de certificado aceitos, quer dizer que aquelas pessoas são confiáveis).

Att.

Ernani C.S.,
Desenvolvimento - Joinville/SC
PPINFO ERP - Sistema Web de Gestão Empresarial
http://www.ppinfo.com.br

Cara.. vlw as dicas... vou ver isso sim... principalmente a configuração dos .cer.. que preciso deixar de um jeito bem flexivel..
Acho que consegui resolver essa parte... e me deparei com outro problema.. que ai ja acho que o certificado que estou usando nao funciona...

postei minha duvida em outro post [url]http://www.guj.com.br/posts/list/195/72325.java#723150[/url] (são tantos de NFe que nem sei mais em qual postar.. hehe).

Vlw **************************** Mudei o código e agora ta me dando:
Default SSL context init failed: DerInputStream.getLength(): lengthTag=109, too big.
Modifiquei o codigo para:
System.setProperty("javax.net.ssl.trustStoreType", "JKS");    
System.setProperty("javax.net.ssl.trustStore", keystore);
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

System.setProperty("javax.net.ssl.keyStoreType", "PKCS12");    
System.setProperty("javax.net.ssl.keyStore", keystore);
System.setProperty("javax.net.ssl.keyStorePassword", "changeit");

No keystore coloquei os .cer do arquivo SEFAZSP_homologacao.p7b

=/

J

Alguém teria um exemplo do código para geração do XML?

P

Algum colega de MG neste forum?
Se sim, por favor, me mande uma mensagem privada.

Grato

Alencar

F

cara, você pode usar um framework p/ gerar o xml há vários, como o xstream, normalmente voce modela seu xml em um beam, e o frame gera o xml, ajuda bastante

abraço

A

estou usando o código do gilmaslima, (muito obrigado por ter postado, ajudou d+)
com algumas alteraçoes para a nota de BH/MG. O xml tem algumas diferenças mínimas como:

ao invés de infNFe é InfNfse
e o param id é todo em minúsculo.

bem, peguei o alias usando o keytool e rodei o codigo, ok gerou o assinado.xml
porém comparando com a nota de exemplo pela sec. faz. faltou um parâmetro em uma tag no xml

na assinatura gerada ficou assim a tag: <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
e no arq exemplo assim: <Signature xmlns="http://www.w3.org/2000/09/xmldsig#" Id="NfseAssSMF_999999990001911733160024200900000000017"> onde esse num é o id da nota

ainda nao consegui testar se a assinatura vai ser validada, mas já adiantando
alguem tem idéia de como adicionar esse Id na nota?

P

esta parte da assinatura (Id=“NfseAssSMF_999999990001911733160024200900000000017”)
é a URI do xml que vai ser assinado.
Caso vc nao informe a URI, o assinador assina todo o arquivo, o que nao é o caso da NFe.

nota = doc.getDocumentElement().getElementsByTagName("NFe").getLength() > 0;
			if (nota) {
				NodeList elements = doc.getElementsByTagName("infNFe");
				Element el = (Element) elements.item(0);  
				URI = "#" + el.getAttribute("Id");
			}

....

			// cria uma referencia ao envelope e define o algoritmo SHA1
			Reference ref = fac.newReference(URI, fac.newDigestMethod(
			    DigestMethod.SHA1, null), transforms, null, null);

Alencar

A

Quanto a essa parte estou usando a URI sim,
da mesma forma que o código que citei tb usa.

Minha dúvida era quanto a diferença entre o XML de exemplo do municipio e o que eu gerei na assinatura.

Só eu que acho, ou tem mais gente que acha que a nfe é muito mal documentada?
por ex: agora estou estudando como assinar os RPS de BH (que por sinal, novamente difere do padrão proposto)
e não vejo claro onde identificar a URI para assinar o lote de RPS, nesse caso o SHA1 seria então do documento inteiro?

V

andredurao:
Só eu que acho, ou tem mais gente que acha que a nfe é muito mal documentada?
por ex: agora estou estudando como assinar os RPS de BH (que por sinal, novamente difere do padrão proposto)

Realmente tem diferenças, estou com alguns problemas em relação a isso também, mais especificamente no cancelamento
Quando envio o web service retorna a seguinte mensagem de erro: “Arquivo enviado com erro na assinatura.”

Alguém sabe o que é ??

G

Senhores, estou tentando assinar a NFe e estou tendo problemas.
Para efeito de testes, peguei o xml gerado e assinei pelo assinador disponivel no site da receita.
A assinatura é feita corretamente.
Só que quando tento validar a NFe o validador joga a seguinte mensagem:

Erro na Cadeia de certificação. ‘CN=Autoridade Certificadora Raiz Brasileira v1, OU=Instituto Nacional de Tecnologia da Informacao - ITI, O=ICP-Brasil, C=BR’, emitido por ‘CN=Autoridade Certificadora Raiz Brasileira v1, OU=Instituto Nacional de Tecnologia da Informacao - ITI, O=ICP-Brasil, C=BR’, serial number ‘01’ - ERRO: 32 - Descrição do Erro: Unknown error.

alguém tem alguma sugestão?

P

Da a entender que o seu certificado não é valido
ou nao é raiz ICP.

Alencar

B

Pessoal.
Segui esse tutorial do proprio guj (http://www.guj.com.br/article.show.logic?id=141)
E consegui fazer a assinatura digital do XML.
A grande questão é: o servidor não tem JAVA 6.
Tem alguma solução para esse caso (usando o JAVA 5)??

Abraços

A

Bom dia pessoal,
Estou desenvolvendo um sistema para envio da NFe para Paraná. O sistema esta pronto, assinando e comunicando com o WebService. Mas não estou conseguindo meu xml com o sistema Visualizador que foi fornecido pela receita, as estrutura do meu xml esta com as tags e , tirando essas tags não estou conseguindo validar o xml no WebService do Paraná. Alguém pode me ajudar com isso ?
Preciso saber com fica a estrutura inicial desse xml. Inclusive eu usei uma classe de assinatura daqui do fórum mesmo.

A

acmedis:
Bom dia pessoal,
Estou desenvolvendo um sistema para envio da NFe para Paraná. O sistema esta pronto, assinando e comunicando com o WebService. Mas não estou conseguindo meu xml com o sistema Visualizador que foi fornecido pela receita, as estrutura do meu xml esta com as tags e , tirando essas tags não estou conseguindo validar o xml no WebService do Paraná. Alguém pode me ajudar com isso ?
Preciso saber com fica a estrutura inicial desse xml. Inclusive eu usei uma classe de assinatura daqui do fórum mesmo.

posta seu xml para melhor ajudar você

A

conforme solicitado pelo alexborges, segue o xml assinado que esta sendo enviado para webservice do Paraná.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
  • 41 388548900 VENDA DE MERCADORIAS 1 55 2 290 2009-10-21 2009-10-22 1 4113700 1 1 6 2 1 0 3
  • [telefone removido] S G teste LTDA S G teste
  • AV DEZ DE DEZEMBRO 1342 G 2 S/N Complemento CENTRO 4113700 LONDRINA PR 86026220 1058 BRASIL [telefone removido] 999999999
  • 99999999999999 MOVEIS LTDA
  • RUA SANTO S/N Complemento DISTRITO INDUSTRIAL 3522901 ITAPUI SP 17230000 1058 BRASIL [telefone removido] 999999999999
  • 123 PERFIL CABIDEIRO SG5006 883MM 6102 UN 1.0000 10.0000 10.00 UN 1.0000 10.0000
  • 0 00 3 10.00 12.00 1.20
  • 04
  • 04
  • 10.00 1.20 0.00 0.00 10.00 0.00 0 0.00 0 0.00 0.00 0.00 0.00 10.00
  • 1
  • 99999999999999 VIACAO GARCIA [telefone removido] AV CELSO 1100 LONDRINA PR
  • AAA1111 PR
  • 1
  • z+w316xzZIoP4PatwNmBa14+wGg= ZRH0Ezm2hvVe+wW3VdrUYmM8TB2CU9ALAW+AwuiR2SmnNhtzZjgqrz+JTXFG4I5f5nCQUxWO1JeN uG2kAyl/pc6aFj7C+X25q5hvlCCG9SQvDjuWmBi30SXh/PHcZ+LUenrJd884uu06Drwr/onFYzmE w5ySs2BR+A9k3Epr7ZE=
  • MIIGQDCCBSigAwIBAgIITkKXDYjr6CgwDQYJKoZIhvcNAQEFBQAwTDELMAkGA1UEBhMCQlIxEzAR BgNVBAoTCklDUC1CcmFzaWwxKDAmBgNVBAMTH1NFUkFTQSBDZXJ0aWZpY2Fkb3JhIERpZ2l0YWwg djEwHhcNMDkwODEzMjEwMDAwWhcNMTAwODEzMjEwMDAwWjCB/DELMAkGA1UEBhMCQlIxEzARBgNV BAoTCklDUC1CcmFzaWwxFDASBgNVBAsTCyhFTSBCUkFOQ08pMRgwFgYDVQQLEw8wMDAwMDEwMDA2 MzI2MjIxFDASBgNVBAsTCyhFTSBCUkFOQ08pMRQwEgYDVQQLEwsoRU0gQlJBTkNPKTEUMBIGA1UE CxMLKEVNIEJSQU5DTykxFDASBgNVBAsTCyhFTSBCUkFOQ08pMRQwEgYDVQQLEwsoRU0gQlJBTkNP KTE6MDgGA1UEAxMxSU5EVVNUUklBIENPTUVSQ0lPIEUgUkVQUkVTRU5UQUNPRVMgR0lCSU0gTFRE QSBNRTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEApnPkoSC3t/A7B9KkLB59yPRgO38e43CR 8KxcaDWwDMISclXCseO4uo1vWCI7C57vKbQhw9rsnFranP+u93C+8qIcMHWCAIhm67YDJRpMoFBP qNm4DDLIOH5JQbabDnQaYP6tzJqPAhc8p9YBtzObFfOIWl98E8IzwmpafhAItWMCAwEAAaOCAvcw ggLzMA4GA1UdDwEB/wQEAwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwHwYDVR0j BBgwFoAUt2CoW/mypq4A7XTr1UrJlmhm9VwwgboGA1UdEQSBsjCBr4EZQ0FSTE9TQFNHQUxVTUlO SU9TLkNPTS5CUqA9BgVgTAEDBKA0EzIwNDExMTk3ODAyMzA3NTMyOTk0MDAwMDAwMDAwMDAwMDAw MDUuODUyLjUzODNTU1BQUqAfBgVgTAEDAqAWExRDQVJMT1MgRURVQVJETyBTT1VaQaAZBgVgTAED A6AQEw44MDkwNTY2NDAwMDEzOaAXBgVgTAEDB6AOEwwwMDAwMDAwMDAwMDAwVwYDVR0gBFAwTjBM BgZgTAECAQYwQjBABggrBgEFBQcCARY0aHR0cDovL3d3dy5jZXJ0aWZpY2Fkb2RpZ2l0YWwuY29t LmJyL3JlcG9zaXRvcmlvL2RwYzCB8AYDVR0fBIHoMIHlMEmgR6BFhkNodHRwOi8vd3d3LmNlcnRp ZmljYWRvZGlnaXRhbC5jb20uYnIvcmVwb3NpdG9yaW8vbGNyL3NlcmFzYWNkdjEuY3JsMEOgQaA/ hj1odHRwOi8vbGNyLmNlcnRpZmljYWRvcy5jb20uYnIvcmVwb3NpdG9yaW8vbGNyL3NlcmFzYWNk djEuY3JsMFOgUaBPhk1odHRwOi8vcmVwb3NpdG9yaW8uaWNwYnJhc2lsLmdvdi5ici9sY3IvU2Vy YXNhL3JlcG9zaXRvcmlvL2xjci9zZXJhc2FjZHYxLmNybDCBlwYIKwYBBQUHAQEEgYowgYcwPAYI KwYBBQUHMAGGMGh0dHA6Ly9vY3NwLmNlcnRpZmljYWRvZGlnaXRhbC5jb20uYnIvc2VyYXNhY2R2 MTBHBggrBgEFBQcwAoY7aHR0cDovL3d3dy5jZXJ0aWZpY2Fkb2RpZ2l0YWwuY29tLmJyL2NhZGVp YXMvc2VyYXNhY2R2MS5wN2IwDQYJKoZIhvcNAQEFBQADggEBAD/JqxgwPOjItKlivZy0AgXNVqbQ HyEhfB39dKMHsm4pPwE+BKJXHU8l1xcc/CYFJ8yfGSYbFGs6ixbyS8Bpeeg4x0wftTg5zEZ/fHDP zXh1C7lQea7IMzO1AcwmTUtGzHlgsNkfm7OjthsDLj4GD2DfF2Z+eIExPiIi72mVczYztSWXTGXg vQhTOu4g2dQcNl5qbzLo4tdGCnrNv6DJnswP09FRGcjC8Ao38YMQYw3HpGgVl53V8Qmmqvh1LKx4 y80jEL2/HNA3r/XCx22cmaMM32o1+eHDN8jEYaJbBsswurhxLLqziiBCiQGLUVHFuCAF47vk7PzY Q9HzkWyN+Xs=

quando envio o xml, retorna o erro 225 - Falha no schema xml.
Porém consigo abrir ele normalmente pelo Visualizador NFeCTe 4.0 fornecido pela receita. E também consigo fazer a validação da estrutura e assinatura através de um programa AssinadorRS fornecido pelo sefaz do RS.

A

só dei uma olhada por cima pq estou saindo do escritorio agora mas da uma olhada no name space da tag “infNFe” seu não me engano não pode ter aquilo ali não…XD

A

também tentei dessa forma na tag infNFe:

mas retorna o mesmo erro 225.

A

acmedis:
também tentei dessa forma na tag infNFe:

mas retorna o mesmo erro 225.

acmedis joguei seu xml no validador da sefaz do RS e os seguintes problemas foram encontrados no shema

The ‘xmlnssi’ attribute is not declared. //AQUI ESTÁ SE REFERINDO AO NAMESPACE NA TAG “infNFe” VC TEM Q REMOVER ELE

The ‘http://www.portalfiscal.inf.br/nfe:dEmi’ element has an invalid value according to its data type. //SUA DATA ESTA FORMATADA ERRADA “2009 10 21” ONDE DEVERIA SER 2009-10-21 “yyyy-MM-dd”

The ‘http://www.portalfiscal.inf.br/nfe:dSaiEnt’ element has an invalid value according to its data type.//SUA DATA ESTA FORMATADA ERRADA “2009 10 22” ONDE DEVERIA SER 2009-10-22 “yyyy-MM-dd”

The ‘http://www.portalfiscal.inf.br/nfe:CNPJ’ element has an invalid value according to its data type.//O CNPJ ESTÁ COM 11 DIGITOS ONDE DEVERIAM CONTER 14

The value of the ‘Algorithm’ attribute does not equal its fixed value.//O ATRIBUTO “Algorithm” DA ASSINATURA ESTA ERRADO http://www.w3.org/2000/09/xmldsig#rsa sha1 ONDE DEVERIA SER http://www.w3.org/2000/09/xmldsig#rsa-sha1 NOTE Q NO SEU ESTÁ COM UM ESPAÇO EM BRANCO…

da uma revisada nisso, depois posta aqui se conseguiu solucionar seu problema

L

Sobre o ambiente de homologação,

-Eu posso usar o certificado da empresa que está desenvolvendo o sistema?
-Onde encontro a chave pública do sefaz virtual?

Y

O erro esta relacionado com a validade da Assinatura.

[list]O arquivo XML foi assinado e a assinatura contém o HASH (DIGEST) do conteudo do arquivo.[/list]
[list]Se por algum motivo o conteudo do arquivo for alterado, será necessário gerar um novo HASH.[/list]

Sobre assinatura digital: http://www.infowester.com/assincertdigital.php

A

boa tarde a todos, estou com o seguinte problema : preciso inserir no XML que será enviado as informações ref. ao protocolo de autorização e fazer a assinatura digital da nota. Porem quando mando fazer a assinatura fica da sequinte forma o xml :

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
  • … { tag’s da NFe}

  • 2 v3706 41100280337553000173550030000005056447753010 2010-02-10T15:29:54 141100000384752 CqvBBuqGUyBd2VBXqALlQISVtX8= 100 Autorizado o uso de NF-e
  • ZOQL7z8psu4IFcCeh9IIzVwCFU8= HK5IxwbfneFTbIwAwO/X+gtb0aQqE/IHuxmtyB/d9oybQivp0Et4tHgqubezIziGgXb8F4Tq2Igr zttLT52o9eu2ap2g3rHkzjnEbXouhW3KOuiaAkAjmsntbQEe6htFWBOn4NsjdCf1619AWlAQ//oV XtQPLnFirLYj0v8sGfRRkXRhxBStuJYe2B3X2ppVRqUdDYHbA267Se/mHniR1QYs/p+za+9Rjn5c zm6RasNbji4L2tjtxFbqnLSpOunVseJ36IEFpcRK2Nm0xBB7qybsJgLAXeRAi8x+PGr5HTEQCOOg V10IaAQxSuIH79S0fn22aOs3ZXkjZ2kPz6wEiA==
  • MIIGiTCCBXGgAwIBAgIQMjAwOTA4MjAxMjM1MDQwMjANBgkqhkiG9w0BAQUFADCBijELMAkGA1UE BhMCQlIxEzARBgNVBAoTCklDUC1CcmFzaWwxNjA0BgNVBAsTLVNlY3JldGFyaWEgZGEgUmVjZWl0 YSBGZWRlcmFsIGRvIEJyYXNpbCAtIFJGQjEuMCwGA1UEAxMlQXV0b3JpZGFkZSBDZXJ0aWZpY2Fk b3JhIGRvIFNFUlBST1JGQjAeFw0wOTA4MjAxODM0NDVaFw0xMDA4MjAxODE1MjVaMIH4MQswCQYD VQQGEwJCUjETMBEGA1UEChMKSUNQLUJyYXNpbDE2MDQGA1UECxMtU2VjcmV0YXJpYSBkYSBSZWNl aXRhIEZlZGVyYWwgZG8gQnJhc2lsIC0gUkZCMREwDwYDVQQLEwhDT1JSRUlPUzETMBEGA1UECxMK QVJDT1JSRUlPUzEWMBQGA1UECxMNUkZCIGUtQ05QSiBBMTERMA8GA1UEBxMIQ2FzY2F2ZWwxCzAJ BgNVBAgTAlBSMTwwOgYDVQQDEzNJTkRVU1RSSUEgREUgUExBU1RJQ09TIENBU0NBVkVMIExUREE6 ODAzMzc1NTMwMDAxNzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDRvzotG/1J6uvG gn58iRV/Z6HYMlcgIRVN3T6+8czokkoH1bOYRszU8MstRal1S5d5Qf6yb2viuA2WeDKUrqVkUpvi 9IsFkvfKFTbzrfn3B8SW97gILuNrcWT20DBxS+h6tgjqtmyfrwjRh/pfsOeWC5xpq+MLM+OPWZFl dAUURB1Zhr8xAoYt3obUxZ4qnfZInYtypZld6D22AncNlxGG8Tl6RQk6Qt1BEo3CHR2m0G5mNMRW H4xcVY4DPqdggfhUDlwiiIWUi44M5kGRn3oWuEt+qbPtZPSlLqi1oScNAx20M28khLbDctTUw18X gYIGczIWhQeEp3pw3Ge8NDw/AgMBAAGjggJ5MIICdTAPBgNVHRMBAf8EBTADAQEAMB8GA1UdIwQY MBaAFLkii4YkRueirecpO4xoO02tdJEUMA4GA1UdDwEB/wQEAwIF4DBgBgNVHSAEWTBXMFUGBmBM AQIBCjBLMEkGCCsGAQUFBwIBFj1odHRwczovL2NjZC5zZXJwcm8uZ292LmJyL2Fjc2VycHJvcmZi L2RvY3MvZHBjYWNzZXJwcm9yZmIucGRmMIGzBgNVHREEgaswgaigPQYFYEwBAwSgNAQyMjgxMDE5 NDUwMTYwNTc4MDk0NDAwMDAwMDAwMDAwMDAwMDAwMDA2NDA5ODczU1NQUFKgGwYFYEwBAwKgEgQQ RG9taW5nb3MgU2FsdmF0aaAZBgVgTAEDA6AQBA44MDMzNzU1MzAwMDE3M6AXBgVgTAEDB6AOBAww MDAwMDAwMDAwMDCBFmFuZHJlQHBsYXN0aXZlbC5jb20uYnIwIAYDVR0lAQH/BBYwFAYIKwYBBQUH AwIGCCsGAQUFBwMEMIGoBgNVHR8EgaAwgZ0wMqAwoC6GLGh0dHA6Ly9jY2Quc2VycHJvLmdvdi5i ci9sY3IvYWNzZXJwcm9yZmIuY3JsMDOgMaAvhi1odHRwOi8vY2NkMi5zZXJwcm8uZ292LmJyL2xj ci9hY3NlcnByb3JmYi5jcmwwMqAwoC6GLGh0dHA6Ly93d3cuaXRpLmdvdi5ici9zZXJwcm8vYWNz ZXJwcm9yZmIuY3JsMEwGCCsGAQUFBwEBBEAwPjA8BggrBgEFBQcwAoYwaHR0cDovL2NjZC5zZXJw cm8uZ292LmJyL2NhZGVpYXMvYWNzZXJwcm9yZmIucDdiMA0GCSqGSIb3DQEBBQUAA4IBAQAYwG7a 8xneLZE1MEhIRDJe2vqvc62A8G/LgL+YzeowJOfqnsTgL2OBsK9R+7Ajq4Wu6vK4/TcYE/IpLyij b6fxheTKgLxIjhbvT5ZJBbeXy6qn+JzEJv7TQiD2sX6DiS0zexfIdgH1J7EOUfRbj/dTDscT3aYk shhFfSdK4Flehz/xErWwovBxxj/S7MuG8Q62YT7cdb+exUXhKv7M25ZXD1M0Hv78Cf/xfyJ+aquN rux8jls49z3T7RGkUlrmgd4Qdy1ipZ+MpNfTUHvPRRoXIW/kyCS0h9Yikbz9JlS/795Z2TSmA+hE yeNmHX608GY7IDJfHfv9ximuxkn2NjnE

A assinatura digital deveria ficar logo abaixo da tag ?
Utilizei a classe que o " gilmaslima " postou.

P

Você deve gerar ou ler o xml da NFe já assinada e concatenar com as outras partes do
xml de distribuição.

Uma dica: armazene o xml assinado que você enviou no arquivo de lote.
Pode ser que ao regerar o xml da mesma nota e assinar este novo arquivo, o
digestValue fique diferente. Neste caso, o segundo xml não terá validade fiscal.

Alencar

M

Pessoal,

Graças a muita leitura aqui no Forum, consegui gerar.. assinar..e enviar uma NFe.

No momento estou enviando e recebendo um XML de resposta que apresenta a mensagem de sucesso:

Lote recebido com sucesso

Como eu faço agora para consultar essa nota fiscal enviada para o ambiente de homologação??

Existe algum site onde eu possao digitar a chave dela e ver como ela chegou até lá??

estou tentando no endereço a seguir, porem ele diz que a Nfe consultada não existe.. será que estou consultando no endereço correto?

http://homologacao.nfe.fazenda.sp.gov.br/nfo/areapublica/consultanfe.aspx

Vale lembrar que estou enviando para o ambiente de homologação ainda...

A validação do meu XML esta ok, conforme podem observar abaixo:

Resultado da Validação do Schema e Conferência da Assinatura:

PARSER XML:	OK
TIPO DE MENSAGEM:	NF-e
SCHEMA:	OK
ASSINATURA XML:	Assinatura VÁLIDA

Obrigado pela respostas... sem dúvida irá me ajudar bastante.

M

Pessoal,

Acabei criando um método próprio para consultar o Status da NFe via webservice… e o resultado que obtenho é o seguinte:

Conferi o Estado do emitente no XML e esta correto, ou seja “SP”. O certificado também é de “SP”. O CNPJ do emitente é o mesmo do Certificado.

O que pode estar havendo??

Obrigado pela ajuda.

P

marpinheiro:
Pessoal,

Acabei criando um método próprio para consultar o Status da NFe via webservice… e o resultado que obtenho é o seguinte:

Conferi o Estado do emitente no XML e esta correto, ou seja “SP”. O certificado também é de “SP”. O CNPJ do emitente é o mesmo do Certificado.

Código da UF é diferente de sigla da UF. Sigla = “SP”, código = “35”

Deve ser isso.

Alencar

A

É por no caso específico da Consulta de Notas Ficais você deve sempre consultar no Estado do Emitente.
Os dois primeiros digitos da Chave Representam o código do IBGE do Estado. Você deve então pela chave identificar qual é o código Estado, e consultar a nota do estado em que ela foi emitida.

Seguem os códigos

"UF"	"IBGE"
"AC"	12
"AL"	27
"AM"	13
"AP"	16
"BA"	29
"ES"	32
"MA"	21
"PB"	25
"PE"	26
"PI"	22
"RO"	11
"RR"	14
"TO"	17
"SP"	35
"CE"	23
"DF"	53
"GO"	52
"MG"	31
"MS"	50
"MT"	51
"PA"	15
"PR"	41
"RJ"	33
"RN"	24
"RS"	43
"SC"	42
"SE"	28

As URLS para cada estado, você encontra aqui:

http://www.nfe.fazenda.gov.br/portal/WebServices.aspx

ATENÇÃO: Isso se aplica apenas a Consulta, no caso de emissão você deve enviar sempre para o mesmo estado em que o seu certificado foi emitido.

M

Olá Senhores,

Eu vi em outro tópico sobre a extração do dados do assinante com base no certificado, eu testei e funcionou, mas agora eu gostaria de saber se é possível extrair as mesmas informações do arquivo XML da NFe com base no conteúdo da tag X509Certificate ou X509Data ou qualquer coisas assim abaixo segue o código, eu estou obtendo apenas com o X509 imagino que precise da Signature também.
    No código abaixo o método test funciona e o testAlheio não, que é o que eu quero fazer funcionar.
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertificateParsingException;
import java.security.cert.X509Certificate;
import java.util.Enumeration;
import java.util.List;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERObject;
import org.bouncycastle.asn1.DERObjectIdentifier;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERString;

/**
 *
 * @author Murilo
 */
public class Main {

    private void testAlheio() throws CertificateException, IOException {
        String x509content = "conteudo da tag <509Certificate>";
        CertificateFactory fact = CertificateFactory.getInstance("X.509");
        ByteArrayInputStream bais = new ByteArrayInputStream(x509content.getBytes());
        while (bais.available() > 0) {
            X509Certificate x509 = (X509Certificate) fact.generateCertificate(bais);
            exibeCertificado(x509);
        }
        bais.close();
    }

    private void exibeCertificado(X509Certificate certificate) throws CertificateParsingException, IOException {
        for (List<?> subjectAlternativeName : certificate.getSubjectAlternativeNames()) {
            String email;
            Pair<DERObjectIdentifier, String> otherName;
            // O primeiro elemento é um Integer com o valor 0 = otherName, 1 = rfc822name etc.
            // O segundo valor é um byte array ou uma String. Veja o javadoc de
            // getSubjectAlternativeNames.
            switch (((Number) subjectAlternativeName.get(0)).intValue()) {
                case 0: // OtherName - contém CPF, CNPJ etc.
                    otherName = getOtherName((byte[]) subjectAlternativeName.get(1));
                    System.out.println("First : " + otherName.first);
                    System.out.println("Second : " + otherName.second);
                    // o OID fica em otherName.first
                    break;
                case 1: // rfc822Name - usado para email
                    email = (String) subjectAlternativeName.get(1);
                    System.out.println("email : "+email);
                    break;
                default:
                    break;
            }
        }
    }

    /**
     * Uma classe que encapsula pares de objetos.
     * Inspirado no template pair<> da STL.
     *
     * @param <T> O primeiro tipo.
     * @param <U> O segundo tipo.
     */
    class Pair<T, U> {

        /** O primeiro objeto. */
        public T first;
        /** O segundo objeto. */
        public U second;

        /** Construtor */
        public Pair(T t, U u) {
            first = t;
            second = u;
        }
    }

    /**
     * Interpreta um dado do tipo otherName.
     * Obs. O JDK 5.0 não tem classes que lidem com um dado do tipo OtherName.
     * É necessário usar o BouncyCastle.
     * @param encoded O dado em ASN.1.
     * @return Um par contendo o OID e o conteúdo.
     */
    private Pair<DERObjectIdentifier, String> getOtherName(byte[] encoded) throws IOException {
        // O JDK 5.0 não tem classes que lidem com um dado do tipo OtherName.
        // É necessário usar o BouncyCastle.
        ASN1InputStream inps = new ASN1InputStream(encoded);
        DERSequence seq = null;
        DERObjectIdentifier oid = null;
        String conteudo = "";
        seq = (DERSequence) inps.readObject();
        inps.close();
        Enumeration en = seq.getObjects();
        oid = (DERObjectIdentifier) en.nextElement();
        DERObject obj = ((ASN1TaggedObject) ((ASN1TaggedObject) en.nextElement()).getObject()).getObject();
        if (obj instanceof DERString) { // Certificados antigos SERASA - incorretos
            conteudo = ((DERString) obj).getString();
        } else if (obj instanceof DEROctetString) { // Certificados corretos
            conteudo = new String(((DEROctetString) obj).getOctets(), "ISO-8859-1");
        }
        return new Pair<DERObjectIdentifier, String>(oid, conteudo);
    }

//
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws CertificateParsingException, IOException, CertificateException {
//        new Main().test();
        new Main().testAlheio();
    }

    private void test() throws CertificateParsingException, IOException {
        File file = new File("CERT.pfx");
        X509Certificate certificate = null;

        if (file.exists()) {

//            CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
//            InputStream is = new FileInputStream(file);
//            Certificate certificate = certificateFactory.generateCertificate(is);
//            System.out.println("Tipo de certificado "+certificate.getType());
//            is.close();
            try {
                KeyStore keyStore = KeyStore.getInstance("PKCS12");
                InputStream is = new FileInputStream(file);
                String senha = "senha";
                keyStore.load(is, senha.toCharArray());
                is.close();

                String alias = "";

                PrivateKey privateKey = null;
                Enumeration e = keyStore.aliases();
                while (e.hasMoreElements()) {
                    alias = (String) e.nextElement();
                    certificate = (X509Certificate) keyStore.getCertificate(alias);
                    privateKey = (PrivateKey) keyStore.getKey(alias, senha.toCharArray());
                    System.out.println(certificate + " " + privateKey.getAlgorithm());
                }
            } catch (Exception ex) {
                ex.printStackTrace();
                System.out.println(ex.getCause());
            }
        } else {
            System.out.println("Certificado nao encontrado em " + file.getAbsolutePath());
        }
        exibeCertificado(certificate);
    }
}
R

julianosott:

ou seja, não pode ter o xmlns:ns2=“http://www.w3.org/2000/09/xmldsig#

o mesmo vale para o enviNFe:

<enviNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.10">
  <idLote>1</idLote> 
  <NFe xmlns="http://www.portalfiscal.inf.br/nfe">

nesse caso tanto o envi como cada nfe devem ter xmlns=“http://www.portalfiscal.inf.br/nfe” e o envi não pode ter o xmlns:ns2=“http://www.w3.org/2000/09/xmldsig#”. Se por acaso o xml estiver do jeito errado, pode usar esses códigos no assinador, ou criar outro método:

esse aqui remove o xmlns:ns2 do elemento raíz:

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

esse aqui adiciona o xmlns necessário a tag NFe:

((Element) doc.getDocumentElement().getElementsByTagName("NFe").item(i)).setAttribute("xmlns", "http://www.portalfiscal.inf.br/nfe");

Quem quiser verificar o xml pode usar esse site: http://www.sefaz.rs.gov.br/AAE_ROOT/NFE/SAT-WEB-NFE-VAL_1.asp Acho que ele só valida os certificados do Rio Grande do Sul, mas o bom é que ele verifica a estrutura do xml tb.

É isso por enquanto, qualquer coisa é só perguntar.

Só para ajudar os próximos, essa solução ai em cima funcionou pra mim q estava com problema de assinatura, porém além disso também fiz:

docs.getDocumentElement().removeAttribute("xmlns:ns2");
		docs.getDocumentElement().removeAttribute("xmlns:ds");
		docs.getDocumentElement().removeAttribute("xmlns:xsi");

funcionou direitinho depois q fiz isso

A

O Grande Bé:
julianosott:

ou seja, não pode ter o xmlns:ns2=“http://www.w3.org/2000/09/xmldsig#

o mesmo vale para o enviNFe:

<enviNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="1.10">
  <idLote>1</idLote> 
  <NFe xmlns="http://www.portalfiscal.inf.br/nfe">

nesse caso tanto o envi como cada nfe devem ter xmlns=“http://www.portalfiscal.inf.br/nfe” e o envi não pode ter o xmlns:ns2=“http://www.w3.org/2000/09/xmldsig#”. Se por acaso o xml estiver do jeito errado, pode usar esses códigos no assinador, ou criar outro método:

esse aqui remove o xmlns:ns2 do elemento raíz:

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

esse aqui adiciona o xmlns necessário a tag NFe:

((Element) doc.getDocumentElement().getElementsByTagName("NFe").item(i)).setAttribute("xmlns", "http://www.portalfiscal.inf.br/nfe");

Quem quiser verificar o xml pode usar esse site: http://www.sefaz.rs.gov.br/AAE_ROOT/NFE/SAT-WEB-NFE-VAL_1.asp Acho que ele só valida os certificados do Rio Grande do Sul, mas o bom é que ele verifica a estrutura do xml tb.

É isso por enquanto, qualquer coisa é só perguntar.

Só para ajudar os próximos, essa solução ai em cima funcionou pra mim q estava com problema de assinatura, porém além disso também fiz:

docs.getDocumentElement().removeAttribute("xmlns:ns2");
		docs.getDocumentElement().removeAttribute("xmlns:ds");
		docs.getDocumentElement().removeAttribute("xmlns:xsi");

funcionou direitinho depois q fiz isso

Só reforçando o que o Grande Bé comentou no manual de integração da NFe fala que não é permitida a utilização de prefixos de namespace…XD

L

Só para atualizar… o validador via web para verificar os xmls do sefaz é http://www.sefaz.rs.gov.br/NFE/NFE-VAL.aspx não é mais o endereço antigo

F

Amigos do forum,

Eu sou programador em ambiente Mac Os X (amador).

Tenho rotinas escritas onde controle há anos em minha pequena empresa a emissão de notas fiscais, recebimentos e etc…

Com o surgimento da nota fiscal eletrônica, portei uma rotina que gera um arquivo em texto. (.txt) que uso na importação para o programa gratuito s]da Sefaz-SP, emissor gratuito de NFe.

Gostaria de melhorar minhas próprias rotinas para assinar e transmitir o .xml da NFe.

Creio que o primeiro passo seria assinar o XML.

Procuro ajuda, e estou de acordo em pagar por sua ajuda.

Alguém neste fórum poderia me ajudar escrevendo ou adaptando sua linha de código existente, para mim?

Pensei em ter um comando de terminal, que posso invocar de dentro de meu programa existente, que assinasse o arquivo de texto que sou capaz de gerar, mas não sou capaz de assinar.

Ou mesmo gravar numa pasta por exemplo: “Notas Fiscais por Assinar”, e uma rotina automática assinasse o xml e automáticamente gravasse cópia dele em outra pasta “Notas Fiscais Assinadas”.

Creio que não deve ser difícil para alguém que já tem suas rotinas prontas.

Aguardo contato,

Obrigado,

Bernardo Höhl

Usina Brasileira de Cristobalita Ltda
http://www.rutenium.com.br

Meu celular: 21-99775490

eu endereço de email é:

fundidor + arroba + mac.com

G

Pessoal, boa tarde.

Meu problema é o seguinte: Preciso saber como me monunicar com o webservice e enviar os dados da minha NF. eu já fiz a assinatura do xml, o que preciso saber é como enviar a nfe para a prefeitura.

vi alguns exemplos aqui mas não compreendi, pois eu tenho um keystore, um pfx, senha, o link, e o XMl. tudo isso deve ser passado como parâmetro(creio eu) na função que fará a comunicação com o webservice da prefeitura. se alguém puder me ajuda, grato pela atenção!

J

Olá Pessoal

Estou com problemas para validar a assinatura digital do XML de terceiros, sei que existe o próprio validador oferecido pelo governo, porem preciso fazer um que valide o XML também.

Tem alguns XML que eu NÃO consigo validar e a aplicação do governo valida.

Alguém tem algum exemplo de método de validação do XML assinado digitalmente?

J

Bah, um tutorial seria muito bacana! Aqui na empresa temos planos para implementar a NFe nos próximos e ter um artigo sobre isso feito por alguém que já teve problemas e conseguiu resolver seria de muita valia! Pois você já tem noção dos problemas encontrados nesse processo.

Sou novo aqui, estou começando um projeto para criar componentes para NFe de campinas está faltando somente a assinatura do XML, você tem algum código fonte java com exemplo de como assinar a NFSe.

P

Jpleiser você está tentando assinar Nfe 1.10 ou 2.0?

[]'s

P

Pessoal, tem alguns xml de distribuição (xml de fornecedor) que estão vindo com namespace na tag nfeProc, tipo assim:

Isso invalida a assinatura do arquivo. Mas, estranhamento ao validar o conteúdo no site da SEFAZ/RS (http://www.sefaz.rs.gov.br/NFE/NFE-VAL.aspx)
valida certo.

O correto da tag seria assim, validando a assinatura corretamente.

Pergunto: alguém saberia como fazer na validação para ignorar/remover estes atributos?

Alencar

D

A tag que contem a assinatura é a NFe

P

drcosta, tô sabendo. Mas estranhamente a assinatura se torna inválida só por conter os atributos na
tag nfeProc, que nem é usada na validação da assinatura…

Muito louco isso.

Alencar

P

Pessoal, estou com um problema de validação de assinatura, quando o certificado usado foi um NF-e (não é e-CNPJ).
Este tipo de certificado existe e é aceito pela SEFAZ para assinatura de NF-e.
Porém, no meu código de validação, retorna falso para a cadeia validadora. Já me certifiquei para a existência dos
certificados no certs.
Se desabilito a verificação da cadeia, a assinatura é validada ou seja, a assinatura em si está correta.
Estou em voltas com um certificado emitido por
– Autoridade Certificadora Raiz Brasileira v2
|-- AC Certisign G6
|-- AC Certisign Multipla G5

fornecedor: http://www.certisign.com.br/atendimento-suporte/downloads/hierarquias/icp-brasil/nf-e#.UTZTuZ5QCZx

Alguma dica de como validar esta cadeia? Algo diferente neste tipo de certificado que mude o algorítimo de validação
na classe X509KeySelector?

Grato a todos pela atenção.

Criado 3 de março de 2008
Ultima resposta 6 de mar. de 2013
Respostas 136
Participantes 47