Dr. Dobb's is part of the Informa Tech Division of Informa PLC

This site is operated by a business or businesses owned by Informa PLC and all copyright resides with them. Informa PLC's registered office is 5 Howick Place, London SW1P 1WG. Registered in England and Wales. Number 8860726.


Channels ▼
RSS

Security

XML Digital Signatures with SignedXML, Part 1


Applying a digital signature to data involves computing a hash code for the data and then encrypting the hash code with an asymmetric algorithm and a private key. This results in a small amount of ciphertext. Typically, the number of bits of ciphertext is equal to the number of bits selected for the encryption key. Because data you might wish to sign in the real world can be very large, encrypting the hash code of the data rather than the data itself is more efficient, though it provides no confidentiality protection over the data because the signed data is not encrypted itself.

When you receive signed data, it must contain at least a copy of the original data and the ciphertext version of the hash code of that data. If you know in advance what key to use to decrypt the ciphertext and you know what hash algorithm was used on the digitally signed data, then you could verify the signature without difficulty. In the real world, we anticipate not knowing such things in advance. It's possible that we won't even know in advance what the data format is of the original data (often referred to in crypto documentation as the “message”), which could cause a real problem as we attempt to figure out where the plaintext data of the message stops and where the ciphertext data of its digital signature begins. If we were to create digital signatures in their most basic form as just described, we might attach ciphertext of the data's encrypted hash code to the beginning or the end of the plaintext message data so that it becomes a part of the message. There are times when this approach works well, but it is also possible that we'll need to store the signature as a separate detached data block so that we don't corrupt the original data format.

Alternatively, we could design a digital signature envelope standard and write up complex contingency rules that tell us how to apply the envelope standard in various scenarios where a simple attached or detached envelope structure would corrupt the data being signed or create some other failure mode. RSA's Public Key Cryptography Standards (PKCS) define just such envelope structures and their encoding rules—while leaving room to adapt and extend algorithms, identifiers, language and character sets, and so forth, so that an organization's Public Key Infrastructure (PKI) will function for everyone, everywhere, at all times, even across organizational boundaries. The PKCS standards are a big part of the reason that PKI is no fun (see http://www.rsasecurity.com/rsalabs/pkcs).

Since XML offers improvements over fixed data structures, such as the ability to add arbitrary branches and embeddings without adversely impacting any properly written XML application, naturally we'll want a consistent way to attach digital signatures to XML data. The W3C XMLDSIG specification serves this purpose (see http://www.w3.org/Signature). Microsoft's .NET Framework provides a class called SignedXML in the System.Security.Cryptography.Xml namespace that implements XMLDSIG for you. The SignedXML class can, and should, be used as a general purpose XML signature creation and verification mechanism because it attempts to conform to the XMLDSIG standard. Compatibility with other XMLDSIG-based systems is, therefore, supposed to be automatic, although differences in encoding and formatting, including things like how whitespace is handled (or ignored) by different XMLDSIG implementations, still causes incompatibilities in practice.

Using XMLDSIG through the SignedXML class gives you a standards-based solution for attaching and later parsing an XML-encoded digital signature so that it can be verified or removed from the signed data. Detached signature envelope files are also easy to create with SignedXML so that the signature data can be stored apart from the data that was signed. However, the real power of the XML-based signature is its ability to become a part of the data without causing problems for any software already in existence that expects XML data without attached signatures. The XMLDSIG standard defines the way in which signature verification public key and cryptographic-algorithm information is stored, along with the ciphertext of the signed data's encrypted hash code.

Creating XMLDSIG Signatures

To create and attach a signature to an XML data block using the SignedXML class requires only a few steps. First, populate a new XmlDocument with the XML to be signed. Next, create an instance of the SignedXml class and create or load an RSA key pair using the RSA class. Set the SigningKey property of the signedXML object and write the XmlDocument to a DataObject. Finally, add the object and an intradocument URI reference for it to the SignedXML object, along with an instance of the KeyInfo class containing the signature key pair to the SignedXML object, and you're ready to compute and display the XMLDSIG signature wrapped around the plaintext message. Listing One shows these steps:

Listing One

  XmlDocument xmldoc = new XmlDocument(); 
  xmldoc.PreserveWhitespace = true;
  XmlNode msgnode =
     xmldoc.CreateNode(XmlNodeType.Element,"Plaintext","msg");
  msgnode.InnerText = "This is the plaintext message.";
  xmldoc.AppendChild(msgnode);
  System.Security.Cryptography.Xml.SignedXml XMLsig = new SignedXml();
  RSA keypair = RSA.Create();  XMLsig.SigningKey = keypair;
  System.Security.Cryptography.Xml.DataObject message =
   new DataObject("Message","","",xmldoc.DocumentElement);
  XMLsig.AddObject(message);
  System.Security.Cryptography.Xml.Reference msgURI = new Reference();
  msgURI.Uri = "#Message";
  XMLsig.AddReference(msgURI);
  System.Security.Cryptography.Xml.KeyInfo ki = new KeyInfo();
  ki.AddClause(new RSAKeyValue(keypair));
  XMLsig.KeyInfo = ki;
  XMLsig.ComputeSignature();
  Console.Out.WriteLine(XMLsig.GetXml().OuterXml);


Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.