Ir ao conteúdo
  • Cadastre-se
diegodm

Assinar todo xml com certificado digital

Recommended Posts

Pessoal, já consegui fazer assinar um arquivo XML da NFS-e com uma Tag e com duas Tags. Mas neste caso a Tag sempre tem um ID. Preciso agora para uma outra prefeitura assinar todo arquivo XML, mas ele não possuí uma Tag específica e nem possuí Id.

 

Preciso assinar o arquivo XML abaixo.

<ns3:esConsultarNfsePorRpsEnvio xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns:ns3="http://www.equiplano.com.br/esnfs"><rps><nrRps>200</nrRps><nrEmissorRps>100</nrEmissorRps></rps><prestador><nrInscricaoMunicipal>100</nrInscricaoMunicipal><cnpj>03740709000189</cnpj><idEntidade>12</idEntidade></prestador></ns3:esConsultarNfsePorRpsEnvio>

 

Em um outro software eles especificam desta maneira: informar a tag que será assinada Ex. infRps para RPS, LoteRps para Lote de RPS, etc., se omitida (""), a assinatura será realizada na tag raiz do XML. Mas não estou conseguindo fazer isso no Java.

 

Vou postar os códigos que estou utilizando de assinatura de Duas Tags. Ele carrega tanto o certificado instalado no Windows como o arquivo do certificado. Vou deixar o código completo caso alguém tenha dificuldade em carregar um certificado A1 ou na assinatura de duas tags.

 

CarregaCertificadoA1 carregaCertificadoArquivo = new CarregaCertificadoA1();
CertificadoA1 certificadoA1Arquivo = new CertificadoA1();
certificadoA1Arquivo = carregaCertificadoArquivo.certificadoArquivo("C:/TMP/CertificadoA1.pfx", "1234", TiposKeyStore.PKCS12);
        
CarregaCertificadoA1 carregaCertificadoWindows = new CarregaCertificadoA1();
CertificadoA1 certificadoA1Windows = new CertificadoA1();
certificadoA1Windows = carregaCertificadoWindows.certificadoWindows("agricola e comercia:9294403", "");
        
AssinadorXMLNovo assinaWindows = new AssinadorXMLNovo();
System.out.println(assinaWindows.assinaNFSe("c:/tmp/XMLAssinar.xml", certificadoA1Windows));
        
AssinadorXMLNovo assinaArquivo = new AssinadorXMLNovo();
System.out.println(assinaWindows.assinaNFSe("c:/tmp/XMLAssinar.xml", certificadoA1Arquivo));

 

package br.com.astersoft.nfse.certificado;

import java.security.PrivateKey;

import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;

public class CertificadoA1 {
	
	private XMLSignatureFactory signatureFactory;
	private PrivateKey privateKey;
	private KeyInfo keyInfo;
	public XMLSignatureFactory getSignatureFactory() {
		return signatureFactory;
	}
	public void setSignatureFactory(XMLSignatureFactory signatureFactory) {
		this.signatureFactory = signatureFactory;
	}
	public PrivateKey getPrivateKey() {
		return privateKey;
	}
	public void setPrivateKey(PrivateKey privateKey) {
		this.privateKey = privateKey;
	}
	public KeyInfo getKeyInfo() {
		return keyInfo;
	}
	public void setKeyInfo(KeyInfo keyInfo) {
		this.keyInfo = keyInfo;
	}
	
	

}
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;

import java.io.*;  
import java.security.*;  
import java.util.Collections;  
import javax.xml.crypto.MarshalException;  
import javax.xml.crypto.dsig.*;  
import javax.xml.crypto.dsig.dom.DOMSignContext;  
import javax.xml.crypto.dsig.keyinfo.KeyInfo;  
import javax.xml.crypto.dsig.spec.C14NMethodParameterSpec;  
import javax.xml.crypto.dsig.spec.TransformParameterSpec;  
import javax.xml.transform.Transformer;  
import javax.xml.transform.TransformerException;  
import javax.xml.transform.TransformerFactory;  
import javax.xml.transform.dom.DOMSource;  
import javax.xml.transform.stream.StreamResult;  
import org.w3c.dom.NodeList;  
import org.xml.sax.SAXException;

