Erro ao tentar assinar XML - CTe [RESOLVIDO]

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

[code]/*

  • 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();
	}

}

}

[/code]

para facilitar o xml

:slight_smile:

[code]

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>PR124578965102TESTE DE NATUREZA0570011232011-02-08T02:02:152112001.0.0.04112345215411234521541123452154112345215654841325687CURITIBAPR010141325687CURITIBAPR41325687FLORIANOPOLISSC0DETALHES3302949901000150ISENTOEMPRESA TESTEFANTASIA4137797274RUA SEM NOMES/NCJ 44FANNY41325687CURITIBA81670090PR1031BRASILINFO ADICIONAL TRANSPORTEINFO ADICIONAL SERVICOFUNCIONARIOCWBBRA12011-02-080OBS GERAIS04384142927ISENTOFERNANDO VILLA ROSARUA OBA5421CASAHAUER41325687CURITIBA81670090PR1031BRASIL413779727404384142927ISENTOFERNANDO VILLA ROSARUA OBA5421CASAHAUER41325687CURITIBA81670090PR1031BRASIL789123DS1A1234652011-02-08100.0018.000.000.00100.00100.005102156.2401202949901000150S/NRUA SEM NOMECJ 44FANNY41325687CURITIBAPR02949901000150ISENTOEMPRESA TESTE4137797274RUA SEM NOMES/NCJ 44FANNY41325687CURITIBA81670090PR1031BRASIL04384142927ISENTOFERNANDO VILLA ROSA4137797274RUA OBA5421CASAHAUER41325687CURITIBA81670090PR1031BRASIL02949901000150ISENTOEMPRESA TESTE4137797274RUA SEM NOMES/NCJ 44FANNY41325687CURITIBA81670090PR1031BRASIL02949901000150EMPRESA TESTERUA SEM NOMES/NCJ 44FANNYCURITIBAPR500.36500.36HONORARIOS500.00SORVETE0.3600500.0033.3340.00INFORMACOES AO FISCO500.00MAGUEIRA D'AGUAVERDEKILOS500.00001ASJKDHKSJADHSJD123232011-02-08SUPERSEGAPOLICE12380040.2501232011-02-080445444987987987987752011-02-08123132123132175ISENTAPR4132541478121ECOVIA2011-02-08654654FD7798798712AIS302130320P001PR0438414292704384142927321321321FERNANDOISENTOPR1uiweruweyruywerMARCELO12345678901321321231CARGA PERIGOSASUBCLASSEGRUPO150infoOPA6546545645645645321VECTRAVECTRA50000.005000.0065465465465456465456465456465456465465465465465465465456465402949901000150nf55654654897987897150.002011-02-08321321321321321231231124.00HONORARIOS500.00SORVETE0.3600500.0033.3340.00INFORMACOES AO FISCO[/code]

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

[code]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.
    *

    
    
  • usage: java PKCS12Import {pkcs12file} [newjksfile]
    *

  • If you don’t supply newjksfile, newstore.jks will be used. This can be an

  • existing JKS keystore.

  • 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

  • You can generate a pkcs12 file from PEM encoded certificate and key files

  • using the following openssl command:

  • 
    
  • openssl pkcs12 -export -out keystore.pkcs12 -in www.crt -inkey www.key

  • then run:

  • 
    
  • java PKCS12Import keystore.pkcs12 keytore.jks

  • @author Jason Gilbert <jason@doozer.com>
    */
    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 © {
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;

}
}

[/code]

Abraço

1 curtida