XMLSignature

B

bouchia.nazha

Hello

I want to sign a xml file using MD5withRSA. I saw a sample in this
forum :


public static void main(String unused[]) throws Exception {


String keystoreType = "JKS";
String keystoreFile =
"data/org/apache/xml/security/­samples/input/keystore.jks";
String keystorePass = "xmlsecurity";
String privateKeyAlias = "test";
String privateKeyPass = "xmlsecurity";
String certificateAlias = "test";


// create DOM document
javax.xml.parsers.DocumentBuil­derFactory dbf =
javax.xml.parsers.DocumentBuil­derFactory.newInstance();


dbf.setNamespaceAware(true);
javax.xml.parsers.DocumentBuil­der db =
dbf.newDocumentBuilder();
org.w3c.dom.Document doc = db.newDocument();


// output file "signature.XML"
java.io.File signatureFile =
new File("signature.xml");


// URI
String BaseURI = signatureFile.toURL().toString­();


// prefix


org.apache.xml.security.utils.­Constants.setSignatureSpecNSpr­efix("ds");



// signature
org.apache.xml.security.signat­ure.XMLSignature sig =
new XMLSignature(doc, BaseURI,
XMLSignature.ALGO_ID_SIGNATURE­_DSA);


// add signature into document
doc.appendChild(sig.getElement­());


// resolver
String xml_to_sign = http://localhost/sample.xml;



org.apache.xml.security.sample­s.signature.NullURIReferenceRe­solver
null_URI =
new NullURIReferenceResolver(xml_t­o_sign.getBytes());


// add resolver to signature
sig.addResourceResolver(null_U­RI);


// transformations i canonicalization C14n
org.apache.xml.security.transf­orms.Transforms transforms =
new Transforms(doc);


// make transformations

transforms.addTransform(Transf­orms.TRANSFORM_ENVELOPED_SIGNA­TURE);

transforms.addTransform(Transf­orms.TRANSFORM_C14N_WITH_COMME­NTS);


// add document "http://localhost/sample.xml" to signature
sig.addDocument(xml_to_sign, transforms,
Constants.ALGO_ID_DIGEST_SHA1)­;


// contener of certificates and keys
java.security.KeyStore ks = KeyStore.getInstance(keystoreT­ype);



java.io.FileInputStream fis =
new FileInputStream(keystoreFile);


// initialization contener
ks.load(fis, keystorePass.toCharArray());


// certificate X509
java.security.cert.X509Certifi­cate cert =
(X509Certificate) ks.getCertificate(certificateA­lias);


// public key
java.security.PublicKey publicKey = cert.getPublicKey();


// private key
java.security.PrivateKey privateKey =
(PrivateKey) ks.getKey(privateKeyAlias,
privateKeyPass.toCharArray());


sig.addKeyInfo(cert);
sig.addKeyInfo(publicKey);
System.out.println("Start signing");
sig.sign(privateKey);
System.out.println("Finished signing");


// save into output file "signature.xml" DOM document
java.io.FileOutputStream fos =
new FileOutputStream(signatureFile­);
XMLUtils.outputDOMc14nWithComm­ents(doc, fos);
fos.close();


System.out.println("Wrote signature to " + BaseURI);
}



My question is why we use the classe Transform. It's necessary ?
Thanks for your help.
 
I

iksrazal

(e-mail address removed) escreveu:
Hello

I want to sign a xml file using MD5withRSA. I saw a sample in this
forum :

Seems like my code when I was just getting started a while back -
probably based on the samples included with the Apache XML Security
source. Here's the production code that occurred a bit later. I'm a bit
busy these days so I'm only checking this group infrequesntly.

package com.infoseg.mr.security;

