Listing 1 : XML file
<?xml version='1.0'?>
<PaymentInfo xmlns='http://example.org/paymentv2'>
<Name>John Doe</Name>
<CreditCard Limit='5,000' Currency='USD'>
<Number>4019 2445 0277 5567</Number>
<Issuer>Example Bank</Issuer>
<Expiration>04/04</Expiration>
</CreditCard>
</PaymentInfo>
Listing 2: Structure of encrypted data
<EncryptedData Id? Type? MimeType? Encoding?>
<EncryptionMethod/>?
<ds:KeyInfo>
<EncryptedKey>?
<AgreementMethod>?
<ds:KeyName>?
<ds:RetrievalMethod>?
<ds:*>?
</ds:KeyInfo>?
<CipherData>
<CipherValue>?
<CipherReference URI?>?
</CipherData>
<EncryptionProperties>?
</EncryptedData>
Listing 3: XML file to be encrypted
<?xml version='1.0'?>
<PaymentInfo xmlns='http://example.org/paymentv2'>
<Name>John Doe</Name>
<CreditCard Limit='5,000' Currency='USD'>
<Number>4019 2445 0277 5567</Number>
<Issuer>Example Bank</Issuer>
<Expiration>04/04</Expiration>
</CreditCard>
</PaymentInfo>
Listing 4 : Encrypted XML element
<?xml version='1.0'?>
<PaymentInfo xmlns='http://example.org/paymentv2'>
<Name>John Smith</Name>
<EncryptedData Type='http://www.w3.org/2001/04/xmlenc#Element'
xmlns='http://www.w3.org/2001/04/xmlenc#'>
<CipherData>
<CipherValue>A23B45C56</CipherValue>
</CipherData>
</EncryptedData>
</PaymentInfo>
Listing 5 : Encrypted XML content
<?xml version='1.0'?>
<PaymentInfo xmlns='http://example.org/paymentv2'>
<Name>John Smith</Name>
<CreditCard Limit='5,000' Currency='USD'>
<EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#'
Type='http://www.w3.org/2001/04/xmlenc#Content'>
<CipherData>
<CipherValue>A23B45C56</CipherValue>
</CipherData>
</EncryptedData>
</CreditCard>
</PaymentInfo>
Listing 6 : Encrypted XML character content
<?xml version='1.0'?>
<PaymentInfo xmlns='http://example.org/paymentv2'>
<Name>John Smith</Name>
<CreditCard Limit='5,000' Currency='USD'>
<Number>
<EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#'
Type='http://www.w3.org/2001/04/xmlenc#Content'>
<CipherData>
<CipherValue>A23B45C56</CipherValue>
</CipherData>
</EncryptedData>
</Number>
<Issuer>Example Bank</Issuer>
<Expiration>04/04</Expiration>
</CreditCard>
</PaymentInfo>
Listing 7 : XML Signature structure
<Signature>
<SignedInfo>
(CanonicalizationMethod)
(SignatureMethod)
(<Reference (URI=)? >
(Transforms)?
(DigestMethod)
(DigestValue)
</Reference>)+
</SignedInfo>
(SignatureValue)
(KeyInfo)?
(Object)*
</Signature>
Listing 8: Signed XML
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>DZyioHJGMPli2oapvqukERomI9w=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>hv3OGlBnIcC8mDL2yZrOtqk8/l7aQjNAOY=</SignatureValue>
<KeyInfo>
<KeyValue xmlns="http://www.w3.org/2000/09/xmldsig#">
<RSAKeyValue>
<Modulus>wItpMqxUfOw46R6lrAO6aPqVLZp/1Cbbc=</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
Listing 9: Custom class for XML encryption
using System;
using System.Xml;
using System.Xml.XPath;
using System.Security.Cryptography;
using CryptoProviderNamespace; //Namespace containing CryptoProvider class
public class XMLEncryptor
{
//The XML document to be encrypted
private XmlDocument XMLdocTobeEncrypted;
//Instance of the custom class CryptoProvider
private CryptoProvider myCryptoProvider;
public XMLEncryptor(XmlDocument doc,string sPublicKeyPath, string sPrivateKeyPath)
{
XMLdocTobeEncrypted = doc;
//Instantiating the custom class and assigning values
myCryptoProvider= new CryptoProvider();
myCryptoProvider.RecipientPublicKeyPath=sPrivateKeyPath;
myCryptoProvider.SenderPrivateKeyPath =sPublicKeyPath;
}
public XmlDocument GetXMLDocument()
{
return XMLdocTobeEncrypted;
}
private string EncryptXML(string sInputString)
{
return myCryptoProvider.Encrypt(sInputString);
}
private string DecryptXML(string sInputString)
{
return myCryptoProvider.Decrypt(sInputString);
}
public void Encrypt(String xpath, XMLEncryptType Type)
{
//selecting the node depending on the xpath expression
XPathNavigator mynavigator = XMLdocTobeEncrypted.CreateNavigator();
XPathNodeIterator myiter = mynavigator.Select(xpath);
myiter.MoveNext();
// Creating the New Element and nodes for the encrypted data
XmlElement myElement = XMLdocTobeEncrypted.CreateElement("EncryptedData","");
XmlNode myElementChild = XMLdocTobeEncrypted.CreateElement("CipherData","");
XmlNode myElementChild2= XMLdocTobeEncrypted.CreateElement("CipherValue");
XmlNode myElementChild3=XMLdocTobeEncrypted.CreateTextNode("");
myElementChild2.AppendChild(myElementChild3);
myElementChild.AppendChild(myElementChild2);
myElement.AppendChild(myElementChild);
XmlNode node = ((IHasXmlNode)myiter.Current).GetNode();
//Choosing the course of action depending on what is to be //encrypted
switch(Type)
{
case XMLEncryptType.EncryptContent:
//Setting the value of the Cipher value node by encrypting the content of the node
myElementChild3.Value=EncryptXML(node.InnerXml);
//Replacing the text of the XML document node by the encrypted data nodes
node.InnerXml=myElement.OuterXml;
break;
case XMLEncryptType.EncryptElement:
myElementChild3.Value=EncryptXML(node.OuterXml);
XmlNode myn1= node.ParentNode;
//Replacing the node with the encrypted Data nodes
myn1.ReplaceChild(myElement,node);
break;
}
}
public void Decrypt(String xpath)
{
XPathNavigator mynavigator = XMLdocTobeEncrypted.CreateNavigator();
XPathNodeIterator myiterator = mynavigator.Select(xpath);
myiterator.MoveNext();
XmlNode node = ((IHasXmlNode)myiterator.Current).GetNode();
//calling the helper method and decrypting the node
string sDecryptedValue= DecryptXML(node.InnerText);
//Since there are three levels of nodes in the structure of
//encrypted data, we navigate 3 levels up and insert the //decrypted value
node.ParentNode.ParentNode.ParentNode.InnerXml = sDecryptedValue;
}
}
Listing 10: A Reusable Class providing public-key encryption
using System;
using System.Security.Cryptography;
using System.IO;
public class CryptoProvider
{
private RSACryptoServiceProvider _myCryptoProvider;
private string _sRecipientPublicKeyPath;
private string _sSenderPrivateKeyPath;
public CryptoProvider()
{
_myCryptoProvider = new RSACryptoServiceProvider();
}
public string SenderPrivateKeyPath
{
set
{
_sSenderPrivateKeyPath=value;
}
get
{
return _sSenderPrivateKeyPath;
}
}
public string RecipientPublicKeyPath
{
set
{
_sRecipientPublicKeyPath=value;
}
get
{
return _sRecipientPublicKeyPath;
}
}
public string Encrypt( string sInputString)
{
string sEncryptedString=string.Empty;
try
{ //Reconstructing the RSA provider from the key saved as //XML file
_myCryptoProvider.FromXmlString(ReadXMLKeyintoString(_sRecipientPublicKeyPath));
//Encrypting input string after changing to byte array
byte[] mybtArray= _myCryptoProvider.Encrypt(ChangeStringToByte(sInputString),false);
sEncryptedString=Convert.ToBase64String(mybtArray); }
catch(Exception ex)
{
throw new Exception("ENCRYPTION FAILED:"+ex.Message);
}
return sEncryptedString;
}
public string Decrypt(string sEncryptedString )
{
string sDecryptedString = string.Empty;
try
{
//Reconstructing the RSA provider from the key saved as XML file
_myCryptoProvider.FromXmlString(ReadXMLKeyintoString(_sSenderPrivateKeyPath));
byte[] mybtArray
=_myCryptoProvider.Decrypt(Convert.FromBase64String(sEncryptedString),false);
sDecryptedString=ChangeByteToString(mybtArray);
}
catch(Exception ex)
{
throw new Exception("DECRYPTION FAILED:"+ex.Message);
}
return sDecryptedString;
}
private string ReadXMLKeyintoString(string sKeyFilePath)
{
string sKeyContent;
//The Key is saved in an XML document , so reading the file
FileStream myFileStream=new FileStream(sKeyFilePath,FileMode.Open);
StreamReader myReader = new StreamReader(myFileStream);
sKeyContent= myReader.ReadToEnd();
myReader.Close();
myFileStream.Close();
return sKeyContent;
}
private byte[] ChangeStringToByte(string sInputString)
{
return System.Text.UnicodeEncoding.Default.GetBytes(sInputString);
}
private string ChangeByteToString(byte[] btArrayInput)
{
return System.Text.UnicodeEncoding.Default.GetString(btArrayInput);
}
}
Listing 11: XMLEncryption Type Enumerator
public enum XMLEncryptType
{
EncryptElement,
EncryptContent
}
Listing 12: A Reusable Class for Key generation
using System;
using System.Security.Cryptography;
using System.IO;
public class KeyPairGenerator
{
public KeyPairGenerator()
{
//Default constructor
}
public void GenKeyAndSave()
{
//Creating an Instance of RSA implementation
RSA myRSA = RSA.Create();
//Creating and saving an XML representation of public key to //file
WriteKeyToFile(myRSA.ToXmlString(false),@"Publickey.xml");
//Creating and saving an XML representation of private key to //file
WriteKeyToFile(myRSA.ToXmlString(true),@"Privatekey.xml");
}
private void WriteKeyToFile(string sKey, string fileName)
{
//Helper method which writes to the physical file
StreamWriter mywriter = new StreamWriter(fileName,false);
mywriter.Write(sKey);
mywriter.Close();
}
}
Listing 13: Method for Signing an XML document
public void SignXMLDocument(string sFilePath ,string sKeyFilePath)
{
string sKeyContent;
//The Key is saved in an XML document
FileStream myFileStream=new FileStream(sKeyFilePath,FileMode.Open);
StreamReader myReader = new StreamReader(myFileStream);
sKeyContent= myReader.ReadToEnd();
myReader.Close();
myFileStream.Close();
XmlDocument mydoc = new XmlDocument();
mydoc.Load(sFilePath);
SignedXml mysignedxml =new SignedXml(mydoc);
RSA key =RSA.Create();
key.FromXmlString(sKeyContent);
mysignedxml.SigningKey =key;
Reference reference = new Reference();
reference.Uri = "";
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new RSAKeyValue(key));
mysignedxml.KeyInfo = keyInfo;
mysignedxml.AddReference(reference);
mysignedxml.ComputeSignature();
XmlElement xmlSignature = mysignedxml.GetXml();
XmlNode n = mydoc.ImportNode(xmlSignature, true);
XmlNode root = mydoc.DocumentElement;
root.InsertAfter(n, root.FirstChild);
mydoc.PreserveWhitespace =true;
mydoc.Save(sFilePath);
}
Listing 14: Method for checking the signature of an XML document
public bool CheckSignature(string sFilePath)
{
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.PreserveWhitespace = true;
xmlDocument.Load(sFilePath);
SignedXml signedXml = new SignedXml(xmlDocument);
XmlNodeList nodeList = xmlDocument.GetElementsByTagName("Signature");
signedXml.LoadXml((XmlElement)nodeList[0]);
return signedXml.CheckSignature();
}