Reputation: 119
Hi i am very new to Digital Signing.I am verifying Digitally Signed XML File and i have verified it using the following code. But i want to know how it is verifying if the XML is proper or tampered. After going through some articles i found that 1. Create hash for the XML.(Excluding signature part) 2. Decrypt Signature using public key(you will get a hash value) 3. Compare both the hash. (If both the hash matches then the XML is not tampered). My understanding is right?.
This is the signature part of my XML
<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="">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>u+1NVN5c3gbaxmIrkO9SzVQDklA=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>QtQJjevrggzsFZj7PqD3p7GaWkzJAfyacjbMgMXgszCuO+Pxe2rrkScqvgGt2DJqgVlTbC/m9gnodCu7BcXSmW459mSJtyGH+ekWwj6g9ej8I7IYWCRqbI5uus3r3+vr/8ECd5CP/khu/LcCMyPuNIxA8h2EywCeQgbXBvLiWcdexBazdKQQpFxlKw0i+oTs8Ou6jViOdX1ZmTRtdKCQXzAElvpyNimQSmO9OECEs/TytjzIG98mpldfdofoq/2JC+xQhs6IF+Ctw/zlJdkgj1U18U/00Cw4puT4oScTELNSihSS+i9gAL+YjZLlIeunACbnZ4B1CVL/uS9kLlutXQ==</SignatureValue>
<KeyInfo>
<KeyValue>
<RSAKeyValue>
<Modulus>kHORMZQYOifL5UdIhKe54SfvJKyzLL5Aaw9MgpzeQPgBMmD9KMRnkeU+5RYMiUW8GT3q4eW77UihyxSX3MTAHzuqXoc6GjkBO1Tr41isud721SG7iMspw829YZKAHAPDAl0BV5gpLZagH8KXrDp4dVU+XDOOLZZZWZnbpKSFKvLaJO34KphZ/9W3L/l1BOwEs7132svmtwGgPO2Y16C90sDRWp78ZCYYhb7fAez7683+fijZCDGuVTvS0lBKhmH0ETiNfBAiELUUwHvQ5GHOFSp5PA8+hV9F7zxno1a0/OBpRsHfLydm3THyMUS7DlPE46zPiO9rRIUe90aQ64ulYQ==</Modulus>
<Exponent>AQAB</Exponent>
</RSAKeyValue>
</KeyValue>
</KeyInfo>
</Signature>
And how i am verifying the XML:
private void btnVerifySign_Click(object sender, EventArgs e)
{
string LModulus = node.SelectSingleNode("//Signature/KeyInfo/KeyValue/RSAKeyValue/Modulus").InnerText.ToString();
string LExponent = node.SelectSingleNode("//Signature/KeyInfo/KeyValue/RSAKeyValue/Exponent").InnerText.ToString();
using (var rsa = new RSACryptoServiceProvider())
{
var rsaParam = new RSAParameters()
{
Modulus = Convert.FromBase64String(LModulus),
Exponent = Convert.FromBase64String(LExponent)
};
rsa.ImportParameters(rsaParam);
bool result = VerifyXml(newxml1, rsa);
}
public static Boolean VerifyXml(XmlDocument Doc, RSA Key)
{
// Check arguments.
if (Doc == null)
throw new ArgumentException("Doc");
if (Key == null)
throw new ArgumentException("Key");
// Create a new SignedXml object and pass it
// the XML document class.
SignedXml signedXml = new SignedXml(Doc);
// Find the "Signature" node and create a new
// XmlNodeList object.
XmlNodeList nodeList = Doc.GetElementsByTagName("Signature");
// Throw an exception if no signature was found.
if (nodeList.Count <= 0)
{
// throw new CryptographicException("Verification failed: No Signature was found in the document.");
MessageBox.Show("Verification failed: No Signature was found in the document.");
}
// This example only supports one signature for
// the entire XML document. Throw an exception
// if more than one signature was found.
if (nodeList.Count > 1)
{
MessageBox.Show("Verification failed: More that one signature was found for the document.");
// throw new CryptographicException("Verification failed: More that one signature was found for the document.");
}
// Load the first <signature> node.
signedXml.LoadXml((XmlElement)nodeList[0]);
// Check the signature and return the result.
return signedXml.CheckSignature(Key);
}
Here if i modify the xml and verify it through VerifyXml method it returns false and if i dont modify the xml VerifyXml method returns true. I want to know how it is validating the XML? I have tried comparing the values for tampered and untampered XML in nodeList[0] and i got the same value but signedXml.CheckSignature(Key) is returning true/false. Digest values should be different for different xml right? Here i am getting the same digest value for modified and unmodified xml. And based on what exactly CheckSignature(Key) is returning true/false. And when the hash value is created for xml?. Thank you.
Upvotes: 0
Views: 2722
Reputation: 56
Actually it is <SignedInfo>
element that is signed, not the data object. Hash of data object is included in the <Reference>
element of the <SignedInfo>
element. Therefore data object is also indirectly signed. When verifying signature, hash value of the data object is compared to signed digest of data in the <Reference>
element. Then signature on <SignedInfo>
element is checked using the public key.
For more information you can read RFC 3275. There you can find information on steps performed for both generation and validation of signed xml.
Upvotes: 1