import java.io.*;
import java.lang.reflect.*;
import java.security.*;
import java.security.cert.*;
import java.security.SecureRandom;
import javax.crypto.*;
import javax.crypto.spec.*;
import java.util.*;
import javax.xml.transform.TransformerException;
import java.util.regex.*;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.apache.xpath.XPathAPI;
import org.w3c.dom.*;
import org.apache.xml.security.algorithms.MessageDigestAlgorithm;
import org.apache.xml.security.c14n.*;
import org.apache.xml.security.exceptions.XMLSecurityException;
import org.apache.xml.security.signature.*;
import org.apache.xml.security.keys.*;
import org.apache.xml.security.keys.content.*;
import org.apache.xml.security.keys.content.x509.*;
import org.apache.xml.security.keys.keyresolver.*;
import org.apache.xml.security.keys.storage.*;
import org.apache.xml.security.keys.storage.implementations.*;
import org.apache.xml.security.utils.*;
import org.apache.xml.security.transforms.*;
import org.apache.xml.security.Init;
import org.apache.xml.serialize.*;
import org.apache.xpath.CachedXPathAPI;
import org.apache.xml.security.encryption.EncryptedData;
import org.apache.xml.security.encryption.XMLCipher;
import org.apache.crimson.tree.XmlDocument;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.dom.DOMSource;
import org.apache.xpath.XPathAPI;
import org.w3c.dom.*;

import gov.sefaz.fw.fwlog.Fwlog;

// problemas commum:
// NoSuchAlgorithmException
// SimpleDeserializer encountered a child element, which is NOT
expected

