[RESOLVIDO]Assinatura Digital A1 a partir de um arquivo .pfx

2 respostas
F

Aew galera estou tentando implementar a assinatura digital de uma nfe com certificado A1 tenho arquivio .pfx e a senha para teste, agora gostaria de saber como fazer essa assinatura, tenho algumas classes de exemplo

package signature.nfe;

import java.security.*;
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();
        }

    }
}

mas é um exemplo de 3 anos atras qual a melhor maneira em se trabalhar com assinatura digital NFe?

Obrigado.

2 Respostas

F

consegui carregar o arquivo .pfx seguindo um post ficou assim

KeyStore ks = KeyStore.getInstance("PKCS12");
FileInputStream fis = new FileInputStream(keystoreFile);

//load the keystore
ks.load(fis, "senha do arquivo".toCharArray());

//get the private key for signing.
PrivateKey privateKey = (PrivateKey) ks.getKey(privateKeyAlias, privateKeyPass.toCharArray());

agora preciso adicionar no arquivo xml da nfe como faço?

F

na verdade a classe que passei primeiro faz tudo que preciso no arquivo xml, só precisei adaptar para carregar o arquivo pfx ao inves do jrs, agora so preciso dar uma entendida melhor em como tudo funciona

Criado 30 de maio de 2011
Ultima resposta 31 de mai. de 2011
Respostas 2
Participantes 1