import br.com.astersoft.nfse.certificado.CertificadoA1;  


public class AssinadorXMLNovo {
	
	private static final String RPS = "Rps";  
    private static final String EnviarLoteRpsEnvio = "LoteRps";  
    private ArrayList<Transform> transformList;  
    private Document document; 
    private NodeList elements;  
    private org.w3c.dom.Element el;
    private Reference ref;  
    private SignedInfo si; 
    private XMLSignature signature;  
    private DOMSignContext dsc;  
    
	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 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 void assinaLoteRpsNFSe(String tipo, XMLSignatureFactory fac,  
	            ArrayList<Transform> transformList, PrivateKey privateKey,  
	            KeyInfo ki, Document document, int indexNFe) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, MarshalException, XMLSignatureException, javax.xml.crypto.MarshalException  
	    {  
	        if(tipo.equals(EnviarLoteRpsEnvio))  
	        {  
	            this.elements = this.document.getDocumentElement().getElementsByTagName("LoteRps");  
	        }  
	        if(tipo.equals(RPS))  
	        {  
	            this.elements = this.document.getElementsByTagName("InfRps");  
	        }  
	          
	        this.el = (org.w3c.dom.Element) this.elements.item(indexNFe);  
	        String id = el.getAttribute("Id");
	        el.setIdAttribute("Id", true);

	        this.ref = fac.newReference("#" + id,  
	                fac.newDigestMethod(DigestMethod.SHA1, null), transformList,  
	                null, null);  
	        this.si = fac.newSignedInfo(fac.newCanonicalizationMethod(  
	                CanonicalizationMethod.INCLUSIVE,  
	                (C14NMethodParameterSpec) null), fac  
	                .newSignatureMethod(SignatureMethod.RSA_SHA1, null),  
	                Collections.singletonList(ref));  
	        this.signature = fac.newXMLSignature(si, ki);  
	        this.dsc = new DOMSignContext(privateKey,   
	                /*document.getDocumentElement().getElementsByTagName(tipo).item(indexNFe)*/document.getFirstChild());  
	        this.signature.sign(this.dsc);  
	    }  
	 
