XML Encryption in .Net
2008-08-06 09:34
281 查看
XML Encryption in .Net
One of the new features being introduced with the Whidbey version of the .Net framework is XML encryption. XML Encryption allows you to encrypt arbitrary data, and have the result be an XML element. Much as XML digital signatures are driven through the SignedXml class, this feature is driven through the new EncryptedXml class. In order to allow this feature to work well with XML digital signatures, there is a special transform included with the framework, that allows the digital signature engine to decrypt the encryption document, and compute the signature over only that portion.In this posting, I'll build upon the code from my earlier posting on signing an XML document. In that post, I showed how to use XML digital signatures to verify that nobody had tampered with a CD order from a website. However, this signature did nothing to hide the purchaser's credit card information from prying eyes.
Encrypting the Document
The first step is to setup an EncryptedXml object, and get a key that will be used for encryption. This example generates a random RSA key (that is then written to a file, so that it can be used again to verify the signature and decrypt the document), but in real life, a well known key would be used here. There are two choices for an encryption key -- you could use a symmetric key that both parties know, but this can be problematic for key management purposes. Instead, I have chosen to use an RSA key. I will then generate a random symmetric session key to do the actual encryption with, and embed this key within the encrypted document itself.XmlDocument doc = new XmlDocument();
doc.Load("order.xml");
EncryptedXml exml = new EncryptedXml(doc);
// setup the key for encryption
RSA sharedKey = new RSACryptoServiceProvider();
using(StreamWriter writer = new StreamWriter("shared-key.xml"))
writer.WriteLine(sharedKey.ToXmlString(true));
// create a random session key to do the actual work with
RijndaelManaged sessionKey = new RijndaelManaged();
sessionKey.KeySize = 256;
// encrypt the session key
EncryptedKey ek = new EncryptedKey();
byte[] encryptedKey = EncryptedXml.EncryptKey(sessionKey.Key, sharedKey, false);
ek.CipherData = new CipherData(encryptedKey);
ek.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncRSA1_5Url);
The last step in setting up the keys, is to assign a name to the key that I'm using to encrypt the document with, which will be later placed into the encrypted xml, allowing the reciepient of my encrypted document to determine which key to use to decrypt it with.
// set up a key info clause for the key that was used to encrypt the session key
KeyInfoName keyName = new KeyInfoName();
keyName.Value = "shared-key";
ek.KeyInfo.AddClause(keyName);
exml.AddKeyNameMapping("shared-key", sharedKey);
In this example, I am only going to encrypt the payment tag, leaving the rest of the less-sensitive content in plain text.
// encrypt the payment tag
XmlElement paymentElem = doc.SelectSingleNode("/order/payment") as XmlElement;
byte[] encryptedPayment = exml.EncryptData(paymentElem, sessionKey, false);
// create the encrypted data
EncryptedData ed = new EncryptedData();
ed.CipherData = new CipherData(encryptedPayment);
ed.Type = EncryptedXml.XmlEncElementUrl;
ed.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url);
ed.KeyInfo.AddClause(new KeyInfoEncryptedKey(ek));
After computing the encrypted value, it is placed in an EncryptedData object, along with some information about how the encryption was done, including the name of the key necessary to decrypt the data, the algorithm used for the encryption, and the type of data that was encrypted. Note that the encryption method is AES-256 since the session key was used for encryption, not the RSA key. The last step is simply to replace the unencrypted data in the document with the encrypted version.
// replace the original XML with this version
EncryptedXml.ReplaceElement(paymentElem, ed, false);
Modifications to the Signature
In order for the XML digital signature to be able to sign the unencrypted form of the payment element, it must have an XmlDecryptionTransform applied to it. This transform needs to be setup with an EncryptedXml object that contains the key name mapping for any keys necessary to decrypt the document. In this case, we can simply pass the EncryptedXml object that we already used to perform the encryption. Here is the modified code that creates the reference to the content that is to be signed.
Code
// read in the encryption key
RSA sharedKey = new RSACryptoServiceProvider();
using(StreamReader reader = new StreamReader("shared-key.xml"))
sharedKey.FromXmlString(reader.ReadLine());
// setup the keyname mapping
EncryptedXml exml = new EncryptedXml(doc);
exml.AddKeyNameMapping("shared-key", sharedKey);
SignedXml verifier = new SignedXml(doc);
verifier.EncryptedXml = exml;
Decrypting the Encrypted Data
Decrypting the encrypted payment value is also trivial. This can be done simply by calling one method on the EncryptedXml object, which will decrypt any encrypted data in the document using the keys that it has in its key name mapping table, and replace the encrypted version with the decrypted one:// decrypt the encrypted document
exml.DecryptDocument();
Console.WriteLine("Decrypted payment info: ");
Console.WriteLine(doc.SelectSingleNode("/order/payment").OuterXml);
Published Friday, November 14, 2003 11:10 PM by shawnfa
Filed under: Security, Cryptography, XML
相关文章推荐
- Transforming XML Data with XSLT in .NET [2/3]
- XML Serializer in .NET
- Matt Meleski's .Net Blog - The ABC's of .NET : Constructing BizTalk 2004 XML Messages (In an Orchestration) - Choices
- Create XML with LoadXml(string) in ASP.NET
- Transforming XML Data with XSLT in .NET [3/3]
- 消除 ASP.NET Core 告警 "No XML encryptor configured. Key may be persisted to storage in unencrypted form"
- 使用 XML 查询替换 ADO.NET 中的 IN ,提高查询性能
- How to convert XML to JSON in ASP.NET C#
- Querying XML Files Using XPATH in ASP.NET
- Encryption And Decryption Functions In Vb.Net
- Accessing and Manipulating XML Data in .NET I
- XML DOM Object Model in .NET [3/3] - Samples
- Using SQLXML Bulk Load in the .NET Environment
- Work with XML Data Type in SQL Server 2005 from ADO.NET 2.0
- [vb.net]XML File Parsing in VB.NET
- XML in ASP.NET
- Writing an XML-RPC server or client in ASP.Net: Part 1
- How to convert XML to JSON in ASP.NET C#
- XML Serialization in the .NET Framework
- XML Serialization in the .NET Framework