|
|
YOUR FEEDBACK
|
TOP MICROSOFT .NET LINKS .NET Security
Securing XML in the .NET Framework
Using the .NET cryptography classes
By: Jeevan Murkoth
Digg This!
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
Security and XML Encrypting XML "?" 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 Encrypting the XML Element Content Encrypting the XML Element Character Content Signing XML There are three basic ways in which an XML signature may be associated with signed content:
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 Enveloped Signature
![]() Encrypting and Decrypting XML Using the .NET Framework 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 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
MICROSOFT .NET LATEST STORIES
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
|
SYS-CON FEATURED WHITEPAPERS MOST READ THIS WEEK BREAKING NEWS FROM THE WIRES
|
||||||||||||||||||||||||||||||||||||