All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.pablodomingos.assinatura.AssinaturaDigital Maven / Gradle / Ivy

package com.pablodomingos.assinatura;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
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.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class AssinaturaDigital {
  private static String INFRPS = "InfRps";
  private static String[] ELEMENTOS_ASSINAVEIS = new String[]{"LoteRps", "InfPedidoCancelamento"};
  private CertificadoConfig config;

  public AssinaturaDigital(CertificadoConfig config) {
    this.config = config;
  }

  public String assinarXML(String xml) throws Exception {
    String certificateAlias = config.getAliasCertificado() != null ? config.getAliasCertificado()
        : config.getCertificadoKeyStore().aliases().nextElement();
    KeyStore.PasswordProtection passwordProtection =
        new KeyStore.PasswordProtection(this.config.getSenhaCertificado().toCharArray());
    KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry) config.getCertificadoKeyStore()
        .getEntry(certificateAlias, passwordProtection);

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

    X509Certificate cert = (X509Certificate) pkEntry.getCertificate();

    KeyInfoFactory keyInfoFactory = signatureFactory.getKeyInfoFactory();
    List x509Content = new ArrayList();
    x509Content.add(cert);
    X509Data x509Data = keyInfoFactory.newX509Data(x509Content);
    KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data));

    Document document = documentFactory(xml);

    //Assinando todos RPS
    NodeList elements = document.getElementsByTagName(INFRPS);
    for (int i = 0; i < elements.getLength(); i++) {
      Element element = (Element) elements.item(i);
      
      String id = element.getAttribute("Id");
      element.setIdAttribute("Id", true);

      Reference reference = signatureFactory.newReference("#" + id, signatureFactory.newDigestMethod(DigestMethod.SHA1, null), transformList, null, null);
      SignedInfo signedInfo = signatureFactory.newSignedInfo( signatureFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
              (C14NMethodParameterSpec) null), signatureFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
          Collections.singletonList(reference));

      XMLSignature signature = signatureFactory.newXMLSignature(signedInfo, keyInfo);
      signature.sign(new DOMSignContext(pkEntry.getPrivateKey(), element.getParentNode()));
    }
 
    Document documentAssinado = documentFactory(converteDocParaXml(document));
    
    //Assinando o Lote de RPS
    for (final String elementoAssinavel : AssinaturaDigital.ELEMENTOS_ASSINAVEIS) {
      NodeList elementsAssinado = documentAssinado.getDocumentElement().getElementsByTagName(elementoAssinavel);
      for (int i = 0; i < elementsAssinado.getLength(); i++) {
        Element element = (Element) elementsAssinado.item(i);
        
        String id = element.getAttribute("Id");
        element.setIdAttribute("Id", true);

        Reference reference = signatureFactory.newReference("#" + id, signatureFactory.newDigestMethod(DigestMethod.SHA1, null), transformList, null, null);
        SignedInfo signedInfo = signatureFactory.newSignedInfo( signatureFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE,
                (C14NMethodParameterSpec) null), signatureFactory.newSignatureMethod(SignatureMethod.RSA_SHA1, null),
            Collections.singletonList(reference));

        XMLSignature signature = signatureFactory.newXMLSignature(signedInfo, keyInfo);
        signature.sign(new DOMSignContext(pkEntry.getPrivateKey(), element.getParentNode()));
      }
    }
    
    
    return converteDocParaXml(documentAssinado);
  }

  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 signatureFactory(XMLSignatureFactory signatureFactory)
      throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
    ArrayList transformList = new ArrayList();
    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 String converteDocParaXml(Document doc) throws TransformerException {
    ByteArrayOutputStream os = new ByteArrayOutputStream();
    Transformer trans = TransformerFactory.newInstance().newTransformer();
    trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
    trans.transform(new DOMSource(doc), new StreamResult(os));
    return os.toString();
}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy