Avoid man-in-middle attack using XML Digital Signature.
Post date: Jul 27, 2011 3:33:45 AM
In previous article we saw about XML Encryption. Now we will see about XML Digital Signature.
Although encryption is an important step in securing your Internet-bound XML, at times you might want to ensure that you are receiving information from the person you think you are. The W3C is also in the process of drafting a specification to handle digital signatures.
XML digital signatures digitally sign an element or, more typically, the entire XML document. Digitally signing an XML document is the process of creating a hash or fingerprint of the document and then encrypting this hash with a private key. This process prevents anyone from changing the document undetected; it also proofs the document sender’s identity.
Signing XML Data
Summary:
Threats:
XML digital signatures are useful to verify the integrity of data and authenticity of the sender and for nonrepudiation
Data corruption, man-in-the-middle attacks, brute-force attacks
A digitally signed XML document provides the following benefits:
Integrity The document is exactly as it was when it was signed. The document cannot be modified in any way after signing, without invalidating the signature.
Authentication The document came from the signer and no one else.
Nonrepudiation The document signer cannot deny signing the document.
A digitally signed document, however, is not private. You should apply XML encryption if privacy is important. Candidates for digitally signed documents are documents such as contracts and agreements, for which it is important that the details of the contract did not change and the sender cannot deny that he or she sent the document.
XML Digital Signatures Specification
The XML digital signature specification is a fairly stable working draft. Its scope includes how to describe a digital signature using XML and the XML-signature namespace. Code should generate the signature from a hash over the canonical form of the manifest, which can reference multiple XML documents. To canonicalize something is to put it in a standard, general-use format. Because the signature is dependent on the content it is endorsing, a signature produced from a noncanonicalized document could possibly be different from that produced from a canonicalized document. Remember that this specification is about defining digital signatures in general, not just those involving XML documents—the manifest may also contain references to any digital content that code can address, even part of an XML document.
Knowing how digital signatures work is helpful in better understanding this specification. Digitally signing a document requires the sender to create a hash of the message itself and then encrypt that hash value with his own private key. Only the sender has that private key, and only he can encrypt the hash so that it can be unencrypted using his public key. The recipient, upon receiving both the message and the encrypted hash value, can decrypt the hash value, knowing the sender’s public key. The recipient must also try to generate the hash value of the message and compare the newly generated hash value with the unencrypted hash value received from the sender. If the hash values are identical, it proves that the sender sent the message, because only the sender could encrypt the hash value correctly. The XML digital signature specification is responsible for clearly defining the information involved in verifying digital certificates.
XML digital signatures are represented by the Signature element, which has the following structure: ? denotes zero or one occurrence, + denotes one or more occurrences, and * denotes zero or more occurrences.
The XML digital signature specification is in the recommended stage and is ready for adoption. For further details, you can review the official W3C XML Signature Syntax and Processing specification found at www.w3.org/TR/xmldsig-core. Figure 8.9 shows the XML digital signature specification syntax.
<Signature> <SignedInfo> (CanonicalizationMethod) (SignatureMethod) (<Reference (URI=)? > (Transforms)? (DigestMethod) (DigestValue) </Reference>)+ </SignedInfo> (SignatureValue) (KeyInfo)? (Object)*</Signature>
Figure 8.9: XML Digital Signature Structure
The following described elements are the most notable of the specification:
Signature The primary construct of an XML signature. This topmost element holds all the other signature elements.
SignedInfo The parent element that contains the canonicalization and signature algorithm elements.
CanonicalizationMethod An element that describes the algorithm that prepares the data for signing. Canonicalization is a necessary and important transformation to convert the data to standard format that will yield that same hash results, regardless of the computing environment. For example, a Windows environment and a UNIX environment use different key codes to represent carriage returns. Canonicalization will standardize these key codes.
SignatureMethod The algorithm used to sign the data. This may be combination of a digest algorithm, an encryption algorithm, or a padding algorithm.
SignatureValue The actual digital signature, base-64 encoded.
DigestMethod The algorithm applied to the data, after any defined transformations are applied, to generate the DigestValue. Signing the DigestValue binds resource content to the signer’s key.
DigestValue The value generated by applying the DigestMethod to the data object to be signed.
KeyInfo The parent element that contains details of the key to be used to validate the signature.
There you go—everything you need to verify a digital signature in one nice, neat package. To validate the signature, you must digest the data object referenced using the relative DigestMethod. The reference is valid if the digest value generated matches the DigestValue specified. Then, to validate the signature, obtain the key information from the SignatureValue and validate it over the SignedInfo element.
XML Digital Signature Example
As an example, let’s take the role of a car dealership. We would like to submit details and prices of our cars to an Internet search engine. The search engine requires our data in XML so that it can display the details in a variety of formats and views. However, we are concerned that the unscrupulous may modify the details of the data, either in transit to the Internet search engine or on the search engine itself. As a car dealership, we are not bothered that anyone can view the car details as we send them to the search engine; in fact, the more viewers, the better! We decide to use an XML digital signature to prevent the undetected modification of our car details. Figure 8.10 shows an example of a document ready to digitally sign.
<?xml version="1.0"?> <acmeCars> <carDetails> <make>Honda</make> <model>Accord</model> <year>2004</year> <price>23000</price> </carDetails> <carDetails> <make>Ford</make> <model>Probe</model> <year>1990</year> <price>530</price> </carDetails> <carDetails> <make>Ferrari</make> <model>Enzos</model> <year>2003</year> <price>643330</price> </carDetails> </acmeCars>
Figure 8.10: XML Document to Be Digitally Signed
The example code in Figures 8.11 and 8.12 demonstrates how to read an XML document and dynamically create a digital signature. For simplicity, code generates the encryption key. Ordinarily, code would read the key from a secure location.
void signDocument(string xmlDocumentUnsignedFilename, string xmlDocumentSignedFilename) { // Load the document to be signed, and key to use XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(xmlDocumentUnsignedFilename); SignedXml signedXml = new SignedXml(); signedXml.SigningKey = rsaKey; // Set up data object to contain the data the will be signed DataObject dataObject = new DataObject(); dataObject.Data = xmlDoc.ChildNodes; dataObject.Id = "SignedObject"; signedXml.AddObject(dataObject); Reference reference = new Reference(); reference.Uri = "#SignedObject"; signedXml.AddReference(reference);
// Create signature KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue(rsaKey)); signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature();
// Write signature to file XmlElement xmlSignature = signedXml.GetXml(); xmlDoc = new XmlDocument(); XmlNode xmlNode = xmlDoc.ImportNode(xmlSignature, true); xmlDoc.AppendChild(xmlNode); xmlDoc.Save(xmlDocumentSignedFilename); }
Figure 8.11: Creating an XML Digital Signature: C#
Public Function signDocument(ByVal xmlDocumentUnsignedFilename, ByVal
xmlDocumentSignedFilename)
' Create key Dim rsaKey = RSA.Create()
' Load the document to be signed, and key to use Dim xmlDoc = New XmlDocument xmlDoc.Load(xmlDocumentUnsignedFilename) Dim signedXml = New SignedXml signedXml.SigningKey = rsaKey
' Set up data object to contain the data the will be signed Dim dataObject As DataObject = New DataObject dataObject.Data = xmlDoc.ChildNodes dataObject.Id = "SignedObject" signedXml.AddObject(dataObject) Dim reference As Reference = New Reference reference.Uri = "#SignedObject" signedXml.AddReference(reference)
' Create signature Dim keyInfo As KeyInfo = New KeyInfo keyInfo.AddClause(New RSAKeyValue(rsaKey)) signedXml.KeyInfo = keyInfo signedXml.ComputeSignature()
' Write signature to file Dim xmlSignature As XmlElement = signedXml.GetXml() xmlDoc = New XmlDocument Dim xmlNode As XmlNode = xmlDoc.ImportNode(xmlSignature, True) xmlDoc.AppendChild(xmlNode) xmlDoc.Save(xmlDocumentSignedFilename) End Function
Figure 8.12: Creating an XML Digital Signature: VB.NET
Figure 8.13 shows the XML document of Figure 8.10 after digitally signing.
<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="#SignedObject"> <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" /> <DigestValue>sPpOt0ysPVG7iPkC9/avA/4bjhM=</DigestValue> </Reference> </SignedInfo>
<SignatureValue>VwiNfYfXdY7bPAk4nULVUdlbIs572RMEWeElk68jIzWojA+3WnmwU/jJU5KYc8/D vwX1gnW/kI/hIpPswcpURSO85nNTKIKwYHX/eS7f8h5JcSlCU1EUdnpxoHEwtbsEu8OuVYUR4AiBgnFl QPVeJldiKHjRdo14j+hkZSM8p6o=</SignatureValue>
<KeyInfo> <KeyValue xmlns="http://www.w3.org/2000/09/xmldsig#"> <RSAKeyValue> <Modulus>wRMK+SKiDIRBHRY1NUc6SpTt+3iPcMGFwdg27MgsU2ydaCJyTZMCsFfDewZ6jK+cJvLLi3+ b46YwEYJ/GyPvdXSOGPHTNaDFTi7AsKAGu4eXkFhSExnDPUJlnOiToG0eMYXWj/DRvK8adMahoeqIkys mkUKq4YO9OvqMkwMyJ3M=</Modulus> <Exponent>AQAB</Exponent> </RSAKeyValue> </KeyValue> </KeyInfo> <Object Id="SignedObject"> <acmeCars xmlns=""> <carDetails> <make>Honda</make> <model>Accord</model> <year>2004</year> <price>23000</price> </carDetails>
<carDetails> <make>Ford</make> <model>Probe</model> <year>1990</year> <price>530</price> </carDetails>
<carDetails> <make>Ferrari</make> <model>Enzos</model> <year>2003</year> <price>643330</price> </carDetails> </acmeCars> </Object> </Signature>
Figure 8.13: XML Digitally Signed Document
Creating a digitally signed XML document is only half the process. The document recipient should now verify that the signature is valid and the document as not been modified. Continuing with our car dealership example, the Internet search engine to which we submitted our signed document must now validate the signature. If the document’s signature is valid, the search engine can guarantee that the document has not been modified. Figures 8.14 and 8.15 show example code to validate an XML signed document.
bool verifySignature(string xmlDocumentSignedFilename) { // Load signed XML document XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.Load(xmlDocumentSignedFilename); SignedXml signedXml = new SignedXml(xmlDoc);
// Get the signature element XmlNodeList nodeList = xmlDoc.GetElementsByTagName( "Signature", "http://www.w3.org/2000/09/xmldsig#"); signedXml.LoadXml((XmlElement)nodeList[0]);
// Validiate signature if (signedXml.CheckSignature()) return true; // signature valid - document unmodified else return false; // signature invalid- document modified }
Figure 8.14: Validating an XML Digital Signature: C#
Public Function verifySignature(ByVal xmlDocumentSignedFilename) As Boolean
' Load signed XML document Dim xmlDoc As XmlDocument = New XmlDocument xmlDoc.Load(xmlDocumentSignedFilename) Dim signedXml As SignedXml = New SignedXml(xmlDoc)
' Get the signature element Dim nodeList = xmlDoc.GetElementsByTagName( _ "Signature", "http://www.w3.org/2000/09/xmldsig#") signedXml.LoadXml(CType(nodeList(0), XmlElement))
' Validiate signature If signedXml.CheckSignature() Then Return True ' signature valid - document unmodified Else Return False ' signature invalid- document modified End If End Function
Figure 8.15: Validating an XML Digital Signature: VB.NET
You will probably see an increase in the use of encryption and digital signatures when the W3C group finalizes both the XML encryption and XML digital signature specifications. Both specifications provide a well-structured way to communicate their respective processes, and as always with ease of use comes adoption. Encryption ensures that confidential information stays confidential through its perilous journey over the Internet. Digital signatures ensure that you are communicating what and with whom you think you are. Yet both these specifications have some evolving to do, especially when they are used concurrently. There’s currently no way to determine if a document that was signed and encrypted was signed using the encrypted or unencrypted version of the document. Typically, these little bumps find a way of smoothing themselves out over time.
Security Policies
Use strong asymmetrical algorithms to ensure the privacy of data.
Validate the signature of signed documents.
Use encryption for sending private data. Digital signatures do not make a document private; they merely validate the source integrity.
-By Boobalan