Login Registre-se
Assinar XML com certificado A3  XML
Índice dos Fóruns » Java Avançado
Autor Mensagem
euclides

JavaC Membro

Membro desde: 15/08/2017 19:27:15
Mensagens: 5
Offline

Pessoal, estou com um certificado A3 com uma leitora da Gemalto. Estou precisando enviar um XML assinado para o governo (eSocial). Alguem tem algo implementado que funcione? Estou utilizando uma implementação que utiliza o SmartCard.cfg
name = SmartCard
library = c:\windows\system32\aetpkss1.dll
showInfo = true
Porem retorna este erro:
Caused by: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_TOKEN_NOT_RECOGNIZED

Acredito que essa DLL não seja a DLL correta para esta leitora.
Alguém tem alguma ideia ou ajuda?

Muito obrigado.
O código é este:


public class AssinarXMLsCertfificadoA3 {
private static final String INFINUT = "infInut";
private static final String INFCANC = "infCanc";
private static final String NFE = "NFe";

private PrivateKey privateKey;
private KeyInfo keyInfo;

public static void main(String[] args) {
try {
System.setProperty("javax.net.debug", "all");
String senhaDoCertificadoDoCliente = "2424";
AssinarXMLsCertfificadoA3 assinarXMLsCertfificadoA3 = new AssinarXMLsCertfificadoA3();

/**
* Assinando o XML de Lote da NF-e
* fileEnviNFe = Caminho do Arquivo XML (EnviNFe) gerado;
*/
info("");
String fileEnviNFe = "C:/euclides/s1000.xml";
String xmlEnviNFe = lerXML(fileEnviNFe);
String xmlEnviNFeAssinado = assinarXMLsCertfificadoA3.assinaEnviNFe(
xmlEnviNFe, senhaDoCertificadoDoCliente);
info("XML EnviNFe Assinado: " + xmlEnviNFeAssinado);

/**
* Assinando o XML de Cancelamento da NF-e
* fileCancNFe = Caminho do Arquivo XML (CancNFe) gerado;
*/
/* info("");
String fileCancNFe = "C:/euclides/s1000.xml";
String xmlCancNFe = lerXML(fileCancNFe);
String xmlCancNFeAssinado = assinarXMLsCertfificadoA3.assinaCancNFe(
xmlCancNFe, senhaDoCertificadoDoCliente);
info("XML CancNFe Assinado: " + xmlCancNFeAssinado); */

/**
* Assinando o XML de Inutilizacao da NF-e
* fileInutNFe = Caminho do Arquivo XML (InutNFe) gerado;
*/
/* info("");
String fileInutNFe = "C:/euclides/s1000.xml";
String xmlInutNFe = lerXML(fileInutNFe);
String xmlInutNFeAssinado = assinarXMLsCertfificadoA3.assinaInutNFe(
xmlInutNFe, senhaDoCertificadoDoCliente);
info("XML InutNFe Assinado: " + xmlInutNFeAssinado); */

} catch (Exception e) {
e.printStackTrace();
error("| " + e.toString());
}
}

/**
* Assinatura do XML de Envio de Lote da NF-e utilizando Certificado
* Digital A3.
* @param xml
* @param certificado
* @param senha
* @return
* @throws Exception
*/
public String assinaEnviNFe(String xml, String senha) throws Exception {

Document document = documentFactory(xml);

XMLSignatureFactory signatureFactory = XMLSignatureFactory.getInstance("DOM");

ArrayList<Transform> transformList = signatureFactory(signatureFactory);

loadCertificates(senha, signatureFactory);

for (int i = 0; i < document.getDocumentElement().getElementsByTagName(NFE).getLength(); i++) {
try {
assinarNFe(signatureFactory, transformList, privateKey, keyInfo, document, i);
} catch(Exception e) {
continue;
}
}

return outputXML(document);
}

/**
* Assintaruda do XML de Cancelamento da NF-e utilizando Certificado
* Digital A3.
* @param xml
* @param certificado
* @param senha
* @return
* @throws Exception
*/
public String assinaCancNFe(String xml, String senha) throws Exception {
return assinaCancelametoInutilizacao(xml, senha, INFCANC);
}

/**
* Assinatura do XML de Inutilizacao de sequenciais da NF-e utilizando
* Certificado Digital A3.
* @param xml
* @param certificado
* @param senha
* @return
* @throws Exception
*/
public String assinaInutNFe(String xml, String senha) throws Exception {
return assinaCancelametoInutilizacao(xml, senha, INFINUT);
}

private void assinarNFe(XMLSignatureFactory fac,
ArrayList<Transform> transformList, PrivateKey privateKey,
KeyInfo ki, Document document, int indexNFe) throws Exception {

NodeList elements = document.getElementsByTagName("infNFe");
org.w3c.dom.Element el = (org.w3c.dom.Element) elements.item(indexNFe);
String id = el.getAttribute("Id");

Reference ref = fac.newReference("#" + id,
fac.newDigestMethod(DigestMethod.SHA1, null), transformList,
null, null);

SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod(
CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null), fac
.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));

XMLSignature signature = fac.newXMLSignature(si, ki);

DOMSignContext dsc = new DOMSignContext(privateKey,
document.getDocumentElement().getElementsByTagName(NFE).item(indexNFe));
signature.sign(dsc);
}

