Sharing structured data

XML Magazine

Subscribe to XML Magazine: eMailAlertsEmail Alerts newslettersWeekly Newsletters
Get XML Magazine: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


XML Authors: Jayaram Krishnaswamy, Chris Pollach, Jason Bloomberg, Peter Silva, Mehdi Daoudi

Related Topics: XML Magazine

XML: Article

Securing XML in the .NET Framework

Using the .NET cryptography classes

Use of XML has become more and more popular over the past few years. Security is a big concern since the content of an XML file is in plain text and the information is in a human-readable form. The World Wide Web Consortium (W3C) has developed standards to meet the security requirements of an XML file conforming to common XML paradigms. In this article I will show you how to implement public-key encryption using the cryptography classes in the .NET Framework to secure an XML file, thereby ensuring its integrity and confidentiality.

XML was conceived as a means of harnessing the power and flexibility of SGML (Standard Generalized Markup Language) without all its complexity. Although a restricted form of SGML, XML nonetheless preserves most of SGML's power and richness, and yet retains all of SGML's commonly used features. XML gives developers the flexibility to develop their own tags and to embed information in them. Since XML is in plain text, it has steadily gained popularity as a medium by which two completely different applications can talk to each other. However, the plain text format that gives XML its inherent advantages is also its Achilles' heel. Listing 1 shows a simple XML document that shows how XML might be used to convey payment information. (All of the code for this article can be downloaded from www.sys-con.com/dotnet/sourcec.cfm).

As you can see, reading XML is pretty simple, and in most cases, no prior knowledge of XML is needed to understand what data is being transmitted in a document. It is very easy for a third party to snoop through the data that is being passed. There needs to be a way to ensure that the information is not disclosed to an unintended recipient. We would also benefit from having some way of making sure that the document has not been tampered with while in transit. The W3C has set standards for implementing encryption of XML documents to prevent the disclosure of information and also to allow for digitally signing a document to ensure its integrity. I will first examine these standards and then discuss ways to implement them by using the cryptography classes in the .NET Framework.

Cryptography
Cryptography is the practice of scrambling plain text into ciphertext through a process called encryption and then converting the ciphertext back into plain text by another process, called decryption. Cryptography has three main objectives.

  • Confidentiality: Keeping the contents of the message private so that only authorized parties can read it. Confidentiality of the information is achieved by encrypting the contents. Cryptography provides an excellent means to ensure confidentiality by applying symmetric or asymmetric encryption mechanisms.
  • Integrity: Ensuring that the contents of the message have not been tampered with while in transit.
  • Authentication: Ensuring that the message claiming to have been sent by a party was actually sent by the party. This is also known as nonrepudiation.
Digitally signing the document helps to ensure the integrity of the document and also helps in verifying its authenticity. The cryptography classes in the .NET Framework provide us with a wide variety of options to implement both asymmetric and symmetric encryption and also to digitally sign documents.

Security and XML
The W3C standards are designed to conform to common XML paradigms. They leverage existing XML standards and also enhance the XML standards. They specifically describe a process for encrypting and signing the XML data and representing the result in XML.

Encrypting XML
The W3C specifies a process for encrypting data and representing the result in XML. The encrypted portion of the XML is replaced by an EncryptedData element, which has the structure shown in Listing 2.

"?" denotes zero or one occurrence; "+" denotes one or more occurrences; "*" denotes zero or more occurrences; and the empty element tag means the element must be empty. The raw encrypted data is enclosed in the CipherValue element. There are different scenarios for implementing XML encryption. Let's look at a few of them. Consider the XML file shown in Listing 3, which includes a person's identification and payment information, which in this case is a credit card.

This XML file is an example of a scenario in which we may want to implement encryption to keep the credit card information from unintended intermediaries. This can be done in three ways.

Encrypting the XML Element
In this scenario, the whole Credit Card element is encrypted since it is sensitive and the user may not want the intermediary to know what is being sent. The encrypted file would look like Listing 4.

Encrypting the XML Element Content
In this scenario, the child elements of the element in question and their contents are encrypted. Taking the same credit card example as before, the number element, the issuer element, and the expiration elements - which are children of the CreditCard element - are encrypted. However, it will be visible to the intermediary that a credit card is being used as the payment medium. Listing 5 shows this scenario.

Encrypting the XML Element Character Content
In this scenario we would encrypt only the character content of a particular element. An example would be if we encrypt only the credit card number, as shown in Listing 6.

Signing XML
The W3C has specific XML syntax and processing rules for creating and representing digital signatures. XML digital signatures are represented by the Signature element, which has the structure shown in Listing 7 (where "?" denotes zero or one occurrence; "+" denotes one or more occurrences; and "*" denotes zero or more occurrences). Listing 8 shows a sample XML signature.

There are three basic ways in which an XML signature may be associated with signed content:

  • Wrapped signature
  • Detached signature
  • Enveloped signature
Wrapped Signature
In this case, the digital signature is wrapped around the signed content. A wrapped digital signature carries the signed content embedded within it. Wrapped signatures have the advantage that they put the signature and the signed content together in a single package that is easily recognizable. However, they obscure the original format of the signed data.

Detached Signature
Detached signatures are physically separate from the signed content and may or may not contain a reference to the signed content.