/** Classe que implementa WS-Security

@author Robert Lazarski
*/
public class SecurityHelper
{
/**
Assina digitalmente o documento XML
@param doc documento XML a ser processado
@param privateKey chave privada para Digital Signature Algorythm
(DSA)
@param cert Digital Certificate
@param boolean para debug
*/
public static boolean sign(Document doc, X509Certificate cert,
PrivateKey privateKey, boolean debug) throws WSSecurityException
{
try
{
//Add SecurityHelper.class header to the SOAP message if it does
not exist
String soap_header = "http://schemas.xmlsoap.org/soap/envelope/";
// Initialize the library - this is now done inside servlet
WSSInit
org.apache.xml.security.Init.init();

/******************* XML SIGNATURE INIT ***********************
Append the signature element to proper location before signing
***************************************************************/
// Look for the SOAP header
Element headerElement = null;
NodeList nodes = doc.getElementsByTagNameNS (soap_header,
"Header");
//No nodes are expected to be found (length of zero) - add
//header here.
if(nodes.getLength() == 0)
{
headerElement = doc.createElementNS (soap_header, "Header");
nodes = doc.getElementsByTagNameNS (soap_header, "Envelope");
if(nodes != null)
{
Element envelopeElement = (Element)nodes.item(0);
headerElement.setPrefix(envelopeElement.getPrefix());
envelopeElement.appendChild(headerElement);
}
}
else
{
//This shouldn't happen unless explicity done elsewhere
Fwlog.debug(SecurityHelper.class, Fwlog.WI, "Unexpectedly Found
" + nodes.getLength() + " SOAP Header elements... probably ok but not
tested");
headerElement = (Element)nodes.item(0);
}

// http://xml-security is the base-uri, which needs to be
//unique within document
XMLSignature sig = new XMLSignature(doc, "http://xml-security",
XMLSignature.ALGO_ID_SIGNATURE_DSA);
// Add SOAP Body to XML Signature
headerElement.appendChild(sig.getElement());
// Due to the bug in the Apache security lib, it does not allow
// us to sign whole message and make "enveloped-signature"
// transform - strictly part of the specification.
// Only sign the body - IT IS NOT CONFORMED TO THE SPEC!!!!!!
//
// Neat trick: since the XMLSignature is actually a part of the
// SOAP XML document, the SOAP body is referenced as a URI
// fragment
sig.addDocument("#Body");
/******************* END XML SIGNATURE INIT
*********************/

/****************** SIGN THE FUCKER *******************/
sig.addKeyInfo(cert);
sig.addKeyInfo(cert.getPublicKey());
// Sign the XML Signature document with our private key
sig.sign(privateKey);
/****************** FUCKER SIGNED *********************/
Fwlog.debug(SecurityHelper.class, Fwlog.WI, "SecurityHelper::sign
-- tudo bem...");
return true;
}
catch (Exception e)
{
Fwlog.error(SecurityHelper.class, Fwlog.WI, "SecurityHelper::sign
-- Exception: ");
Fwlog.error(SecurityHelper.class, Fwlog.WI, e);
throw new WSSecurityException("Could not digitally sign SOAP
message", e);
}
}

/**
Verifica a assinatura do documento XML
@param doc documento XML
@return boolean true se tem succeso, false no contrário
*/
public static boolean verify(Document doc) throws WSSecurityException
{
try
{
// Initialize the library - this is now done inside servlet
WSSInit
org.apache.xml.security.Init.init();

// must match baseURI
String baseURI = "http://xml-security";
CachedXPathAPI xpathAPI = new CachedXPathAPI();
Element nsctx = doc.createElement("nsctx");
nsctx.setAttribute("xmlns:ds", Constants.SignatureSpecNS);

Element signatureElem = (Element) xpathAPI.selectSingleNode(doc,
"//ds:Signature", nsctx);
// Check to make sure that the document claims to have been
signed
if (null == signatureElem)
{
throw new IllegalStateException ("SOAP Document not digitally
signed - missing element: //ds:Signature");
}

XMLSignature sig = new XMLSignature (signatureElem, baseURI);
boolean verify = sig.checkSignatureValue
(sig.getKeyInfo().getPublicKey());
if (true == verify)
{
Fwlog.debug(SecurityHelper.class, Fwlog.WI,
"SecurityHelper::verify -- tudo bem, returning true...");
return true;
}
}
catch (Exception e)
{
Fwlog.error(SecurityHelper.class, Fwlog.WI,
"SecurityHelper::verify -- Exception: ");
Fwlog.error(SecurityHelper.class, Fwlog.WI, e);
throw new WSSecurityException("Could not verify digitally signed
SOAP message", e);
}

// signature verification failed -
//do not forward request to SOAP Service.
return false;
}

/**
Encriptografa o documento XML

@param d documento XML
@param ename nome do elemento a encryptar
@param key chave privada
@param boolean para debug

* */
public static boolean encrypt(Document d, String ename, SecretKey
key, boolean debug) throws WSSecurityException
{
/******************* GET THE XML ELEMENT TO ENCRYPT **********/
Element e;
try
{
if (debug)
{
Fwlog.debug(SecurityHelper.class, Fwlog.WI, "soap xml doc
recieved in SecurityHelper::encrypt : " + XMLHelper.getXml(d));
}
// Initialize the library - this is now done inside servlet
WSSInit
org.apache.xml.security.Init.init();
if (debug)
{
Fwlog.debug(SecurityHelper.class, Fwlog.WI, "Encrypting
Element: " + ename);
}
if(null == ename)
{
throw new IllegalStateException("Tag name to encrypt is
null");
}
NodeList nodes = d.getElementsByTagName(ename);
if(0 == nodes.getLength())
{
Fwlog.error(SecurityHelper.class, Fwlog.WI, "***ENCRYPT ERROR
FROM THIS MESSAGE*** - reference tag not found: " + ename + " \n\n" +
XMLHelper.getXml(d));
throw new IllegalStateException("Cannot encrypt SOAP Message,
reference tag not found: " + ename);
}
else
{
e = (Element)nodes.item(0);
}

/******************* XML ELEMENT FOUND **************/


/******************* CHECK THE FUCKER *************/
if (null == key)
{
throw new IllegalStateException("Secret Key is null!!!");
}
if (null == e)
{
throw new IllegalStateException("Element to encrypt is
null!!!");
}
if (null == d)
{
throw new IllegalStateException("XML Document to encrypt is
null!!!");
}

if (debug)
{
Fwlog.debug(SecurityHelper.class, Fwlog.WI, "Before encryption
of node: " + ename + " " + XMLHelper.getNodeToString(nodes.item(0)));
}

/******************* FUCKER CHECKED *************/

/******************* ENCRYPT THE FUCKER *************/
XMLCipher cipher = XMLCipher.getInstance(XMLCipher.TRIPLEDES);
cipher.init(XMLCipher.ENCRYPT_MODE, key);
d = cipher.doFinal(d, e);
if (debug)
{
Fwlog.debug(SecurityHelper.class, Fwlog.WI, "After encryption:
" + XMLHelper.getXml(d));
}
/******************* FUCKER ENCRYPTED *************/
Fwlog.debug(SecurityHelper.class, Fwlog.WI,
"SecurityHelper::encrypt -- tudo bem...");
return true;
}
catch (Exception x)
{
Fwlog.error(SecurityHelper.class, Fwlog.WI,
"SecurityHelper::encrypt -- Exception: ");
Fwlog.error(SecurityHelper.class, Fwlog.WI, x);
throw new WSSecurityException("Could not encrypt SOAP message",
x);
}
}

/**
Remove criptografia do documento XML

@param d documento XML
@param ename nome do elemento a processar
@param key chave privada usando o DES algoryhtim
@param boolean para debug
*/
public static boolean decrypt(Document d, SecretKey key, boolean
debug) throws WSSecurityException
{
Element e;
try
{
// Initialize the library - this is now done inside servlet
WSSInit
org.apache.xml.security.Init.init();

// Check if we have previous errors from response. If so, throw
NodeList erro_nodes = d.getElementsByTagName("faultstring");
if(0 != erro_nodes.getLength())
{
Node nerror = erro_nodes.item(0);
String erro = nerror.getFirstChild().getNodeValue();
throw new IllegalStateException("Cannot recover from previous
error: " + erro);
}

/******************* DECRYPT THE FUCKER *************/
NodeList nodes = d.getElementsByTagName("xenc:EncryptedData");
if(0 == nodes.getLength())
{
Fwlog.error(SecurityHelper.class, Fwlog.WI, "***DECRYPT ERROR
FROM THIS MESSAGE*** - reference tag not found: :
xenc:EncryptedData:\n\n" + XMLHelper.getXml(d));
throw new IllegalStateException("Cannot decrypt SOAP Message,
reference tag not found: xenc:EncryptedData");
}
else
{
e = (Element)nodes.item(0);
}

/******************* CHECK THE FUCKER *************/

if (null == key)
{
throw new IllegalStateException("Secret Key is null!!!");
}
if (null == e)
{
throw new IllegalStateException("Element to decrypt is
null!!!");
}
if (null == d)
{
throw new IllegalStateException("XML Document to encrypt is
null!!!");
}

if (debug)
{
Fwlog.debug(SecurityHelper.class, Fwlog.WI, "Before decryption:
\n\n" + XMLHelper.getNodeToString(nodes.item(0)));
}

/******************* FUCKER CHECKED *************/

/******************* DECRYPT THE FUCKER *************/
XMLCipher cipher = XMLCipher.getInstance(XMLCipher.TRIPLEDES);
cipher.init(XMLCipher.DECRYPT_MODE, key);
d = cipher.doFinal(d, e);
if (debug)
{
Fwlog.debug(SecurityHelper.class, Fwlog.WI, "After decryption:
" + XMLHelper.getXml(d));
}
/******************* FUCKER DECRYPTED *************/
Fwlog.debug(SecurityHelper.class, Fwlog.WI,
"SecurityHelper::decrypt -- tudo bem...");
return true;
}
catch (Exception x)
{
Fwlog.error(SecurityHelper.class, Fwlog.WI,
"SecurityHelper::decrypt -- Exception: ");
Fwlog.error(SecurityHelper.class, Fwlog.WI, x);
throw new WSSecurityException("Could not decrypt SOAP message",
x);
}
}
}


HTH,
iksrazal
http://www.braziloutsource.com/
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,002
Messages
2,570,261
Members
46,859
Latest member
VallieMcKe

Latest Threads

Top