package gov.pr.celepar.teste;
/*
Este programa � licenciado de acordo com a
LPG-AP (LICEN�A P�BLICA GERAL PARA PROGRAMAS DE COMPUTADOR DA ADMINISTRA��O P�BLICA),
vers�o 1.1 ou qualquer vers�o posterior.
A LPG-AP deve acompanhar todas PUBLICA��ES, DISTRIBUI��ES e REPRODU��ES deste Programa.
Caso uma c�pia da LPG-AP n�o esteja dispon�vel junto com este Programa,
voc� pode contatar o LICENCIANTE ou ent�o acessar diretamente:
http://www.celepar.pr.gov.br/licenca/LPG-AP.pdf
Para poder USAR, PUBLICAR, DISTRIBUIR, REPRODUZIR ou ALTERAR este Programa
� preciso estar de acordo com os termos da LPG-AP
*/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.GregorianCalendar;
import java.util.Locale;
import com.sun.org.apache.xml.internal.security.Init;
import com.sun.org.apache.xml.internal.security.signature.ObjectContainer;
import com.sun.org.apache.xml.internal.security.signature.XMLSignature;
import com.sun.org.apache.xml.internal.security.transforms.Transforms;
import com.sun.org.apache.xml.internal.security.utils.Constants;
import com.sun.org.apache.xml.internal.security.utils.IdResolver;
import com.sun.org.apache.xml.internal.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class AssinarEnveloping {
public static Document createXMLDocument() throws Exception {
javax.xml.parsers.DocumentBuilderFactory dbf =
javax.xml.parsers.DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
javax.xml.parsers.DocumentBuilder db;
db = dbf.newDocumentBuilder();
org.w3c.dom.Document doc = db.newDocument();
return doc;
}
public static void main(String[] args) throws Exception {
Init.init();
String xadesNS="http://uri.etsi.org/01903/v1.3.2#";
String signedPropID="SignedProperties";
String endNomeArquivo= "/home/esaito/arquivosXML_Assinatura/Enveloping_Contra.xml";
//Document docXML = carregaXML(new FileInputStream("/home/esaito/arquivosXML_Assinatura/content.xml"));
//Document docXML = carregaXML(new FileInputStream("/home/esaito/arquivosXML_Assinatura/nfe_assinar.xml"));
//Document docXML = carregaXML(new FileInputStream("/home/esaito/arquivosXML_Assinatura/NotaDeCompra.xml"));
Document docXML = carregaXML(new FileInputStream(endNomeArquivo));
int tamNomeArquivo = endNomeArquivo.length() - 4 ;
endNomeArquivo = endNomeArquivo.substring(0, tamNomeArquivo);
// final String prefix = "";
Document xmlDocument = createXMLDocument();
Node oldDocument = xmlDocument.importNode(docXML.getFirstChild(), true);
Constants.setSignatureSpecNSprefix("");
XMLSignature xmlSignature = new XMLSignature(xmlDocument, "", XMLSignature.ALGO_ID_SIGNATURE_RSA);
xmlDocument.appendChild(xmlSignature.getElement());
ObjectContainer obj = new ObjectContainer(xmlDocument);
obj.appendChild((Element)oldDocument);
xmlSignature.appendObject(obj);
String idObjeto = "";
// Verifica se h� outras assinaturas, isso influenciar� no Id do Objeto.
NodeList xmlSignatureElements = docXML.getElementsByTagName("Signature");
if (xmlSignatureElements.getLength() > 0){
Element sigElement = (Element) xmlSignatureElements.item(0);
XMLSignature assinatura = new XMLSignature(sigElement, "");
// Verifica se existe o objeto envelopado
if (assinatura.getObjectLength() > 0){
idObjeto = assinatura.getObjectItem(0).getId()+assinatura.getObjectLength();
System.out.println("idObjeto : "+idObjeto);
}
}else{
idObjeto="object";
}
//docXML.getElementsByTagNameNS(XMLSignature...XMLNS, "Signature");
// A principio n�o h� Contra-Assinatura em enveloping
/*
String contraAssinatura = "S";
NodeList contraAssinaturaNL = null;
if (contraAssinatura != null && !contraAssinatura.equalsIgnoreCase("")) {
if (xmlSignatureElements.getLength() < 1){
throw new Exception("N�o h� assinatura para contra-assinar");
}else{
contraAssinaturaNL = xmlSignatureElements;
}
}*/
// carrega cert.
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("/home/esaito/workspace/exercicios/exercicios/assinaturaXML/tabeliao_icp.jks"),
"pinhaoprod".toCharArray());
KeyStore.PrivateKeyEntry keyEntry =
(KeyStore.PrivateKeyEntry) ks.getEntry
("www.tabeliao.eparana.parana", new KeyStore.PasswordProtection("pinhaoprod".toCharArray()));
X509Certificate cert = (X509Certificate) keyEntry.getCertificate();
// gera o objeto de propriedades assinadas.
Element QPElement = createElement(xmlDocument,"QualifyingProperties",null,xadesNS);
Element SPElement = createElement(xmlDocument, "SignedProperties", null,xadesNS);
//SPElement.setAttributeNS(null, "Id", signedPropID);
//SPElement.setAttributeNS(null, "Target", signatureID);
IdResolver.registerElementById(SPElement, signedPropID);
QPElement.appendChild(SPElement);
Element SSPElement = createElement(xmlDocument, "SignedSignatureProperties", null,xadesNS);
SPElement.appendChild(SSPElement);
Element STElement = createElement(xmlDocument, "SigningTime", null,xadesNS);
Locale locale = new Locale("pt","BR");
GregorianCalendar calendar = new GregorianCalendar();
SimpleDateFormat formatador = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ",locale);
STElement.setTextContent(formatador.format(calendar.getTime()));
SSPElement.appendChild(STElement);
Element SCElement = createElement(xmlDocument, "SigningCertificate", null,xadesNS);
Element certElement = createElement(xmlDocument, "cert", null,xadesNS);
Element certDigestElement = createElement(xmlDocument, "CertDigest", null,xadesNS);
Element DigestMethodElement = createElement(xmlDocument, "DigestMethod", null,xadesNS);
DigestMethodElement.setAttributeNS(null,"Algorithm", cert.getSigAlgName());
certDigestElement.appendChild(DigestMethodElement);
Element DigestValueElement = createElement(xmlDocument, "DigestValue", null,xadesNS);
DigestValueElement.setTextContent(Integer.toString(cert.hashCode()));
certDigestElement.appendChild(DigestValueElement);
certElement.appendChild(certDigestElement);
Element certIssuerSerial = createElement(xmlDocument, "IssuerSerial", null,xadesNS);
Element X509IssuerName = createElement(xmlDocument, "X509IssuerName", null,xadesNS);
X509IssuerName.setTextContent(cert.getIssuerDN().getName());
certIssuerSerial.appendChild(X509IssuerName);
Element X509SerialNumber = createElement(xmlDocument, "X509SerialNumber", null,xadesNS);
X509SerialNumber.setTextContent(cert.getSerialNumber().toString());
certIssuerSerial.appendChild(X509SerialNumber);
certElement.appendChild(certIssuerSerial);
SCElement.appendChild(certElement);
// SCElement.setTextContent(cert.getSubjectX500Principal().getName());
SSPElement.appendChild(SCElement);
Element SPIElement = createElement(xmlDocument, "SignaturePolicyIdentifier", null,xadesNS);
Element SPIdElement = createElement(xmlDocument, "SignaturePolicyId", null,xadesNS);
Element SiPIdElement = createElement(xmlDocument, "SigPolicyId", null,xadesNS);
SiPIdElement.setTextContent("xmlDocument-ICP-15.02");
//Element SPHElement = createElement(xmlDocument, "SigPolicyHash", null,xadesNS);
Element SPQElement = createElement(xmlDocument, "SigPolicyQualifiers", null,xadesNS);
Element SPQrElement = createElement(xmlDocument, "SigPolicyQualifier", null,xadesNS);
Element SPUriElement = createElement(xmlDocument, "SPURI", null,xadesNS);
SPUriElement.setTextContent("www.iti.gov.br");
SPQrElement.appendChild(SPUriElement);
SPQElement.appendChild(SPQrElement);
SPIdElement.appendChild(SiPIdElement);
//SPIdElement.appendChild(SPHElement);
SPIdElement.appendChild(SPQElement);
SPIElement.appendChild(SPIdElement);
SSPElement.appendChild(SPIElement);
Element SPPElement = createElement(xmlDocument, "SignatureProductionPlace", null,xadesNS);
SSPElement.appendChild(SPPElement);
Element SRElement = createElement(xmlDocument, "SignerRole", null,xadesNS);
SSPElement.appendChild(SRElement);
Element SDOPElement = createElement(xmlDocument, "SignedDataObjectProperties", null,xadesNS);
SPElement.appendChild(SDOPElement);
Element DOFElement = createElement(xmlDocument, "DataObjectFormat", null,xadesNS);
//DOFElement.setAttributeNS("null","ObjectReference", "#reference-1-1");
Element mimetype = createElement(xmlDocument,"MimeType",null,xadesNS);
mimetype.setTextContent("application/xml");
DOFElement.appendChild(mimetype);
SDOPElement.appendChild(DOFElement);
/*if (contraAssinaturaNL != null ) {
Node contraNode = contraAssinaturaNL.item(0);
Element UPElement = createElement(xmlDocument, "UnsignedProperties", null,xadesNS);
Element CSElement = createElement(xmlDocument, "CounterSignature", null,xadesNS);
//CSElement.appendChild(contraNode);
CSElement.setNodeValue(contraNode.toString());
UPElement.appendChild(CSElement);
QPElement.appendChild(UPElement);
}*/
obj.appendChild(QPElement);
obj.setId(idObjeto);
xmlSignature.appendObject(obj);
Transforms transforms = new Transforms(xmlDocument);
transforms.addTransform(Transforms.TRANSFORM_C14N_WITH_COMMENTS);
xmlSignature.addDocument("#" + idObjeto, transforms, Constants.ALGO_ID_DIGEST_SHA1);
// Load the KeyStore and get the signing key and certificate.
xmlSignature.addKeyInfo(cert);
xmlSignature.sign(keyEntry.getPrivateKey());
XMLUtils.outputDOMc14nWithComments(xmlDocument, new FileOutputStream(endNomeArquivo+"_Co_assinado_teste.xml"));
//XMLUtils.outputDOM(xmlDocument, new FileOutputStream("/home/esaito/arquivosXML_Assinatura/Enveloping_assinado.xml"));
System.out.println("OK");
}
public static org.w3c.dom.Document carregaXML(InputStream xmlFile) throws Exception {
javax.xml.parsers.DocumentBuilderFactory dbf =
javax.xml.parsers.DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
org.w3c.dom.Document doc = null;
javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
doc = db.parse(xmlFile);
return doc;
}
public static Element createElement(Document doc, String tag, String prefix, String nsURI) {
String qName = prefix == null ? tag : prefix + ":" + tag;
return doc.createElementNS(nsURI, qName);
}
}