private String assinaCancelametoInutilizacao(String xml,
String senha, String tagCancInut) throws Exception {
Document document = documentFactory(xml);

XMLSignatureFactory signatureFactory = XMLSignatureFactory
.getInstance("DOM");
ArrayList<Transform> transformList = signatureFactory(signatureFactory);
loadCertificates(senha, signatureFactory);

NodeList elements = document.getElementsByTagName(tagCancInut);
org.w3c.dom.Element el = (org.w3c.dom.Element) elements.item(0);
String id = el.getAttribute("Id");

Reference ref = signatureFactory.newReference("#" + id,
signatureFactory.newDigestMethod(DigestMethod.SHA1, null),
transformList, null, null);

SignedInfo si = signatureFactory.newSignedInfo(signatureFactory
.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
(C14NMethodParameterSpec) null), signatureFactory
.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
Collections.singletonList(ref));

XMLSignature signature = signatureFactory.newXMLSignature(si, keyInfo);

DOMSignContext dsc = new DOMSignContext(privateKey, document.getFirstChild());
signature.sign(dsc);

return outputXML(document);
}

private ArrayList<Transform> signatureFactory(
XMLSignatureFactory signatureFactory)
throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
ArrayList<Transform> transformList = new ArrayList<Transform>();
TransformParameterSpec tps = null;
Transform envelopedTransform = signatureFactory.newTransform(
Transform.ENVELOPED, tps);
Transform c14NTransform = signatureFactory.newTransform(
"http://www.w3.org/TR/2001/REC-xml-c14n-20010315", tps);

transformList.add(envelopedTransform);
transformList.add(c14NTransform);
return transformList;
}

private Document documentFactory(String xml) throws SAXException,
IOException, ParserConfigurationException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
Document document = factory.newDocumentBuilder().parse(
new ByteArrayInputStream(xml.getBytes()));
return document;
}

private void loadCertificates(String senha,
XMLSignatureFactory signatureFactory) throws Exception {

/**
* Para Certificados A3 Cartao usar: SmartCard.cfg;
* Para Certificados A3 Token usar: Token.cfg;
*/
Provider provider = new sun.security.pkcs11.SunPKCS11("SmartCard.cfg");
Security.addProvider(provider);

KeyStore ks = KeyStore.getInstance("pkcs11");
try {
ks.load(null, senha.toCharArray());
} catch (IOException e) {
throw new Exception("Senha do Certificado Digital incorreta ou Certificado inválido.");
}

KeyStore.PrivateKeyEntry pkEntry = null;
Enumeration<String> aliasesEnum = ks.aliases();
while (aliasesEnum.hasMoreElements()) {
String alias = (String) aliasesEnum.nextElement();
if (ks.isKeyEntry(alias)) {
pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias,
new KeyStore.PasswordProtection(senha.toCharArray()));
privateKey = pkEntry.getPrivateKey();
break;
}
}

X509Certificate cert = (X509Certificate) pkEntry.getCertificate();
info("SubjectDN: " + cert.getSubjectDN().toString());

KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
List<X509Certificate> x509Content = new ArrayList<X509Certificate>();

x509Content.add(cert);
X509Data x509Data = keyInfoFactory.newX509Data(x509Content);
keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data));
}

private String outputXML(Document doc) throws TransformerException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
trans.transform(new DOMSource(doc), new StreamResult(os));
String xml = os.toString();
if ((xml != null) && (!"".equals(xml))) {
xml = xml.replaceAll("\\r\\n", "");
xml = xml.replaceAll(" standalone=\"no\"", "");
}
return xml;
}

private static String lerXML(String fileXML) throws IOException {
String linha = "";
StringBuilder xml = new StringBuilder();

BufferedReader in = new BufferedReader(new InputStreamReader(
new FileInputStream(fileXML)));
while ((linha = in.readLine()) != null) {
xml.append(linha);
}
in.close();

return xml.toString();
}

/**
* Log ERROR.
*
* @param error
*/
private static void error(String error) {
System.out.println("| ERROR: " + error);
}

/**
* Log INFO.
*
* @param info
*/
private static void info(String info) {
System.out.println("| INFO: " + info);
}

}

Esta mensagem foi editada 2 vezes. Última atualização foi em 17/08/2017 16:37:48

pfugazza

JavaC Membro

Membro desde: 18/07/2017 16:25:41
Mensagens: 57
Localização: Rio de Janeiro
Offline

euclides, boa tarde.

Há uma (bela) discussão a respeito do e-Social aqui no JavaC (http://www.javac.com.br/jc/posts/list/2866-esocial.page). No entanto, dê uma olhada nesta postagem (http://www.javac.com.br/jc/posts/list/45/2866.page#14799, onde há dois pré-projetos, um deles faz assinatura de XML via certificado A3 e o outro envia para o e-Social um lote de eventos.

Até mais.
euclides

JavaC Membro

Membro desde: 15/08/2017 19:27:15
Mensagens: 5
Offline

pfugazza Muito obrigado! to acompanhando a discussão lá.
 
Índice dos Fóruns » Java Avançado
Ir para:   
Powered by JForum 2.1.9 © JForum Team