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
[code]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();
}
}
}
[/code]
mas é um exemplo de 3 anos atras qual a melhor maneira em se trabalhar com assinatura digital NFe?
Obrigado.