	 private void assinaInfRpsNFSe(String tipo, XMLSignatureFactory fac,  
	            ArrayList<Transform> transformList, PrivateKey privateKey,  
	            KeyInfo ki, Document document, int indexNFe) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException, MarshalException, XMLSignatureException, javax.xml.crypto.MarshalException  
	    {  
	        if(tipo.equals(EnviarLoteRpsEnvio))  
	        {  
	            this.elements = this.document.getDocumentElement().getElementsByTagName("LoteRps");  
	        }  
	        if(tipo.equals(RPS))  
	        {  
	            this.elements = this.document.getElementsByTagName("InfRps");  
	        }  
	          
	        this.el = (org.w3c.dom.Element) this.elements.item(indexNFe);  
	        String id = el.getAttribute("Id");  
	        el.setIdAttribute("Id", true);
	        this.ref = fac.newReference("#" + id,  
	                fac.newDigestMethod(DigestMethod.SHA1, null), transformList,  
	                null, null);  
	        this.si = fac.newSignedInfo(fac.newCanonicalizationMethod(  
	                CanonicalizationMethod.INCLUSIVE,  
	                (C14NMethodParameterSpec) null), fac  
	                .newSignatureMethod(SignatureMethod.RSA_SHA1, null),  
	                Collections.singletonList(ref));  
	        this.signature = fac.newXMLSignature(si, ki);  
	        this.dsc = new DOMSignContext(privateKey,   
	                document.getDocumentElement().getElementsByTagName(tipo).item(indexNFe));  
	        this.signature.sign(this.dsc);  
	    }  
	 
	 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;  
	    } 
	 
	 public static String lerXML(String fileXML) throws IOException   
	    {  
	        String linha = "";  
	        StringBuilder xml = new StringBuilder();  
	  
	        BufferedReader in = new BufferedReader(new InputStreamReader(  
	                        new FileInputStream(fileXML), "ISO8859-1"));  
	        while ((linha = in.readLine()) != null) {  
	                xml.append(linha);  
	        }  
	        in.close();  
	  
	        return xml.toString();  
	    }  
	
	public String assinaNFSe(String caminhoXML, CertificadoA1 certificadoA1) throws Exception  
    {  
		
        String arquivoXML = lerXML(caminhoXML);
        this.document = documentFactory(arquivoXML);  
        this.transformList = signatureFactory(certificadoA1.getSignatureFactory());  
  
          
        assinaLoteRpsNFSe(EnviarLoteRpsEnvio, certificadoA1.getSignatureFactory(), this.transformList, certificadoA1.getPrivateKey(),   
        		certificadoA1.getKeyInfo(), this.document, 0);  
          
        for (int i = 0; i < this.document.getDocumentElement().getElementsByTagName(RPS).getLength(); i++)  
        {  
            assinaInfRpsNFSe(RPS, certificadoA1.getSignatureFactory(), this.transformList, certificadoA1.getPrivateKey(),   
            		certificadoA1.getKeyInfo(), this.document, i);  
        }  
        return outputXML(this.document);  
    }  

}
package br.com.astersoft.nfse.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.UnrecoverableEntryException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.X509Data;

import br.com.astersoft.nfse.certificado.CertificadoA1;

public class CarregaCertificadoA1 {

	private XMLSignatureFactory signatureFactory;
	private PrivateKey privateKey;
	private KeyInfo keyInfo;

	public CertificadoA1 certificadoArquivo(String caminhoKeyStore, String senha, TiposKeyStore tipoKeystore)
			throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException,
			IOException, UnrecoverableEntryException {
		char[] senhaCertificado = senha.toCharArray();
		signatureFactory = XMLSignatureFactory.getInstance("DOM");
		KeyStore ks = KeyStore.getInstance(tipoKeystore.getValue());
		ks.load(new java.io.FileInputStream(caminhoKeyStore), senhaCertificado);

		KeyStore.PrivateKeyEntry pkEntry = null;
		Enumeration<String> aliasesEnum = null;

		aliasesEnum = ks.aliases();

		while (aliasesEnum.hasMoreElements()) {
			String alias = aliasesEnum.nextElement();
			if (ks.isKeyEntry(alias)) {
				pkEntry = (KeyStore.PrivateKeyEntry) ks.getEntry(alias, new KeyStore.PasswordProtection(senhaCertificado));
				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));
		
		CertificadoA1 certificadoA1 = new CertificadoA1();
		certificadoA1.setKeyInfo(keyInfo);
		certificadoA1.setPrivateKey(privateKey);
		certificadoA1.setSignatureFactory(signatureFactory);
		
		return certificadoA1;

	}

	public CertificadoA1 certificadoWindows(String certificado, String senha) throws KeyStoreException, NoSuchProviderException,
			NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableEntryException {

		signatureFactory = XMLSignatureFactory.getInstance("DOM");

		KeyStore ks = null;

		ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");

		ks.load(null, null);

		KeyStore.PrivateKeyEntry pkEntry = null;
		Enumeration<String> aliasesEnum = null;

		aliasesEnum = ks.aliases();

		while (aliasesEnum.hasMoreElements()) {
			String alias = certificado;
			// 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));
		
		CertificadoA1 certificadoA1 = new CertificadoA1();
		certificadoA1.setKeyInfo(keyInfo);
		certificadoA1.setPrivateKey(privateKey);
		certificadoA1.setSignatureFactory(signatureFactory);
		
		return certificadoA1;

	}


}

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora





Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas publicações sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×