Enveloped Signature
In this representation, the signature object is embedded within the signed content. An enveloped signature can be used only when there exists a way to add the signature to the signed content without changing the hash of the signed content. Figure 1 shows a comparison between the different types of XML digital signatures.

 

Encrypting and Decrypting XML Using the .NET Framework
In this section, we will look at using the .NET Framework to encrypt and decrypt an XML document according to the standards set by the W3C. The System.Security. Cryptography namespace of the .NET Framework provides a variety of options for implementing either symmetric or asymmetric encryption and decryption. The steps for encryption are almost the same irrespective of whether we are encrypting the XML element, its content, or even its character data. The encryption method can be designed in such a way as to accept an XPath expression and return the encrypted value. Listing 9 shows the custom class XMLEncryptor used to encrypt and decrypt an XML document according to the standards set by the W3C.

XMLEncryptor accepts as parameters in its constructor the XML document to be encrypted, the path to the public key, and the path to the private key. This class uses a custom class called CryptoProvider, shown in Listing 10, which provides the implementation of public-key encryption. It has two public methods, namely Encrypt and Decrypt, which take the XPath expression and the Type of Encryption as arguments (XMLEncryptType). XMLEncryptType is an enumerator shown in Listing 11.

The encrypt method creates the new nodes, namely EncryptedData, CipherData, and CipherValue. Depending upon the value of XMLEncryptType, either the XML element or the content in the XML document is replaced with the encrypted data. The Decrypt method again takes the XPath expression and makes a call to the Decrypt method of CryptoProvider to decrypt the data. It then replaces the nodes in the XML document with the decrypted data. Both methods utilize XPathNodeIterator and XPathNavigator classes to iterate and navigate through the XML document.

Listing 10 shows a custom class called CryptoProvider that can be reused to implement public-key encryption. This class utilizes the RSACryptoServiceProvider class to provide asymmetric encryption and decryption using the RSA algorithm. This class accepts the path to the private key and public key, which are saved as XML files, and uses them to encrypt and decrypt the input string. The Encrypt method encrypts the input string. It takes the input string as the argument, and then creates a new instance of the RSACryptoServiceProvider from the public key. It utilizes a helper method, ReadXMLKeyintoString, to read the key from the XML file. RSACryptoServiceProvider provides an Encrypt method that encrypts a byte array. In order to convert the string into a byte array, the method utilizes another helper method, called ChangeStringToByte, which outputs a byte array. This byte array is then converted into a string by utilizing the Convert.ToBase64String method. The resulting string is then passed to the caller.

The Decrypt method is similar to the Encrypt method. The difference is that it creates a new instance of the RSACryptoServiceProvider from the private key. The encrypted string is first converted to a byte array. The byte array is then decrypted and the decrypted byte array is converted back into a string and returned to the caller. Listing 12 shows a custom class that generates a public key and private key pair that can be used for encryption and decryption. The class utilizes the RSA class to create the key pair and then writes the public and private keys as XML files.

Signing and Verifying XML Using the .NET Framework
The .NET Framework provides a set of classes in the system.Security. Cryptography.Xml namespace that provide high-level signature generation and verification functions. Regardless of the type of signature being created, the steps are almost the same. They involve creating a new SignedXml object to hold the signature information.

The next step is to associate the signing key with the SignedXml object by setting its SigningKey property. Once this is done, a reference object is created for the piece of content to be signed, and the reference object is added to the SignedXml object. Optionally, a KeyInfo object can be added to the SignedXml object to communicate key information.The XML signature is computed by calling the ComputeSignature() method of the SignedXml object. The XML signature can now be obtained by calling the SignedXml.GetXml method(). Listing 13 summarizes these steps and creates an enveloped signature. These steps can easily be modified for creating other types of signatures.

The next challenge is to verify the signature that has been created. We will be using the enveloped signature created in the above example and verifying its signature. The first step in the process is to create a SignedXml object and to pass the Xmldocument being verified as a parameter to the constructor.The next step is to load the digital signature object by using the Loadxml method of the SignedXml object. Since we have created an enveloped signature, we extract the Signature node from the document and then load the signature into the SignedXml object. To verify the signature, utilize the CheckSignature method of the SignedXml object. If the signature is valid, the CheckSignature method (see Listing 14) returns true and if it's invalid, it returns false.

Summary
I have discussed the standards set by the W3C for securing XML by encrypting the content and also by digitally signing it. I have also shown how these standards can be implemented using the .NET Framework.

More Stories By Jeevan Murkoth

Jeevan Murkoth is a Microsoft Certified Solutions Developer (MCSD) in .NET (Early Achiever) and a Microsoft Certified Application Developer (MCAD) in .NET. He currently consults for Tennessee Valley Authority and lives in Chattanooga, TN. He has an MS in Management Information Systems from Texas Tech University.

Comments (2) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
Robert O''Neil 02/25/04 11:19:20 PM EST

I did manage to find the link to the code - it was the second link under the msdn link. However, I was very disappointed to pay $7.00 and then have to hunt down the code. The first time I checked the link, it was only showing code for volume 1 (last year)! This approach makes it unnecessarily hard to follow the logic in the articles when off line. Then, for future reference I will have to print it out and keep the print out with the magazine? I will definitely not waste my money again, nor my time.

Pete Fink 02/24/04 09:25:16 AM EST

I purchased the magazine. Inside the magazine it refers to listing x. The listings are not in the article. They do not appear to be at the web site either.