The example below is a very simple "wrapped" signature representing a signed XML fragment. To be very specific, the example used here is based on .NET Framework Security, B. LaMacchia et. al. 2002, Addison Wesley, Listing 32.23 p. 738.
The full C# code used to create the signature results on this page is:
using System;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;
using System.Xml;
public class WrappedSig {
const string ContainerName = "Exponent1" ;
const int AT_KEYEXCHANGE = 1;
static void Main(String[] args)
{
XmlDocument doc = new XmlDocument();
XmlElement elem = doc.CreateElement("MyElement");
XmlNode child = (XmlNode) doc.CreateTextNode("My Element's Text Value") ;
elem.AppendChild(child);
CspParameters cp = new CspParameters();
cp.KeyContainerName = ContainerName;
cp.KeyNumber = AT_KEYEXCHANGE;
RSACryptoServiceProvider rsaCSP = new RSACryptoServiceProvider(cp);
XmlElement xmlSignature = CreateWrappedSignature(rsaCSP, elem);
Console.WriteLine(xmlSignature.OuterXml);
}
private static XmlElement CreateWrappedSignature (AsymmetricAlgorithm signingKey, XmlElement contentToSign)
{
SignedXml signedXml = new SignedXml();
signedXml.SigningKey = signingKey;
DataObject dataObject = new DataObject("ID1", null, null, contentToSign);
signedXml.AddObject(dataObject);
Reference reference = new Reference();
reference.Uri = "#ID1";
signedXml.AddReference(reference);
signedXml.ComputeSignature();
return signedXml.GetXml();
}
}
In this exercise, we are interested in inspecting two different hash values: The hash value describing the
XML fragment and represented in the tag <DigestValue> as b64-encoded, and also the hash value for the
<SignedInfo> tag, which is encrypted with an RSA private key to generate the <SignatureValue>
data. We wish to manually verify the exact byte-data (octet-stream) which generates these hashes. This byte data
will be the C14 canonicalized XML data.
To facilitate actually seeing the hash value for the SignatureValue data, I use a special type of RSA keypair called an "ExponentOfOne" key, which does not encrypt at all, but simply shows the raw RSA signature block, allowing us to actually see the hash value.
Executing the code above, creates the following XML data (pretty printed below for ease of display; this
only produces line breaks BETWEEN XML tags):
Consider now the hash value for the entire SignedInfo tag. As mentioned above, an ExponentOfOne keypair
allows us to see the actual hash value of the entire data-to-be-signed. The SignedValue data above,
after b64 decoding, is just a standard
PKCS #1 Type 1 binary signature block
of exactly 128 bytes (for a 1024 bit RSA keypair) in big-endian byte order. Displaying it in hex:
It is easy to verify the results above directly, or the following web-based
hashing Java applet
(requires MS JVM and IE 5+) can be used to simply cut/paste the strings above and verify hashes.
Note that the above example is an extremely simple example of XMLDSIG wrapped signature over
a simple textual XML fragment. Hence, there are no unusual character-conversion issues.
References
Michel I. Gallant
yE16F3R6FqVErhSWEXlUJekp3s8= (b64)
C8 4D 7A 17 74 7A 16 A5 44 AE 14 96 11 79 54 25 E9 29 DE CF (HEX)
Transforming manually with XmlDsigC14NTransform does NOT actually include the namespace propogation.
Evidently, oSignedXml.ComputeSignature internally inserts the namespace attribute into the Object tag
to generate the actual octet-stream for hashing. The resultant fully C14 transformed data internally passed for hashing is:
00 01 FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
FF FF FF FF FF FF FF FF FF FF FF FF 00 30 21 30
09 06 05 2B 0E 03 02 1A 05 00 04 14 FF FE 82 E3
EB 01 C2 B8 FD 4A 08 D3 54 94 E8 FC 27 4B 7B 8A
The last 20 bytes represents the SHA-1 hash:
FF FE 82 E3 EB 01 C2 B8 FD 4A 08 D3 54 94 E8 FC 27 4B 7B 8A
which exactly matches the SHA-1 hash of the fully C14 transformed SignedInfo tag:
QUESTION for the Student: Can you detect why the signature in LaMacchia et. al. Listing 32.24 p. 739
shows a different DigestValue entry than that shown above, for exactly the same XML fragment??
JavaScience Consulting
neutron@istar.ca