Extending XSLT to Encrypt XML on the Fly: Code
Listings
[ Back to
Article ]
This section contains the complete code listings for the example we've
discussed here. When running this example, my CLASSPATH
contained the following files, in order:
xss4j.jar, from the 26 April 2001 version of the XML
Security Suite
xalan.jar and xerces.jar, from version 2.1.0
of the Xalan XSLT processor
ibmjceprovider.jar and ibmjcefw.jar, IBM's
JCE 1.2.1 implementation. In theory, anyone's JCE implementation should
work, but I haven't tested them.
EncryptionExtension.java
Notice that we try to catch a number of different exceptions in the
code.
import com.ibm.xml.enc.XEncryption;
import com.ibm.xml.enc.StructureException;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StringReader;
import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.KeyStore;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import org.apache.xerces.parsers.DOMParser;
import org.apache.xpath.DOMHelper;
import org.apache.xpath.objects.XNodeSet;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
public class EncryptionExtension
{
public static XNodeSet encryptNode(NodeList nl, String passPhrase,
String keyStore, String keyName,
String encryptionTemplate)
{
XNodeSet encryptedResult = null;
XEncryption xenc = new XEncryption();
Document doc;
Element ee = null, encrypted = null;
try
{
DOMParser parser = new DOMParser();
parser.setIncludeIgnorableWhitespace(false);
parser.parse(encryptionTemplate);
doc = parser.getDocument();
ee = doc.getDocumentElement();
Element ek = (Element)(ee.getElementsByTagName("EncryptedKey").item(0));
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(keyStore), passPhrase.toCharArray());
Key k = null;
if (ks.isKeyEntry(keyName))
k = (ks.getCertificate(keyName)).getPublicKey();
encrypted = xenc.encrypt((Element)nl.item(0), false, ee, k, ek);
encryptedResult = new XNodeSet(encrypted);
}
catch (com.ibm.xml.enc.StructureException se)
{
System.out.println("SE: " + se);
}
catch (java.security.InvalidAlgorithmParameterException iape)
{
System.out.println("IAPE: " + iape);
}
catch (java.security.InvalidKeyException ike)
{
System.out.println("IKE: " + ike);
}
catch (java.security.NoSuchAlgorithmException nsae)
{
System.out.println("NSAE: " + nsae);
}
catch (javax.crypto.NoSuchPaddingException nspe)
{
System.out.println("NSPE: " + nspe);
}
catch (java.security.NoSuchProviderException snspe)
{
System.out.println("SNSPE: " + snspe);
}
catch (GeneralSecurityException gse)
{
System.out.println("GeneralSecurityException: " + gse.getMessage());
}
catch (IOException ioe)
{
System.out.println("IOException: " + ioe);
}
catch (org.xml.sax.SAXException se)
{
System.out.println("SAXException: " + se);
}
return encryptedResult;
}
}
custorder.xml
<?xml version="1.0"?>
<customer_order>
<items>
<item>
<name>Turnip Twaddler</name>
<qty>3</qty>
<price>9.95</price>
</item>
<item>
<name>Snipe Curdler</name>
<qty>1</qty>
<price>19.95</price>
</item>
</items>
<customer>
<name>Doug Tidwell</name>
<street>1234 Main Street</street>
<city state="NC">Raleigh</city>
<zip>11111</zip>
</customer>
<credit_payment>
<card_issuer>American Express</card_issuer>
<card_number>1234 567890 12345</card_number>
<expiration_date month="10" year="2004"/>
</credit_payment>
</customer_order>
crypto-details.xml
<?xml version="1.0"?>
<EncryptedData xmlns="http://www.w3.org/2000/11/temp-xmlenc"
Type="Element">
<EncryptedKey>
<EncryptionMethod Algorithm="urn:rsadsi-com:rsa-v1.5"/>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<KeyName>key</KeyName>
</KeyInfo>
</EncryptedKey>
<EncryptionMethod Algorithm="urn:nist-gov:tripledes-ede-cbc"/>
</EncryptedData>
encrypt.xsl
<?xml version="1.0"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:encrypt="EncryptionExtension"
extension-element-prefixes="encrypt">
<xsl:output method="xml"/>
<xsl:template match="/">
<xsl:apply-templates select="*"/>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates select="*|text()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()">
<xsl:value-of select="normalize-space(.)"/>
</xsl:template>
<xsl:template match="credit_payment">
<xsl:copy-of select="encrypt:encryptNode(., 'storepass',
'keystore', 'key', 'crypto-details.xml')"/>
</xsl:template>
</xsl:stylesheet>
[ Back to
Article ]