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
XML digital signatures are useful to verify the integrity of data and authenticity of the sender and for non-repudiation.
The various threat associated with this approach are Data Corruption, 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
XML Digital Signature Example
For a simplified example let us take the role of car dealership.
<?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>
Below code generates the encryption key.
Code Sample in C#
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);
}
XML Document After Digital 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>
Validating the XML Signature using C#
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
}