Erro ao tentar assinar XML - CTe [RESOLVIDO]

2 respostas
W

Olá estou com dificuldades para assinar meu XML

Erro:Certificado válido!
Documento ok!
Documento:CTe
java.lang.NullPointerException: signingKey cannot be null
at javax.xml.crypto.dsig.dom.DOMSignContext.(DOMSignContext.java:74)
at fernando.Main.assinarDocumento(Main.java:147)
at fernando.Main.main(Main.java:161)
CONSTRUÍDO COM SUCESSO (tempo total: 1 segundo)

classe

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package fernando;

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 Main{
	/*
	 * 	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("/home/fernando/thiago/keystore.jks");
	private static String alias="icp_br";
	private static char[] senha="123456".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= Main.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("infCte");
		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));


                System.out.println("Documento:"+doc.getDocumentElement().getTagName());

		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{
			Main.getCertificado();
			Main.assinarDocumento("/home/fernando/Cte41123452154112345215411234521541123452156548.xml");
		}
		catch(Exception e){
			e.printStackTrace();
		}

	}

}

2 Respostas

W

para facilitar o xml

:)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CTe xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns="http://www.portalfiscal.inf.br/cte"><infCte versao="1.03" Id="Cte41123452154112345215411234521541123452156548"><ide><cUF>PR</cUF><cCT>12457896</cCT><CFOP>5102</CFOP><natOp>TESTE DE NATUREZA</natOp><forPag>0</forPag><mod>57</mod><serie>001</serie><nCT>123</nCT><dhEmi>2011-02-08T02:02:15</dhEmi><tpImp>2</tpImp><tpEmis>1</tpEmis><cDV>1</cDV><tpAmb>2</tpAmb><tpCTe>0</tpCTe><procEmi>0</procEmi><verProc>1.0.0.0</verProc><refCTE>41123452154112345215411234521541123452156548</refCTE><cMunEmi>41325687</cMunEmi><xMunEmi>CURITIBA</xMunEmi><UFEmi>PR</UFEmi><modal>01</modal><tpServ>01</tpServ><cMunIni>41325687</cMunIni><xMunIni>CURITIBA</xMunIni><UFIni>PR</UFIni><cMunFim>41325687</cMunFim><xMunFim>FLORIANOPOLIS</xMunFim><UFFim>SC</UFFim><retira>0</retira><xDetRetira>DETALHES</xDetRetira><toma03><toma>3</toma></toma03><toma4><toma>3</toma><CNPJ>02949901000150</CNPJ><IE>ISENTO</IE><xNome>EMPRESA TESTE</xNome><xFant>FANTASIA</xFant><fone>[telefone removido]</fone><enderToma><xLgr>RUA SEM NOME</xLgr><nro>S/N</nro><xCpl>CJ 44</xCpl><xBairro>FANNY</xBairro><cMun>41325687</cMun><xMun>CURITIBA</xMun><CEP>81670090</CEP><UF>PR</UF><cPais>1031</cPais><xPais>BRASIL</xPais></enderToma></toma4></ide><compl><xCaracAd>INFO ADICIONAL TRANSPORTE</xCaracAd><xCaracSer>INFO ADICIONAL SERVICO</xCaracSer><xEmi>FUNCIONARIO</xEmi><fluxo><xOrig>CWB</xOrig><pass><xPass>BRA</xPass></pass></fluxo><Entrega><comData><tpPer>1</tpPer><dProg>2011-02-08</dProg></comData><semHora><tpHor>0</tpHor></semHora></Entrega><xObs>OBS GERAIS</xObs></compl><emit><CNPJ>[telefone removido]</CNPJ><IE>ISENTO</IE><xNome>FERNANDO VILLA ROSA</xNome><xFant></xFant><enderEmit><xLgr>RUA OBA</xLgr><nro>5421</nro><xCpl>CASA</xCpl><xBairro>HAUER</xBairro><cMun>41325687</cMun><xMun>CURITIBA</xMun><CEP>81670090</CEP><UF>PR</UF><cPais>1031</cPais><xPais>BRASIL</xPais><fone>[telefone removido]</fone></enderEmit></emit><rem><CNPJ>[telefone removido]</CNPJ><IE>ISENTO</IE><xNome>FERNANDO VILLA ROSA</xNome><xFant></xFant><enderReme><xLgr>RUA OBA</xLgr><nro>5421</nro><xCpl>CASA</xCpl><xBairro>HAUER</xBairro><cMun>41325687</cMun><xMun>CURITIBA</xMun><CEP>81670090</CEP><UF>PR</UF><cPais>1031</cPais><xPais>BRASIL</xPais></enderReme><infNF><nRoma>789</nRoma><nPed>123DS</nPed><serie>1A</serie><nDoc>123465</nDoc><dEmi>2011-02-08</dEmi><vBC>100.00</vBC><vICMS>18.00</vICMS><vBCST>0.00</vBCST><vST>0.00</vST><vProd>100.00</vProd><vNF>100.00</vNF><nCFOP>5102</nCFOP><nPeso>156.240</nPeso><PIN>12</PIN><locRet><CNPJ>02949901000150</CNPJ><xNome>S/N</xNome><xLgr>RUA SEM NOME</xLgr><xCpl>CJ 44</xCpl><xBairro>FANNY</xBairro><cMun>41325687</cMun><xMun>CURITIBA</xMun><UF>PR</UF></locRet></infNF></rem><exped><CNPJ>02949901000150</CNPJ><IE>ISENTO</IE><xNome>EMPRESA TESTE</xNome><fone>[telefone removido]</fone><enderExped><xLgr>RUA SEM NOME</xLgr><nro>S/N</nro><xCpl>CJ 44</xCpl><xBairro>FANNY</xBairro><cMun>41325687</cMun><xMun>CURITIBA</xMun><CEP>81670090</CEP><UF>PR</UF><cPais>1031</cPais><xPais>BRASIL</xPais></enderExped></exped><receb><CNPJ>[telefone removido]</CNPJ><IE>ISENTO</IE><xNome>FERNANDO VILLA ROSA</xNome><fone>[telefone removido]</fone><enderReceb><xLgr>RUA OBA</xLgr><nro>5421</nro><xCpl>CASA</xCpl><xBairro>HAUER</xBairro><cMun>41325687</cMun><xMun>CURITIBA</xMun><CEP>81670090</CEP><UF>PR</UF><cPais>1031</cPais><xPais>BRASIL</xPais></enderReceb></receb><dest><CNPJ>02949901000150</CNPJ><IE>ISENTO</IE><xNome>EMPRESA TESTE</xNome><fone>[telefone removido]</fone><enderDest><xLgr>RUA SEM NOME</xLgr><nro>S/N</nro><xCpl>CJ 44</xCpl><xBairro>FANNY</xBairro><cMun>41325687</cMun><xMun>CURITIBA</xMun><CEP>81670090</CEP><UF>PR</UF><cPais>1031</cPais><xPais>BRASIL</xPais></enderDest><locEnt><CNPJ>02949901000150</CNPJ><xNome>EMPRESA TESTE</xNome><xLgr>RUA SEM NOME</xLgr><nro>S/N</nro><xCpl>CJ 44</xCpl><xBairro>FANNY</xBairro><cMun>CURITIBA</cMun><UF>PR</UF></locEnt></dest><vPrest><vTPrest>500.36</vTPrest><vRec>500.36</vRec><Comp><xNome>HONORARIOS</xNome><vComp>500.00</vComp></Comp><Comp><xNome>SORVETE</xNome><vComp>0.36</vComp></Comp></vPrest><imp><ICMS><CST00><CST>00</CST><vBC>500.00</vBC><pICMS>33.33</pICMS><vICMS>40.00</vICMS></CST00></ICMS><infAdFisco>INFORMACOES AO FISCO</infAdFisco></imp><infCTeNorm><infCarga><vMerc>500.00</vMerc><proPred>MAGUEIRA D'AGUA</proPred><xOutCat>VERDE</xOutCat><infQ><tpMed>KILOS</tpMed><qCarga>500.0000</qCarga></infQ></infCarga><contQt><nCont>1</nCont><lacContQt><nLacre>ASJKDHKSJADHSJD12323</nLacre></lacContQt><dPrev>2011-02-08</dPrev></contQt><seg><respSeg>SUPERSEG</respSeg><nApol>APOLICE123</nApol><nAver>80040.250</nAver></seg><rodo><RNTRC>123</RNTRC><dPrev>2011-02-08</dPrev><lota>0</lota><CTRB><serie>445444</serie><nCTRB>987987987</nCTRB></CTRB><occ><serie>987</serie><nOcc>75</nOcc><dEmi>2011-02-08</dEmi><emiOcc><CNPJ>1231321231321</CNPJ><cInt>75</cInt><IE>ISENTA</IE><UF>PR</UF><fone>[telefone removido]</fone></emiOcc></occ><valePed><nroRE>1</nroRE><vTValePed>2</vTValePed><disp><tpDisp>1</tpDisp><xEmp>ECOVIA</xEmp><dVig>2011-02-08</dVig><nDisp>654654FD77</nDisp><nCompC>987987</nCompC></disp></valePed><veic><cInt>12</cInt><placa>AIS3021</placa><tara>30</tara><capKG>3</capKG><capM3>20</capM3><tpProp>P</tpProp><tpVeic>0</tpVeic><tpRod>01</tpRod><UF>PR</UF><prop><CPF>[telefone removido]</CPF><CNPJ>[telefone removido]</CNPJ><RNTRC>321321321</RNTRC><xNome>FERNANDO</xNome><IE>ISENTO</IE><UF>PR</UF><tpProp>1</tpProp></prop></veic><lacRodo><nLacre>uiweruweyruywer</nLacre></lacRodo><moto><xNome>MARCELO</xNome><CPF>[telefone removido]</CPF></moto></rodo><peri><nONU>321321231</nONU><xNomeAE>CARGA PERIGOSA</xNomeAE><xClaRisco>SUBCLASSE</xClaRisco><grEmb>GRUPO</grEmb><qTotProd>150</qTotProd><qVolTipo>info</qVolTipo><pontoFulgor>OPA</pontoFulgor></peri><veicNovos><chassi>6546545645645645</chassi><cCor>321</cCor><xCor>VECTRA</xCor><cMod>VECTRA</cMod><vUnit>50000.00</vUnit><vFrete>5000.00</vFrete></veicNovos><infCteSub><chCte>654654654654564654564654564654</chCte><tomaICMS><refNFe>564654654654654654654654564654</refNFe><refNF><CNPJ>02949901000150</CNPJ><mod>nf</mod><serie>55</serie><subserie>654654</subserie><nro>897987897</nro><valor>150.00</valor><dEmi>2011-02-08</dEmi></refNF><refCte>321321</refCte></tomaICMS></infCteSub></infCTeNorm><infCteComp><chave>321321321231231</chave><vPresComp><vTPrest>124.00</vTPrest><compComp><xNome>HONORARIOS</xNome><vComp>500.00</vComp></compComp><compComp><xNome>SORVETE</xNome><vComp>0.36</vComp></compComp></vPresComp><impComp><ICMSComp><CST00><CST>00</CST><vBC>500.00</vBC><pICMS>33.33</pICMS><vICMS>40.00</vICMS></CST00></ICMSComp><infAdFisco>INFORMACOES AO FISCO</infAdFisco></impComp></infCteComp></infCte></CTe>
W

Bom vou postar aki que pode ajudar mais gente!

o problema era no registro do certificado do cliente no keystore ai usei a classe abaixo que resolveu meu problema

package certificadoimport;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.security.Key;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Enumeration;

/**
 * This class can be used to import a key/certificate pair from a pkcs12 file
 * into a regular JKS format keystore for use with jetty and other java based
 * SSL applications, etc.
 *<PRE>
 *    usage: java PKCS12Import {pkcs12file} [newjksfile]
 *</PRE>
 *
 * If you don't supply newjksfile, newstore.jks will be used.  This can be an
 * existing JKS keystore.
 * <P>
 * Upon execution, you will be prompted for the password for the pkcs12 keystore
 * as well as the password for the jdk file.  After execution you should have a
 * JKS keystore file that contains the private key and certificate that were in
 * the pkcs12
 * <P>
 * You can generate a pkcs12 file from PEM encoded certificate and key files
 * using the following openssl command:
 * <PRE>
 *    openssl pkcs12 -export -out keystore.pkcs12 -in www.crt -inkey www.key
 * </PRE>
 * then run:
 * <PRE>
 *    java PKCS12Import keystore.pkcs12 keytore.jks
 * </PRE>
 *
 * @author Jason Gilbert &lt;[email removido]&gt;
 */
public class PKCS12Import
{
   public static void main(String[] args) throws Exception
   {
      if (args.length < 1) {
         System.err.println(
               "usage: java PKCS12Import {pkcs12file} [newjksfile]");
         System.exit(1);
      }

      File fileIn = new File(args[0]);
      File fileOut;
      if (args.length > 1) {
         fileOut = new File(args[1]);
      } else {
         fileOut = new File("newstore.jks");
      }

      if (!fileIn.canRead()) {
         System.err.println(
               "Unable to access input keystore: " + fileIn.getPath());
         System.exit(2);
      }

      if (fileOut.exists() && !fileOut.canWrite()) {
         System.err.println(
               "Output file is not writable: " + fileOut.getPath());
         System.exit(2);
      }

      KeyStore kspkcs12 = KeyStore.getInstance("pkcs12");
      KeyStore ksjks = KeyStore.getInstance("jks");

      System.out.print("Enter input keystore passphrase: ");
      char[] inphrase = readPassphrase();
      System.out.print("Enter output keystore passphrase: ");
      char[] outphrase = readPassphrase();

      kspkcs12.load(new FileInputStream(fileIn), inphrase);

      ksjks.load(
            (fileOut.exists())
            ? new FileInputStream(fileOut) : null, outphrase);

      Enumeration eAliases = kspkcs12.aliases();
      int n = 0;
      while (eAliases.hasMoreElements()) {
         String strAlias = (String)eAliases.nextElement();
         System.err.println("Alias " + n++ + ": " + strAlias);

         if (kspkcs12.isKeyEntry(strAlias)) {
            System.err.println("Adding key for alias " + strAlias);
            Key key = kspkcs12.getKey(strAlias, inphrase);

            Certificate[] chain = kspkcs12.getCertificateChain(strAlias);

            ksjks.setKeyEntry("001", key, outphrase, chain);
         }
      }

      OutputStream out = new FileOutputStream(fileOut);
      ksjks.store(out, outphrase);
      out.close();
   }

   static void dumpChain(Certificate[] chain)
   {
      for (int i = 0; i < chain.length; i++) {
         Certificate cert = chain[i];
         if (cert instanceof X509Certificate) {
            X509Certificate x509 = (X509Certificate)chain[i];
            System.err.println("subject: " + x509.getSubjectDN());
            System.err.println("issuer: " + x509.getIssuerDN());
         }
      }
   }

   static char[] readPassphrase() throws IOException
   {
      InputStreamReader in = new InputStreamReader(System.in);

      char[] cbuf = new char[256];
      int i = 0;

readchars:
      while (i < cbuf.length) {
         char c = (char)in.read();
         switch (c) {
            case '\r':
               break readchars;
            case '\n':
               break readchars;
            default:
               cbuf[i++] = c;
         }
      }

      char[] phrase = new char[i];
      System.arraycopy(cbuf, 0, phrase, 0, i);
      return phrase;
   }
}

Abraço

Criado 10 de fevereiro de 2011
Ultima resposta 10 de fev. de 2011
Respostas 2
Participantes 1