[code]
package desktop;
/*
- To change this template, choose Tools | Templates
- and open the template in the editor.
*/
import br.inf.portalfiscal.nfe.xsd.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.KeyStore;
import java.security.Provider;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import javax.swing.JOptionPane;
import javax.xml.crypto.dsig.CanonicalizationMethod;
import javax.xml.crypto.dsig.DigestMethod;
import javax.xml.crypto.dsig.Reference;
import javax.xml.crypto.dsig.SignatureMethod;
import javax.xml.crypto.dsig.SignedInfo;
import javax.xml.crypto.dsig.Transform;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;
import javax.xml.crypto.dsig.spec.TransformParameterSpec;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class AssXML
{
private static final String C14N_TRANSFORM_METHOD = “http://www.w3.org/TR/2001/REC-xml-c14n-20010315”;
private static final String PROVIDER_CLASS_NAME = “org.jcp.xml.dsig.internal.dom.XMLDSigRI”;
private static final String PROVIDER_NAME = “jsr105Provider”;
@SuppressWarnings(“unchecked”)
// atravez de outra classe chamo metodo assinar e passo os parametros
public void assinar(String caminhoXml, String caminhoCertificado, String senha, String caminhoXmlNovo, String tipo) throws Exception
{
// tipo
// ‘1’ - NFE
// ‘2’ - CANCELAMENTO
// ‘3’ - INUTILIZACAO
//
String tag = “”;
if(tipo.equals(“1”))
tag = “infNFe”;
else if (tipo.equals(“2”))
tag = “infCanc”;
else if (tipo.equals(“3”))
tag = “infInut”;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document docs = builder.parse(new File(caminhoXml));
// Obtem elemento do documento a ser assinado, será criado uma referencia para o mesmo
NodeList elements = docs.getElementsByTagName(tag);
Element el = (Element) elements.item(0);
String id = el.getAttribute(“Id”);
//System.out.println("Obtendo elemento ID (chave de acesso) do documento a ser assinado: "+id);
// Create a DOM XMLSignatureFactory that will be used to
// generate the enveloped signature.
String providerName = System.getProperty(PROVIDER_NAME, PROVIDER_CLASS_NAME);
XMLSignatureFactory fac = XMLSignatureFactory.getInstance(“DOM”, (Provider) Class.forName(providerName).newInstance());
//XMLSignatureFactory fac = XMLSignatureFactory.getInstance(“DOM”, new org.jcp.xml.dsig.internal.dom.XMLDSigRI());
// Create a Reference to the enveloped document (in this case,
// you are signing the whole document, so a URI of “” signifies
// that, and also specify the SHA1 digest algorithm and
// the ENVELOPED Transform.
ArrayList transformList = new ArrayList();
TransformParameterSpec tps = null;
Transform envelopedTransform = fac.newTransform(Transform.ENVELOPED,tps);
Transform c14NTransform = fac.newTransform(C14N_TRANSFORM_METHOD, tps);
transformList.add(envelopedTransform);
transformList.add(c14NTransform);
Reference ref = fac.newReference("#" + id, fac.newDigestMethod(DigestMethod.SHA1, null), transformList, null, null);
// Create the SignedInfo.
SignedInfo si = fac.newSignedInfo(fac.newCanonicalizationMethod( CanonicalizationMethod.INCLUSIVE,(C14NMethodParameterSpec) null), fac.newSignatureMethod(SignatureMethod.RSA_SHA1, null), Collections.singletonList(ref));
KeyStore ks = KeyStore.getInstance(“Windows-MY”, “SunMSCAPI”);
try{
ks.load(null, senha.toCharArray());
Enumeration aliasEnum = ks.aliases();
while (aliasEnum.hasMoreElements()) {
String aliasKey = (String) aliasEnum.nextElement();
if (ks.isKeyEntry(aliasKey)) {
System.out.println(aliasKey);
}
}
}catch(Exception e){
JOptionPane.showMessageDialog(null,“Erro ao acessar o certificado A3!\nVerifique se o mesmo esta conectado ao seu computador erro na classe AssXmlDesk”);
}
//KeyStore ks = KeyStore.getInstance(“PKCS12”);
//ks.load(new FileInputStream(caminhoCertificado), senha.toCharArray());
Enumeration aliasesEnum = ks.aliases();
String alias = “”;
while (aliasesEnum.hasMoreElements()) {
alias = (String) aliasesEnum.nextElement();
if (ks.isKeyEntry(alias)) {
//System.out.println(alias);
break;
}
}
//Original
//KeyStore ks = KeyStore.getInstance(“JKS”);
//ks.load(new FileInputStream(“santaclara.jks”), “RAIMUNDO”.toCharArray());
KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(senha.toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
// Create the KeyInfo containing the X509Data.
KeyInfoFactory kif = fac.getKeyInfoFactory();
List x509Content = new ArrayList();
// x509Content.add(cert.getSubjectX500Principal().getName());
x509Content.add(cert);
X509Data xd = kif.newX509Data(x509Content);
KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));
// Instantiate the document to be signed.
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
Document doc = dbf.newDocumentBuilder().parse(new FileInputStream(caminhoXml));
// Create a DOMSignContext and specify the RSA PrivateKey and
// location of the resulting XMLSignature’s parent element.
DOMSignContext dsc = new DOMSignContext(keyEntry.getPrivateKey(), doc.getDocumentElement());
// Create the XMLSignature, but don’t sign it yet.
XMLSignature signature = fac.newXMLSignature(si, ki);
// Marshal, generate, and sign the enveloped signature.
signature.sign(dsc);
// Output the resulting document.
OutputStream os = new FileOutputStream(caminhoXmlNovo);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer trans = tf.newTransformer();
/**
trans.setOutputProperty(OutputKeys.INDENT, “no”);
trans.setOutputProperty(OutputKeys.ENCODING, “UTF-8”);
trans.setOutputProperty(OutputKeys.MEDIA_TYPE, “text/xml”);
trans.setOutputProperty(OutputKeys.METHOD, “xml”);
*/
trans.transform(new DOMSource(doc), new StreamResult(os));
// Find Signature element.
NodeList nl = doc.getElementsByTagNameNS(XMLSignature.XMLNS, “Signature”);
if (nl.getLength() == 0) {
throw new Exception(“Cannot find Signature element”);
}
// Create a DOMValidateContext and specify a KeySelector and document
// context.
DOMValidateContext valContext = new DOMValidateContext( new X509KeySelector(ks), nl.item(0));
// Unmarshal the XMLSignature.
XMLSignature signatures = fac.unmarshalXMLSignature(valContext);
// Validate the XMLSignature.
boolean coreValidity = signatures.validate(valContext);
// Check core validation status.
if (coreValidity == false) {
System.err.println(“Falha na Assinatura!”);
JOptionPane.showMessageDialog(null, “Falha na Assinatura!”);
} else {
System.out.println(“XML assinado com sucesso!”);
JOptionPane.showMessageDialog(null, “XML assinado com sucesso!”);
}
}