Assinaturas de arquivos xml da NFe

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

boa tarde!!!

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

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.
Adrianolkp@gmail.com

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 bhermont@gmail.com ?

Obrigado

Como consigo gerar o arquivo pfx a partir do token?

Alguma dica?

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.

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: alexrosa@gmail.com

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?

.

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…

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.

[quote=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!![/quote]

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

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.

Galera,

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

doc.setXmlStandalone(true);

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

[quote=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.[/quote]

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.

[quote=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.[/quote]

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

é 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

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!

[quote=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![/quote]

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