public static void Main(String[] args) { //calculate caninicalized xml var t = new XmlDsigEnvelopedSignatureTransform(false); XmlDocument doc = new XmlDocument(); //doc.PreserveWhitespace = true; doc.Load(@"c:\temp\x.xml"); t.LoadInput(doc); FieldInfo field = t.GetType().GetField("_signaturePosition", BindingFlags.NonPublic | BindingFlags.Instance); field.SetValue(t, 1); var res = (XmlDocument)t.GetOutput(); var s = res.OuterXml; var c14 = new XmlDsigC14NTransform(); c14.LoadInput(res); var mem = (MemoryStream)c14.GetOutput(); var sha = new SHA256Managed(); var byte1 = c14.GetDigestedOutput(new SHA256Managed()); var digest1 = Convert.ToBase64String(byte1); var byte2 = sha.ComputeHash(mem.ToArray()); var digest2 = Convert.ToBase64String(byte2); var s1 = System.Text.Encoding.UTF8.GetString(mem.ToArray()); var byte3 = sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(s1)); var digest3 = Convert.ToBase64String(byte3); //return; //validate signature CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(@"c:\temp\x.xml"); XmlNode node = xmlDoc.DocumentElement; X509Certificate2 cert = new X509Certificate2(File.ReadAllBytes(@"c:\temp\x.cer")); bool isValid = ValidateXml(xmlDoc, cert); //return; //calc hash var sha1 = new SHA256Managed(); var b1 = sha1.ComputeHash(System.Text.Encoding.UTF8.GetBytes(File.ReadAllText(@"c:\temp\x_no_sig.xml"))); var b64 = Convert.ToBase64String(b1); }
public void XMLSemanticCorrectnessTest() { var hash = new List <byte[]>(); var inputs = new string[] { "<test><sample value=\"1\" putthisanywhere=\"abcdef\" /></test>", "<test><sample putthisanywhere=\"abcdef\" value=\"1\" /></test>", "<test><sample value=\"1\" broken=\"true\" /></test>" }; foreach (var input in inputs) { using (var stream = new MemoryStream()) { using (var writer = new StreamWriter(stream)) { writer.Write(input); writer.Flush(); stream.Position = 0; var xfrm = new XmlDsigC14NTransform(false); xfrm.LoadInput(stream); hash.Add(xfrm.GetDigestedOutput(new SHA1Managed())); } } } CollectionAssert.AreEqual(hash[0], hash[1]); CollectionAssert.AreNotEqual(hash[0], hash[2]); CollectionAssert.AreNotEqual(hash[1], hash[2]); }
/// <summary> /// Verifies the Signature and Licence Info in the Certificate /// </summary> /// <param name="path">Path to the certificate file</param> /// <returns>true if 'sign' matches the signature computed using the specified hash algorithm and key on 'Signature' and 'Digest' matches the computed hash for license; otherwise, false.</returns> static bool VerifyCertSignature(string path) { XmlDocument doc = new XmlDocument(); doc.Load(path); XmlDsigC14NTransform transform = new XmlDsigC14NTransform(); transform.LoadInput(new MemoryStream(Encoding.UTF8.GetBytes(doc.GetElementsByTagName("SignedInfo")[0].OuterXml))); byte[] siHash = transform.GetDigestedOutput(SHA1.Create()); byte[] Signature = Convert.FromBase64String(doc.GetElementsByTagName("SignatureValue")[0].InnerText); byte[] Modulus = Convert.FromBase64String(doc.GetElementsByTagName("Modulus")[0].InnerText); byte[] Exponent = Convert.FromBase64String(doc.GetElementsByTagName("Exponent")[0].InnerText); string Digest = doc.GetElementsByTagName("DigestValue")[0].InnerText; RSAParameters parameter = new RSAParameters(); parameter.Modulus = Modulus; parameter.Exponent = Exponent; RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); rsa.ImportParameters(parameter); RSAPKCS1SignatureDeformatter rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa); rsaDeformatter.SetHashAlgorithm("SHA1"); bool sign = rsaDeformatter.VerifySignature(siHash, Signature); XmlLicenseTransform License = new XmlLicenseTransform(); License.Context = (XmlElement)doc.GetElementsByTagName("Signature")[0]; License.LoadInput(doc); transform = new XmlDsigC14NTransform(); transform.LoadInput(License.GetOutput()); string dvHash = Convert.ToBase64String(transform.GetDigestedOutput(SHA1.Create())); return(sign && dvHash.Equals(Digest)); }
public static byte[] CanonicalizeXmlDigest(XmlNode xmlNode, System.Security.Cryptography.HashAlgorithm hashAlgo) { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.PreserveWhitespace = true; xmlDoc.LoadXml(xmlNode.OuterXml); XmlDsigC14NTransform c14n = new XmlDsigC14NTransform(false); c14n.LoadInput(xmlDoc); return(c14n.GetDigestedOutput(hashAlgo)); }
private string step_3(string filename) //Core validation { string[] SUPPORTED_TRANSFORMS = { "http://www.w3.org/TR/2001/REC-xml-c14n-20010315", "http://www.w3.org/2000/09/xmldsig#base64", }; string[] SUPPORTED_DIGEST_METHOD = { "http://www.w3.org/2001/04/xmlenc#sha512 ", "http://www.w3.org/2001/04/xmldsig-more#sha384", "http://www.w3.org/2001/04/xmlenc#sha256", "http://www.w3.org/2001/04/xmldsig-more#sha224", "http://www.w3.org/2000/09/xmldsig#sha1", }; XmlDocument xades = new XmlDocument(); xades.Load(filename); var namespaceId = new XmlNamespaceManager(xades.NameTable); namespaceId.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#"); namespaceId.AddNamespace("xades", "http://uri.etsi.org/01903/v1.3.2#"); //check ds:SignedInfo and ds:Manifest XmlNode signedInfoN = xades.SelectSingleNode(@"//ds:SignedInfo", namespaceId); XmlNodeList referenceElements = signedInfoN.SelectNodes(@"//ds:Reference", namespaceId); //Reference in SignedInfo foreach (XmlNode reference in referenceElements) { String ReferenceURI = reference.Attributes.GetNamedItem("URI").Value; ReferenceURI = ReferenceURI.Substring(1); XmlNode digestMethod = reference.SelectSingleNode("ds:DigestMethod", namespaceId); String digestMethodAlgorithm = digestMethod.Attributes.GetNamedItem("Algorithm").Value; string dsDigestValue = reference.SelectSingleNode("ds:DigestValue", namespaceId).InnerText; if (ReferenceURI.StartsWith("ManifestObject")) { //get Manifest XML and check DigestValue string manifestXML = xades.SelectSingleNode("//ds:Manifest[@Id='" + ReferenceURI + "']", namespaceId).OuterXml; MemoryStream sManifest = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(manifestXML)); XmlDsigC14NTransform t = new XmlDsigC14NTransform(); t.LoadInput(sManifest); HashAlgorithm hash = null; switch (digestMethodAlgorithm) { case "http://www.w3.org/2000/09/xmldsig#sha1": hash = new System.Security.Cryptography.SHA1Managed(); break; case "http://www.w3.org/2001/04/xmlenc#sha256": hash = new System.Security.Cryptography.SHA256Managed(); break; case "http://www.w3.org/2001/04/xmldsig-more#sha384": hash = new System.Security.Cryptography.SHA384Managed(); break; case "http://www.w3.org/2001/04/xmlenc#sha512": hash = new System.Security.Cryptography.SHA512Managed(); break; } if (hash == null) { return("nesprávny hashovací algoritmus " + digestMethodAlgorithm); } byte[] digest = t.GetDigestedOutput(hash); string result = Convert.ToBase64String(digest); Console.WriteLine("-"); Console.WriteLine("Overenie hodnoty podpisu"); Console.WriteLine(result); Console.WriteLine(dsDigestValue); Console.WriteLine("-"); if (!result.Equals(dsDigestValue)) { return("hodnoty DigestValue s výpočtom Manifest sa nezhodujú"); } } } //signed info kanonikalizovat XmlNode checkData = xades.SelectSingleNode(@"//ds:KeyInfo/ds:X509Data/ds:X509Certificate", namespaceId); if (checkData == null) { return("neobsahuje element ds:X509Data"); } byte[] signatureCertificate = Convert.FromBase64String(xades.SelectSingleNode(@"//ds:KeyInfo/ds:X509Data/ds:X509Certificate", namespaceId).InnerText); byte[] signature = Convert.FromBase64String(xades.SelectSingleNode(@"//ds:SignatureValue", namespaceId).InnerText); XmlNode signedInfoNnn = xades.SelectSingleNode(@"//ds:SignedInfo", namespaceId); string signedInfoTransformAlg = xades.SelectSingleNode(@"//ds:SignedInfo/ds:CanonicalizationMethod", namespaceId).Attributes.GetNamedItem("Algorithm").Value; string signedInfoSignatureAlg = xades.SelectSingleNode(@"//ds:SignedInfo/ds:SignatureMethod", namespaceId).Attributes.GetNamedItem("Algorithm").Value; XmlDsigC14NTransform t1 = new XmlDsigC14NTransform(false); XmlDocument pom = new XmlDocument(); pom.LoadXml(signedInfoNnn.OuterXml); t1.LoadInput(pom); byte[] data = ((MemoryStream)t1.GetOutput()).ToArray(); string errMsg = ""; bool res = this.verifySign(signatureCertificate, signature, data, signedInfoSignatureAlg, out errMsg); if (!res) { Console.WriteLine("Error " + errMsg); return(errMsg); } //check Id in ds:Signature XmlNode dsSignatureId = xades.SelectSingleNode("//ds:Signature", namespaceId).Attributes["Id"]; if (dsSignatureId == null) { return("ds:Signature nemá atribút Id"); } //check namespace in ds:Signature XmlNode dsSignatureXmlns = xades.SelectSingleNode("//ds:Signature", namespaceId).Attributes["xmlns:ds"]; if (dsSignatureXmlns == null) { return("ds:Signature nemá špecifikovaný namespace xmlns:ds"); } //check SignatureValue Id XmlNode dsSignatureValueId = xades.SelectSingleNode("//ds:SignatureValue", namespaceId).Attributes["Id"]; if (dsSignatureValueId == null) { return("ds:SignatureValue nemá atribút Id"); } //check reference in ds:SignedInfo XmlNode signedInfo = xades.SelectSingleNode("//ds:SignedInfo", namespaceId); XmlNodeList dsKeyInfoId = signedInfo.SelectNodes("//ds:Reference", namespaceId); if (dsKeyInfoId.Count < 1) { return("ds:SignedInfo neobsahuje ds:Reference"); } String KeyInfo = ""; String SignatureProperties = ""; String SignedProperties = ""; List <string> Manifest = new List <string>(); //get URI foreach (XmlNode ReferenceList in dsKeyInfoId) { if (ReferenceList.Attributes["Id"] == null) { continue; } else if (ReferenceList.Attributes["Id"] != null) { if (ReferenceList.Attributes["Type"].Value.Contains("Object")) { KeyInfo = ReferenceList.Attributes["URI"].Value; KeyInfo = KeyInfo.Substring(1); } else if (ReferenceList.Attributes["Type"].Value.Contains("SignatureProperties")) { SignatureProperties = ReferenceList.Attributes["URI"].Value; SignatureProperties = SignatureProperties.Substring(1); } else if (ReferenceList.Attributes["Type"].Value.Contains("SignedProperties")) { SignedProperties = ReferenceList.Attributes["URI"].Value; SignedProperties = SignedProperties.Substring(1); } else if (ReferenceList.Attributes["Type"].Value.Contains("Manifest")) { String tmp = ReferenceList.Attributes["URI"].Value; tmp = tmp.Substring(1); Manifest.Add(tmp); } } } //check if exist ds:KeyInfo, ds:SignatureProperties, xades:SignedProperties XmlNode ElementKeyInfo = xades.SelectSingleNode("//ds:KeyInfo", namespaceId); XmlNode ElementSignatureProperties = xades.SelectSingleNode("//ds:SignatureProperties", namespaceId); XmlNode ElementSignedProperties = xades.SelectSingleNode("//xades:SignedProperties", namespaceId); if (ElementKeyInfo.Attributes["Id"] == null) { return("ds:Keyinfo nemá atribút Id"); } if (!ElementKeyInfo.Attributes["Id"].Value.Equals(KeyInfo)) { return("ds:Keyinfo, nezhoduje sa Id s URI"); } if (ElementSignatureProperties.Attributes["Id"] == null) { return("ds:SignatureProperties nemá atribút Id"); } if (!ElementSignatureProperties.Attributes["Id"].Value.Equals(SignatureProperties)) { return("ds:SignatureProperties, nezhoduje sa Id s URI"); } if (ElementSignedProperties.Attributes["Id"] == null) { return("xades:SignedProperties nemá atribút Id"); } if (!ElementSignedProperties.Attributes["Id"].Value.Equals(SignedProperties)) { return("xades:SignedProperties, nezhoduje sa Id s URI"); } //check if exist ds:Manifest XmlNodeList ElementManifest = xades.SelectNodes("//ds:Manifest", namespaceId); bool flag = false; foreach (XmlNode OneManifest in ElementManifest) { foreach (String ManifestURI in Manifest) { if (OneManifest.Attributes["Id"] == null || !OneManifest.Attributes["Id"].Value.Equals(ManifestURI)) { flag = true; } } } if (!flag) { return("ds:Manifest nemá atribút Id alebo sa nezhoduje Id s URI"); } //check ds:KeyInfo Id if (ElementKeyInfo.Attributes["Id"] == null) { return("element ds:KeyInfo nemá atribút Id"); } //check ds:KeyInfo elements XmlNode X509Data = ElementKeyInfo.SelectSingleNode("//ds:X509Data", namespaceId); if (X509Data == null) { return("ds:KeyInfo neobsahuje element ds:X509Data"); } if (X509Data.ChildNodes.Count < 3) { return(" chýbajú podelementy pre ds:X509Data"); } //check ds:KeyInfo values XmlNodeList elemList = X509Data.ChildNodes; byte[] bytes; var cert = new X509Certificate2(); String IssuerSerialFirst = ""; String IssuerSerialSecond = ""; String SubjectName = ""; for (int i = 0; i < elemList.Count; i++) { switch (elemList[i].Name) { case "ds:X509Certificate": bytes = Convert.FromBase64String(elemList[i].InnerText); cert = new X509Certificate2(bytes); break; case "ds:X509IssuerSerial": if (elemList[i].HasChildNodes) { IssuerSerialFirst = elemList[i].FirstChild.InnerText; IssuerSerialSecond = elemList[i].LastChild.InnerText; } break; case "ds:X509SubjectName": SubjectName = elemList[i].InnerText; break; } } BigInteger hex = BigInteger.Parse(cert.SerialNumber, NumberStyles.AllowHexSpecifier); if (!cert.Subject.Equals(SubjectName)) { return("hodnota ds:X509SubjectName sa nezhoduje s príslušnou hodnotou v certifikáte"); } if (!cert.Issuer.Equals(IssuerSerialFirst)) { return("hodnota ds:X509IssuerName sa nezhoduje s príslušnou hodnotou v certifikáte"); } if (!hex.ToString().Equals(IssuerSerialSecond)) { return("hodnota ds:X509SerialNumber sa nezhoduje s príslušnou hodnotou v certifikáte"); } //check ds:SignatureProperties Id if (ElementSignatureProperties.Attributes["Id"] == null) { return("element ds:SignatureProperties nema atribut Id"); } //check ds:SignatureProperties numbers of elements XmlNodeList elemListSignatureProperties = ElementSignatureProperties.ChildNodes; if (elemListSignatureProperties.Count < 2) { return("ds:SignatureProperties neobsahuje dva elementy"); } //check ds:SignatureProperties elements for (int i = 0; i < elemListSignatureProperties.Count; i++) { if (elemListSignatureProperties[i].FirstChild.Name.Equals("xzep:SignatureVersion") || elemListSignatureProperties[i].FirstChild.Name.Equals("xzep:ProductInfos")) { String tmpTargetValue = elemListSignatureProperties[i].Attributes["Target"].Value; tmpTargetValue = tmpTargetValue.Substring(1); if (!tmpTargetValue.Equals(dsSignatureId.Value)) { return("atribút Target v elemente ds:SignatureProperty nie je nastavený na element ds:Signature"); } } } //check Manifest and Manifest references String ManifestReferenceUri = ""; String algorithmDigestMethod = ""; String algorithmTransforms = ""; String digestValue = ""; bool flag1 = false; for (int i = 0; i < ElementManifest.Count; i++) { //check ds:Manifest Id if (ElementManifest[i].Attributes["Id"] == null) { return("jeden z elementov ds:Manifest nemá atribút Id"); } //check number of reference, ds:Object XmlNodeList ManifestChildNodes = ElementManifest[i].ChildNodes; if (ManifestChildNodes.Count > 1 || ManifestChildNodes.Count < 1) { return("ds:Manifest neobsahuje práve jedenu referenciu"); } if (!ManifestChildNodes[0].Attributes["Type"].Value.Contains("Object")) { return("nezhoduje sa Type v ds:Manifest"); } //check value attribute Type if (ManifestChildNodes[0].Attributes["Type"].Value.Equals("http://www.w3.org/2000/09/xmldsig#Object")) { //check supported ds:Transforms and ds:DigestMethod XmlNodeList ReferenceElementsChild = ManifestChildNodes[0].ChildNodes; for (int l = 0; l < ReferenceElementsChild.Count; l++) { if (ReferenceElementsChild[l].Name.Equals("ds:Transforms")) { algorithmTransforms = ReferenceElementsChild[l].FirstChild.Attributes["Algorithm"].Value; if (!SUPPORTED_TRANSFORMS.Contains(algorithmTransforms)) { return("ds:Transforms neobsahuje podporovaný algoritmus pre daný element podľa profilu XAdES_ZEP"); } } if (ReferenceElementsChild[l].Name.Equals("ds:DigestMethod")) { algorithmDigestMethod = ReferenceElementsChild[l].Attributes["Algorithm"].Value; if (!SUPPORTED_DIGEST_METHOD.Contains(algorithmDigestMethod)) { return("ds:DigestMethod neobsahuje podporovaný algoritmus pre daný element podľa profilu XAdES_ZEP"); } } if (ReferenceElementsChild[l].Name.Equals("ds:DigestValue")) { digestValue = ReferenceElementsChild[l].InnerText; } } ManifestReferenceUri = ManifestChildNodes[0].Attributes["URI"].Value; ManifestReferenceUri = ManifestReferenceUri.Substring(1); //check values ds:Manifest and ds:Object XmlNodeList ObjectElement = xades.SelectNodes("//ds:Object", namespaceId); for (int j = 0; j < ObjectElement.Count; j++) { if (ObjectElement[j].Attributes["Id"] == null) { continue; } if (ObjectElement[j].Attributes["Id"].Value.Equals(ManifestReferenceUri)) { flag1 = true; XmlDsigC14NTransform t = new XmlDsigC14NTransform(); XmlDocument myDoc = new XmlDocument(); myDoc.LoadXml(ObjectElement[i].OuterXml); t.LoadInput(myDoc); Stream s = (Stream)t.GetOutput(typeof(Stream)); byte[] hash; string base64String = ""; switch (algorithmDigestMethod) { case "http://www.w3.org/2001/04/xmldsig#sha1": SHA1 sha1 = SHA1.Create(); hash = sha1.ComputeHash(s); base64String = Convert.ToBase64String(hash); break; case "http://www.w3.org/2001/04/xmlenc#sha256": SHA256 sha256 = SHA256.Create(); hash = sha256.ComputeHash(s); base64String = Convert.ToBase64String(hash); break; case "http://www.w3.org/2001/04/xmldsig-more#sha384": SHA384 sha384 = SHA384.Create(); hash = sha384.ComputeHash(s); base64String = Convert.ToBase64String(hash); break; case "http://www.w3.org/2001/04/xmlenc#sha512": SHA512 sha512 = SHA512.Create(); hash = sha512.ComputeHash(s); base64String = Convert.ToBase64String(hash); break; } Console.WriteLine("-"); Console.WriteLine("Overenie hodnoty ds:DigestValue"); Console.WriteLine("First " + base64String); Console.WriteLine("Second " + digestValue); Console.WriteLine("-"); } } if (!flag1) { return("odkaz z ds:Manifest na ds:Object sa nezhoduje"); } flag1 = false; } else { return("ds:Reference, hodnota atribútu Type sa neoverila voči profilu XADES_ZEP"); } } return("OK"); }