// Třída podepíše certifikátem dokument XML a přidá časové razítko // Pokud je již dokument podepsaný, přidá se další podpis public XmlDocument SignWithTimestamp(XmlDocument doc, X509Certificate2 cert, string tsURL, string tsUsername, string tsPassword) { // před podepisováním z dokumentu odstraníme komentáře (.NET s nimi má problémy pokud se kombinují s XPath transformacemi) XmlDocument strippedDoc = RemoveComments(doc); // definice mapování prefixů na jmenné prostory XmlNamespaceManager manager = new XmlNamespaceManager(strippedDoc.NameTable); manager.AddNamespace("dsig", "http://www.w3.org/2000/09/xmldsig#"); // zjištění kolik podpisů již v dokumentu je int signatures = strippedDoc.SelectNodes("//dsig:Signature", manager).Count; string signatureID = (signatures + 1).ToString(); // vytvoření elementu Object pro časové razítko XmlElement objectElement = doc.CreateElement("Object", "http://www.w3.org/2000/09/xmldsig#"); // spočítání otisku certifikátu SHA256 sha256 = new SHA256Managed(); string certHash = Convert.ToBase64String(sha256.ComputeHash(cert.GetRawCertData())); objectElement.InnerXml = @"<xades:QualifyingProperties xmlns:xades='http://uri.etsi.org/01903/v1.3.2#' Target='#Signature-" + signatureID + @"' xmlns='http://www.w3.org/2000/09/xmldsig#'> <xades:SignedProperties Id='Signature-" + signatureID + @"-SignedProperties'> <xades:SignedSignatureProperties> <xades:SigningTime>" + XmlConvert.ToString(DateTime.Now.ToUniversalTime(), XmlDateTimeSerializationMode.RoundtripKind) + @"</xades:SigningTime> <xades:SigningCertificate> <xades:Cert> <xades:CertDigest> <DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha256'></DigestMethod> <DigestValue>" + certHash + @"</DigestValue> </xades:CertDigest> <xades:IssuerSerial> <X509IssuerName>" + cert.IssuerName + @"</X509IssuerName> <X509SerialNumber>" + cert.GetSerialNumberString() + @"</X509SerialNumber> </xades:IssuerSerial> </xades:Cert> </xades:SigningCertificate> </xades:SignedSignatureProperties> <xades:SignedDataObjectProperties> <xades:DataObjectFormat ObjectReference='#Signature-" + signatureID + @"-Document-Reference'> <xades:MimeType>application/xml</xades:MimeType> </xades:DataObjectFormat> </xades:SignedDataObjectProperties> </xades:SignedProperties> <xades:UnsignedProperties> <xades:UnsignedSignatureProperties> <xades:SignatureTimeStamp> <xades:EncapsulatedTimeStamp Encoding='http://uri.etsi.org/01903/v1.2.2#DER'></xades:EncapsulatedTimeStamp> </xades:SignatureTimeStamp> </xades:UnsignedSignatureProperties> </xades:UnsignedProperties> </xades:QualifyingProperties>"; // objekt sloužící pro vytvoření podpisu CustomIdSignedXml signedXml = new CustomIdSignedXml(strippedDoc, objectElement); // podepisovat budeme privátním klíčem z certifikátu signedXml.SigningKey = cert.PrivateKey; // podepisovat budeme pomocí RSA-SHA256 signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; // reference na podepisovaný dokument ("" znamená celý dokument) Reference reference = new Reference(); reference.Uri = ""; reference.Id = "Signature-" + signatureID + "-Document-Reference"; // pro výpočet otisku se bude používat SHA-256 reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; // digitální podpis bude přímo součástí dokumentu XML (tzv. "enveloped signature") XmlDsigEnvelopedSignatureTransform envTransform = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envTransform); // navíc budeme používat XPath transoformaci, která dovoluje přidat několik podpisů najednou XmlDsigXPathTransform xpathTransform = new XmlDsigXPathTransform(); // příprava definice XPath transformace jako struktura XML signature XmlDocument transformBody = new XmlDocument(); // podoba XPath filtru se liší podle počtu podpisů if (signatures == 0) transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature)</dsig:XPath>"); else transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature) or not(ancestor-or-self::dsig:Signature/preceding-sibling::dsig:Signature[" + signatures + "])</dsig:XPath>"); // načtení definice XPath transformace do objektu xpathTransform.LoadInnerXml(transformBody.SelectNodes("/*[1]")); // přidání XPath transformace reference.AddTransform(xpathTransform); // přidání reference do podpisu signedXml.AddReference(reference); // reference na SignedProperties -- XAdES-BES vyžaduje podpis certifikátu Reference spReference = new Reference(); spReference.Uri = "#Signature-" + signatureID + "-SignedProperties"; // pro výpočet otisku se bude používat SHA-256 spReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; // přidání reference do podpisu signedXml.AddReference(spReference); // přidání certifikátu do podpisu KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); signedXml.KeyInfo = keyInfo; // přidání objektu s časovým razítkem do podpisu DataObject dataObj = new DataObject(); dataObj.LoadXml(objectElement); signedXml.AddObject(dataObj); // výpočet podpisu signedXml.ComputeSignature(); // získání XML reprezentace podpisu XmlElement xmlSignature = signedXml.GetXml(); // k podpisu přidáme identifikátor, tak jak doporučuje standard ISDOC xmlSignature.SetAttribute("Id", "Signature-" + signatureID); // XML dokument pro podepsaný výsledek XmlDocument result = new XmlDocument(); // bílé znaky musíme zachovat, jinak se špatně spočte hash result.PreserveWhitespace = true; // načtení původního dokumentu result.AppendChild(result.ImportNode(strippedDoc.DocumentElement, true)); // připojení podpisu na konec dokumentu XML result.DocumentElement.AppendChild(result.ImportNode(xmlSignature, true)); // Spočítání otisku digitálního podpisu byte[] digest; digest = sha256.ComputeHash(signedXml.SignatureValue); // generátor požadavků na časové razítko TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); // vytvoření dat pro požadavek na timestamp server TimeStampRequest request = reqGen.Generate(TspAlgorithms.Sha256, digest); // získání surových dat pro poslání na timestamp server byte[] reqData = request.GetEncoded(); // inicializace požadavku na timestamp server HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(tsURL); httpReq.Method = "POST"; httpReq.ContentType = "application/timestamp-query"; httpReq.ContentLength = reqData.Length; httpReq.Credentials = new NetworkCredential(tsUsername, tsPassword); // odeslání požadavku na timestamp server Stream reqStream = httpReq.GetRequestStream(); reqStream.Write(reqData, 0, reqData.Length); reqStream.Close(); // přečtení odpovědi HttpWebResponse httpResp = (HttpWebResponse)httpReq.GetResponse(); Stream respStream = new BufferedStream(httpResp.GetResponseStream()); TimeStampResponse response = new TimeStampResponse(respStream); respStream.Close(); // Console.WriteLine("Status razítkování: " + response.Status); // Console.WriteLine("Čas razítka: " + response.TimeStampToken.TimeStampInfo.GenTime.ToLocalTime()); string timestamp = Convert.ToBase64String(response.GetEncoded()); // doplnění získaného časového razítka do dokumentu XmlNamespaceManager nsmng = new XmlNamespaceManager(result.NameTable); nsmng.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#"); nsmng.AddNamespace("xades", "http://uri.etsi.org/01903/v1.3.2#"); XmlElement etsElement = (XmlElement)result.SelectSingleNode("//*[@Id = 'Signature-" + signatureID +"']/ds:Object/xades:QualifyingProperties/xades:UnsignedProperties/xades:UnsignedSignatureProperties/xades:SignatureTimeStamp/xades:EncapsulatedTimeStamp", nsmng); etsElement.InnerText = timestamp; return result; }
// Sign an XML file and save the signature in a new file. public static void SignXmlFile(string FileName, string SignedFileName, RSA Key) { // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. doc.Load(new XmlTextReader(FileName)); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document. signedXml.SigningKey = Key; // Specify a canonicalization method. signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NWithCommentsTransformUrl; // Set the InclusiveNamespacesPrefixList property. XmlDsigExcC14NWithCommentsTransform canMethod = (XmlDsigExcC14NWithCommentsTransform)signedXml.SignedInfo.CanonicalizationMethodObject; canMethod.InclusiveNamespacesPrefixList = "Sign"; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue((RSA)Key)); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); }
// <Snippet2> // Sign an XML file and save the signature in a new file. public static void SignXmlFile(string FileName, string SignedFileName, DSA DSAKey) { // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. doc.Load(new XmlTextReader(FileName)); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the DSA key to the SignedXml document. signedXml.SigningKey = DSAKey; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add a transformation to the reference. Transform trns = new XmlDsigC14NTransform(); reference.AddTransform(trns); // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Add a DSAKeyValue to the KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new DSAKeyValue((DSA)DSAKey)); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); }
public XmlDocument SignMessage(XmlDocument xmlDoc, X509Certificate2 certificate, SignAlgorithm signAlgorithm) { XmlNamespaceManager ns = new XmlNamespaceManager(xmlDoc.NameTable); ns.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/"); XmlElement soapHeader = xmlDoc.DocumentElement.SelectSingleNode("//s:Header", ns) as XmlElement; XmlElement body = xmlDoc.DocumentElement.SelectSingleNode("//s:Body", ns) as XmlElement; if (body == null) throw new Exception("No body tag found."); XmlElement securityNode = xmlDoc.CreateElement( "wsse", "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); XmlElement binarySecurityToken = xmlDoc.CreateElement("wse", "BinarySecurityToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); binarySecurityToken.SetAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"); binarySecurityToken.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"); binarySecurityToken.SetAttribute("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", "BinaryToken1"); binarySecurityToken.InnerText = Convert.ToBase64String(certificate.GetRawCertData()); securityNode.AppendChild(binarySecurityToken); soapHeader.AppendChild(securityNode); SignedXmlWithId signedXml = new SignedXmlWithId(xmlDoc); if (signAlgorithm == SignAlgorithm.SHA1) { signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; } else { signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; } RSACryptoServiceProvider rsaKey = null; if (signAlgorithm == SignAlgorithm.SHA1) { rsaKey = (RSACryptoServiceProvider)certificate.PrivateKey; } else { var key = (RSACryptoServiceProvider)certificate.PrivateKey; var enhCsp = new RSACryptoServiceProvider().CspKeyContainerInfo; var cspparams = new CspParameters(enhCsp.ProviderType, enhCsp.ProviderName, key.CspKeyContainerInfo.KeyContainerName); rsaKey = new RSACryptoServiceProvider(cspparams); } signedXml.SigningKey = rsaKey; KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new SecurityTokenReference("BinaryToken1")); signedXml.KeyInfo = keyInfo; signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; Reference reference = new Reference { Uri = "#_1" }; if (signAlgorithm == SignAlgorithm.SHA1) { reference.DigestMethod = "http://www.w3.org/2000/09/xmldsig#sha1"; } else { reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; } reference.AddTransform(new XmlDsigExcC14NTransform()); signedXml.AddReference(reference); signedXml.ComputeSignature(); XmlElement signedElement = signedXml.GetXml(); securityNode.AppendChild(signedElement); if (soapHeader == null) { soapHeader = xmlDoc.CreateElement("s:Header", ""); xmlDoc.DocumentElement.InsertBefore(soapHeader, xmlDoc.DocumentElement.ChildNodes[0]); } return xmlDoc; }
public void Sign() { var security = new AS4.Security.Security { BinarySecurityToken = new BinarySecurityToken { Id = Guid.NewGuid().ToString(), EncodingType = Soap.Namespaces.Base64Binary, ValueType = Soap.Namespaces.X509TokenProfile, Value = Certificate.GetRawCertData() } }; var securityXml = ObjectToXml.Serialize(security); var signedXml = new ExtendedSignedXml(Xml) { SigningKey = Certificate.GetRSAPrivateKey() }; foreach (var uri in Uris) { var reference = new Reference { Uri = "#" + uri, DigestMethod = SignedXml.XmlDsigSHA256Url }; reference.AddTransform(new XmlDsigExcC14NTransform()); signedXml.AddReference(reference); } foreach (var attachment in Attachments) { var reference = new Reference(new NonCloseableStream(attachment.Stream)) { Uri = "cid:" + attachment.ContentId, DigestMethod = SignedXml.XmlDsigSHA256Url }; reference.AddTransform(new AttachmentContentSignatureTransform()); signedXml.AddExternalReference(reference); } var keyInfo = new KeyInfo(); keyInfo.AddClause(new SecurityTokenReference(security.BinarySecurityToken.Id)); signedXml.KeyInfo = keyInfo; signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA256Url; signedXml.ComputeSignature(); var signature = signedXml.GetXml(); Insert(signature, securityXml.DocumentElement); var namespaces = new XmlNamespaceManager(Xml.NameTable); namespaces.AddNamespace("s", Soap.Namespaces.SoapEnvelope); var header = Xml.SelectSingleNode("/s:Envelope/s:Header", namespaces); Insert(securityXml, header); }
private static string AddSignature(X509Certificate2 certificate, string xml, bool useFingerprint, bool addReferenceURI) { var doc = new XmlDocument { PreserveWhitespace = true }; try { doc.LoadXml(xml); } catch (Exception) { return(xml); } // document is empty, parse issue, etc if (doc.DocumentElement == null) { return(xml); } // already has a signature on the root element if (doc.DocumentElement["Signature", SignedXml.XmlDsigNamespaceUrl] != null) { return(xml); } var rsaKey = (RSACryptoServiceProvider)certificate.PrivateKey; var ki = new KeyInfo(); if (useFingerprint) { ki.AddClause(new KeyInfoName(certificate.Thumbprint)); } else { ki.AddClause(new KeyInfoX509Data(certificate)); } var signedXml = new SignedXml(doc) { SigningKey = rsaKey }; var reference = new Reference("") { DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256" }; if (addReferenceURI) { reference.Uri = "#_a75adf55-01d7-40cc-929f-dbd8372ebdfc"; } reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigExcC14NTransform()); signedXml.Signature.SignedInfo.AddReference(reference); signedXml.Signature.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; signedXml.Signature.SignedInfo.SignatureMethod = XmlDsigRsaSha256Url; signedXml.Signature.KeyInfo = ki; signedXml.ComputeSignature(); var signature = signedXml.GetXml().CloneNode(true); doc.DocumentElement.AppendChild(doc.ImportNode(signature, true)); return(doc.OuterXml); }
// Třída podepíše certifikátem dokument XML a přidá časové razítko // Pokud je již dokument podepsaný, přidá se další podpis public XmlDocument SignWithTimestamp(XmlDocument doc, X509Certificate2 cert, string tsURL, string tsUsername, string tsPassword) { // před podepisováním z dokumentu odstraníme komentáře (.NET s nimi má problémy pokud se kombinují s XPath transformacemi) XmlDocument strippedDoc = RemoveComments(doc); // definice mapování prefixů na jmenné prostory XmlNamespaceManager manager = new XmlNamespaceManager(strippedDoc.NameTable); manager.AddNamespace("dsig", "http://www.w3.org/2000/09/xmldsig#"); // zjištění kolik podpisů již v dokumentu je int signatures = strippedDoc.SelectNodes("//dsig:Signature", manager).Count; string signatureID = (signatures + 1).ToString(); // vytvoření elementu Object pro časové razítko XmlElement objectElement = doc.CreateElement("Object", "http://www.w3.org/2000/09/xmldsig#"); // spočítání otisku certifikátu SHA256 sha256 = new SHA256Managed(); string certHash = Convert.ToBase64String(sha256.ComputeHash(cert.GetRawCertData())); objectElement.InnerXml = @"<xades:QualifyingProperties xmlns:xades='http://uri.etsi.org/01903/v1.3.2#' Target='#Signature-" + signatureID + @"' xmlns='http://www.w3.org/2000/09/xmldsig#'> <xades:SignedProperties Id='Signature-" + signatureID + @"-SignedProperties'> <xades:SignedSignatureProperties> <xades:SigningTime>" + XmlConvert.ToString(DateTime.Now.ToUniversalTime(), XmlDateTimeSerializationMode.RoundtripKind) + @"</xades:SigningTime> <xades:SigningCertificate> <xades:Cert> <xades:CertDigest> <DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha256'></DigestMethod> <DigestValue>" + certHash + @"</DigestValue> </xades:CertDigest> <xades:IssuerSerial> <X509IssuerName>" + cert.IssuerName + @"</X509IssuerName> <X509SerialNumber>" + cert.GetSerialNumberString() + @"</X509SerialNumber> </xades:IssuerSerial> </xades:Cert> </xades:SigningCertificate> </xades:SignedSignatureProperties> <xades:SignedDataObjectProperties> <xades:DataObjectFormat ObjectReference='#Signature-" + signatureID + @"-Document-Reference'> <xades:MimeType>application/xml</xades:MimeType> </xades:DataObjectFormat> </xades:SignedDataObjectProperties> </xades:SignedProperties> <xades:UnsignedProperties> <xades:UnsignedSignatureProperties> <xades:SignatureTimeStamp> <xades:EncapsulatedTimeStamp Encoding='http://uri.etsi.org/01903/v1.2.2#DER'></xades:EncapsulatedTimeStamp> </xades:SignatureTimeStamp> </xades:UnsignedSignatureProperties> </xades:UnsignedProperties> </xades:QualifyingProperties>"; // objekt sloužící pro vytvoření podpisu CustomIdSignedXml signedXml = new CustomIdSignedXml(strippedDoc, objectElement); // podepisovat budeme privátním klíčem z certifikátu signedXml.SigningKey = cert.PrivateKey; // podepisovat budeme pomocí RSA-SHA256 signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; // reference na podepisovaný dokument ("" znamená celý dokument) Reference reference = new Reference(); reference.Uri = ""; reference.Id = "Signature-" + signatureID + "-Document-Reference"; // pro výpočet otisku se bude používat SHA-256 reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; // digitální podpis bude přímo součástí dokumentu XML (tzv. "enveloped signature") XmlDsigEnvelopedSignatureTransform envTransform = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envTransform); // navíc budeme používat XPath transoformaci, která dovoluje přidat několik podpisů najednou XmlDsigXPathTransform xpathTransform = new XmlDsigXPathTransform(); // příprava definice XPath transformace jako struktura XML signature XmlDocument transformBody = new XmlDocument(); // podoba XPath filtru se liší podle počtu podpisů if (signatures == 0) { transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature)</dsig:XPath>"); } else { transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature) or not(ancestor-or-self::dsig:Signature/preceding-sibling::dsig:Signature[" + signatures + "])</dsig:XPath>"); } // načtení definice XPath transformace do objektu xpathTransform.LoadInnerXml(transformBody.SelectNodes("/*[1]")); // přidání XPath transformace reference.AddTransform(xpathTransform); // přidání reference do podpisu signedXml.AddReference(reference); // reference na SignedProperties -- XAdES-BES vyžaduje podpis certifikátu Reference spReference = new Reference(); spReference.Uri = "#Signature-" + signatureID + "-SignedProperties"; // pro výpočet otisku se bude používat SHA-256 spReference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; // přidání reference do podpisu signedXml.AddReference(spReference); // přidání certifikátu do podpisu KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); signedXml.KeyInfo = keyInfo; // přidání objektu s časovým razítkem do podpisu DataObject dataObj = new DataObject(); dataObj.LoadXml(objectElement); signedXml.AddObject(dataObj); // výpočet podpisu signedXml.ComputeSignature(); // získání XML reprezentace podpisu XmlElement xmlSignature = signedXml.GetXml(); // k podpisu přidáme identifikátor, tak jak doporučuje standard ISDOC xmlSignature.SetAttribute("Id", "Signature-" + signatureID); // XML dokument pro podepsaný výsledek XmlDocument result = new XmlDocument(); // bílé znaky musíme zachovat, jinak se špatně spočte hash result.PreserveWhitespace = true; // načtení původního dokumentu result.AppendChild(result.ImportNode(strippedDoc.DocumentElement, true)); // připojení podpisu na konec dokumentu XML result.DocumentElement.AppendChild(result.ImportNode(xmlSignature, true)); // Spočítání otisku digitálního podpisu byte[] digest; digest = sha256.ComputeHash(signedXml.SignatureValue); // generátor požadavků na časové razítko TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator(); // vytvoření dat pro požadavek na timestamp server TimeStampRequest request = reqGen.Generate(TspAlgorithms.Sha256, digest); // získání surových dat pro poslání na timestamp server byte[] reqData = request.GetEncoded(); // inicializace požadavku na timestamp server HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create(tsURL); httpReq.Method = "POST"; httpReq.ContentType = "application/timestamp-query"; httpReq.ContentLength = reqData.Length; httpReq.Credentials = new NetworkCredential(tsUsername, tsPassword); // odeslání požadavku na timestamp server Stream reqStream = httpReq.GetRequestStream(); reqStream.Write(reqData, 0, reqData.Length); reqStream.Close(); // přečtení odpovědi HttpWebResponse httpResp = (HttpWebResponse)httpReq.GetResponse(); Stream respStream = new BufferedStream(httpResp.GetResponseStream()); TimeStampResponse response = new TimeStampResponse(respStream); respStream.Close(); // Console.WriteLine("Status razítkování: " + response.Status); // Console.WriteLine("Čas razítka: " + response.TimeStampToken.TimeStampInfo.GenTime.ToLocalTime()); string timestamp = Convert.ToBase64String(response.GetEncoded()); // doplnění získaného časového razítka do dokumentu XmlNamespaceManager nsmng = new XmlNamespaceManager(result.NameTable); nsmng.AddNamespace("ds", "http://www.w3.org/2000/09/xmldsig#"); nsmng.AddNamespace("xades", "http://uri.etsi.org/01903/v1.3.2#"); XmlElement etsElement = (XmlElement)result.SelectSingleNode("//*[@Id = 'Signature-" + signatureID + "']/ds:Object/xades:QualifyingProperties/xades:UnsignedProperties/xades:UnsignedSignatureProperties/xades:SignatureTimeStamp/xades:EncapsulatedTimeStamp", nsmng); etsElement.InnerText = timestamp; return(result); }
private Resultado AssinarXML(ref XmlDocument _xml, string _cnpj) { Resultado _resultado = new Resultado(); if (_xml == null) { _resultado.Sucesso = false; _resultado.Mensagens = new Base.ResultadoMensagem[] { new Base.ResultadoMensagem() { Texto = "Arquivo XML não pode estar vazio." } }; } if (string.IsNullOrEmpty(_cnpj)) { _resultado.Sucesso = false; _resultado.Mensagens = new Base.ResultadoMensagem[] { new Base.ResultadoMensagem() { Texto = "CNPJ para recuperar certificado não pode ser nulo" } }; } Resultado <X509Certificate2> _resultadoCert = Lib.Library.recuperarCertificadoEnvio(Guid, _cnpj); if (_resultadoCert.Sucesso) { X509Certificate2 _cert = _resultadoCert.Retorno; CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); string _exportedKeyMaterial = _cert.PrivateKey.ToXmlString(true); RSACryptoServiceProvider _key = new RSACryptoServiceProvider(new CspParameters(24)) { PersistKeyInCsp = false }; _key.FromXmlString(_exportedKeyMaterial); KeyInfo _keyInfo = new KeyInfo(); _keyInfo.AddClause(new KeyInfoX509Data(_cert)); var _xmlElements = _xml.GetElementsByTagName("eventos").Cast <XmlElement>().FirstOrDefault() .GetElementsByTagName("eSocial").Cast <XmlElement>().ToList(); foreach (XmlElement _xmlEle in _xmlElements) { string _id = _xmlEle.FirstChild.Attributes["Id"].Value; XmlDocument _newXML = new XmlDocument(); _newXML.LoadXml(_xmlEle.OuterXml); SignedXml _assinador = new SignedXml(_newXML) { SigningKey = _key }; _assinador.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; Reference _reference = new Reference(""); _reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); _reference.AddTransform(new XmlDsigC14NTransform()); _reference.Uri = ""; _reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; _assinador.AddReference(_reference); _assinador.KeyInfo = _keyInfo; _assinador.ComputeSignature(); _xmlEle.AppendChild(_xml.ImportNode(_assinador.GetXml(), true)); } } else { _resultado.Sucesso = false; _resultado.Mensagens = new Base.ResultadoMensagem[] { new Base.ResultadoMensagem() { Texto = _resultadoCert.Mensagem } }; } return(_resultado); }
// <Snippet2> // Sign an XML file and save the signature in a new file. public static void SignXmlFile(string FileName, string SignedFileName, RSA Key, string Certificate) { // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. doc.Load(new XmlTextReader(FileName)); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document. signedXml.SigningKey = Key; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object. KeyInfo keyInfo = new KeyInfo(); // Load the X509 certificate. X509Certificate MSCert = X509Certificate.CreateFromCertFile(Certificate); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(MSCert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); }
static void Main(string[] args) { Console.WriteLine("Hello World!"); var stopWatch = Stopwatch.StartNew(); var certificateFinder = new CertificateFinder(); var certInfo = certificateFinder.GetCertInfo(); Console.WriteLine($"GetCertInfo ticks: {stopWatch.ElapsedTicks}"); var xmlDocs = CreateTwoXmlDocs(); SecureString pinCode = new SecureString(); pinCode.AppendChar('6'); pinCode.AppendChar('8'); pinCode.AppendChar('6'); pinCode.AppendChar('1'); using (var key = certificateFinder.GetKey(certInfo, pinCode)) { Console.WriteLine($"GetKey ticks: {stopWatch.ElapsedTicks}"); foreach (var xmlDoc in xmlDocs) { var signedXml = new SignedXml(xmlDoc) { SigningKey = key }; var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certInfo.SelectedCertificate.Certificate, X509IncludeOption.EndCertOnly)); signedXml.KeyInfo = keyInfo; // Create a reference to be signed. var reference = new Reference(); reference.Uri = string.Empty; // Add an enveloped transformation to the reference. var env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Compute the signature. signedXml.ComputeSignature(); Console.WriteLine($"ComputeSignature ticks: {stopWatch.ElapsedTicks}"); var signature = signedXml.GetXml(); var certificateSerialNumber = certInfo.SelectedCertificate.Certificate.SerialNumber; xmlDoc.DocumentElement.AppendChild(signature); //perSigningCallback?.Invoke(); } } Console.WriteLine("\nDone! Press any key to exit"); Console.ReadKey(); }
public async Task <FirmadoResponse> FirmarXml(FirmadoRequest request) { var task = Task.Factory.StartNew(() => { var response = new FirmadoResponse(); var certificate = new X509Certificate2(); certificate.Import(Convert.FromBase64String(request.CertificadoDigital), request.PasswordCertificado, X509KeyStorageFlags.MachineKeySet); var xmlDoc = new XmlDocument(); string resultado; var betterBytes = Encoding.Convert(Encoding.UTF8, Encoding.GetEncoding(Formatos.EncodingIso), Convert.FromBase64String(request.TramaXmlSinFirma)); using (var documento = new MemoryStream(betterBytes)) { xmlDoc.PreserveWhitespace = false; xmlDoc.Load(documento); var indiceNodo = request.UnSoloNodoExtension ? 0 : 1; var nodoExtension = xmlDoc.GetElementsByTagName("ExtensionContent", EspacioNombres.ext) .Item(indiceNodo); if (nodoExtension == null) { throw new InvalidOperationException("No se pudo encontrar el nodo ExtensionContent en el XML"); } nodoExtension.RemoveAll(); // Creamos el objeto SignedXml. var signedXml = new SignedXml(xmlDoc) { SigningKey = certificate.PrivateKey }; var xmlSignature = signedXml.Signature; var env = new XmlDsigEnvelopedSignatureTransform(); var reference = new Reference(string.Empty); reference.AddTransform(env); xmlSignature.SignedInfo.AddReference(reference); var keyInfo = new KeyInfo(); var x509Data = new KeyInfoX509Data(certificate); x509Data.AddSubjectName(certificate.Subject); keyInfo.AddClause(x509Data); xmlSignature.KeyInfo = keyInfo; xmlSignature.Id = "SignOpenInvoicePeru"; signedXml.ComputeSignature(); // Recuperamos el valor Hash de la firma para este documento. if (reference.DigestValue != null) { response.ResumenFirma = Convert.ToBase64String(reference.DigestValue); } response.ValorFirma = Convert.ToBase64String(signedXml.SignatureValue); nodoExtension.AppendChild(signedXml.GetXml()); using (var memDoc = new MemoryStream()) { using (var writer = XmlWriter.Create(memDoc, new XmlWriterSettings { Encoding = Encoding.GetEncoding(Formatos.EncodingIso) })) { xmlDoc.WriteTo(writer); } resultado = Convert.ToBase64String(memDoc.ToArray()); } } response.TramaXmlFirmado = resultado; return(response); }); return(await task); }
public static string FirmarDocumentoXML(string pathXmlDocument, string RutaCertificadoDigital, string PasswordCertificado) { XmlDocument documentXml = new XmlDocument(); documentXml.PreserveWhitespace = true; documentXml.Load(pathXmlDocument); var nodoExtension = documentXml.GetElementsByTagName("ExtensionContent", EspacioNombres.CommonExtensionComponents).Item(0); if (nodoExtension == null) { throw new InvalidOperationException("No se pudo encontrar el nodo ExtensionContent en el XML"); } nodoExtension.RemoveAll(); SignedXml firmado = new SignedXml(documentXml); var xmlSignature = firmado.Signature; var cert = RSAHelper.GetX509Certificate(RutaCertificadoDigital, PasswordCertificado); firmado.SigningKey = (RSA)cert.PrivateKey; //digest info agregada en la seccion firma var env = new XmlDsigEnvelopedSignatureTransform(); Reference reference = new Reference(); reference.AddTransform(env); reference.Uri = ""; firmado.AddReference(reference); firmado.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; reference.DigestMethod = "http://www.w3.org/2000/09/xmldsig#sha1"; // info para la llave publica KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); xmlSignature.KeyInfo = keyInfo; xmlSignature.Id = "SignatureErickOrlando"; firmado.ComputeSignature(); // Recuperamos el valor Hash de la firma para este documento. if (reference.DigestValue != null) { ModuloDoc moduloFactura = new ModuloDoc(); moduloFactura.DigestValue = Convert.ToBase64String(reference.DigestValue); } nodoExtension.AppendChild(firmado.GetXml()); var settings = new XmlWriterSettings() { Encoding = Encoding.GetEncoding("ISO-8859-1") }; string resultado = String.Empty; using (var memDoc = new MemoryStream()) { using (var writer = XmlWriter.Create(memDoc, settings)) { documentXml.WriteTo(writer); } resultado = Convert.ToBase64String(memDoc.ToArray()); } return(resultado); }
public int Assinar(string XMLString, string RefUri, X509Certificate2 X509Cert) /* * Entradas: * XMLString: string XML a ser assinada * RefUri : Referência da URI a ser assinada (Ex. infNFe * X509Cert : certificado digital a ser utilizado na assinatura digital * * Retornos: * Assinar : 0 - Assinatura realizada com sucesso * 1 - Erro: Problema ao acessar o certificado digital - %exceção% * 2 - Problemas no certificado digital * 3 - XML mal formado + exceção * 4 - A tag de assinatura %RefUri% inexiste * 5 - A tag de assinatura %RefUri% não é unica * 6 - Erro Ao assinar o documento - ID deve ser string %RefUri(Atributo)% * 7 - Erro: Ao assinar o documento - %exceção% * * XMLStringAssinado : string XML assinada * * XMLDocAssinado : XMLDocument do XML assinado */ { int resultado = 0; msgResultado = "Assinatura realizada com sucesso"; try { // certificado para ser utilizado na assinatura // string _xnome = ""; if (X509Cert != null) { // certificado ok ///_X509Cert = collection1[0]; string x; x = X509Cert.GetKeyAlgorithm().ToString(); // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = true; // Load the passed XML file using it's name. try { doc.LoadXml(XMLString); // Verifica se a tag a ser assinada existe é única int qtdeRefUri = doc.GetElementsByTagName(RefUri).Count; if (qtdeRefUri == 0) { // a URI indicada não existe resultado = 4; msgResultado = "A tag de assinatura " + RefUri.Trim() + " inexiste"; } // Exsiste mais de uma tag a ser assinada else { if (qtdeRefUri > 1) { // existe mais de uma URI indicada resultado = 5; msgResultado = "A tag de assinatura " + RefUri.Trim() + " não é unica"; } //else if (_listaNum.IndexOf(doc.GetElementsByTagName(RefUri).Item(0).Attributes.ToString().Substring(1,1))>0) //{ // resultado = 6; // msgResultado = "Erro: Ao assinar o documento - ID deve ser string (" + doc.GetElementsByTagName(RefUri).Item(0).Attributes + ")"; //} else { try { // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document signedXml.SigningKey = X509Cert.PrivateKey; // Create a reference to be signed signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url; Reference reference = new Reference(); // pega o uri que deve ser assinada XmlAttributeCollection _Uri = doc.GetElementsByTagName(RefUri).Item(0).Attributes; foreach (XmlAttribute _atributo in _Uri) { if (_atributo.Name == "Id") { reference.Uri = "#" + _atributo.InnerText; } } // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigC14NTransform c14 = new XmlDsigC14NTransform(); reference.AddTransform(c14); reference.DigestMethod = SignedXml.XmlDsigSHA1Url; // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object KeyInfo keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(X509Cert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); XMLDoc = new XmlDocument(); XMLDoc.PreserveWhitespace = true; XMLDoc = doc; XMLDoc.Save("/storage/emulated/0/certificados/xml.xml"); } catch (Exception caught) { resultado = 7; msgResultado = "Erro: Ao assinar o documento - " + caught.Message; } } } } catch (Exception caught) { resultado = 3; msgResultado = "Erro: XML mal formado - " + caught.Message; } } } catch (Exception caught) { resultado = 1; msgResultado = "Erro: Problema ao acessar o certificado digital" + caught.Message; } return(resultado); }
private void Assinar(ref XmlDocument conteudoXML, string tagAssinatura, string tagAtributoId, X509Certificate2 x509Cert, Empresa empresa, EnumAlgorithmType algorithmType = EnumAlgorithmType.Sha1, string idAttributeName = "", bool definirURI = true, string pinCertificado = "") { try { //if (x509Cert == null) // throw new ExceptionCertificadoDigital(ErroPadrao.CertificadoNaoEncontrado); if (conteudoXML.GetElementsByTagName(tagAssinatura).Count == 0) { throw new Exception("A tag de assinatura " + tagAssinatura.Trim() + " não existe no XML. (Código do Erro: 5)"); } else if (conteudoXML.GetElementsByTagName(tagAtributoId).Count == 0) { throw new Exception("A tag de assinatura " + tagAtributoId.Trim() + " não existe no XML. (Código do Erro: 4)"); } else { XmlNodeList lists = conteudoXML.GetElementsByTagName(tagAssinatura); XmlNode listRPS = null; /// Esta condição foi feita especificamente para prefeitura de Governador Valadares pois o AtribudoID e o Elemento assinado devem possuir o mesmo nome. /// Talvez tenha que ser reavaliado. #region Governador Valadares if (tagAssinatura.Equals(tagAtributoId) && empresa.UnidadeFederativaCodigo == 3127701) { foreach (XmlNode item in lists) { if (listRPS == null) { listRPS = item; } if (item.Name.Equals(tagAssinatura)) { lists = item.ChildNodes; break; } } } #endregion Governador Valadares foreach (XmlNode nodes in lists) { foreach (XmlNode childNodes in nodes.ChildNodes) { if (!childNodes.Name.Equals(tagAtributoId)) { continue; } var reference = new Reference { Uri = "" }; // pega o uri que deve ser assinada var childElemen = (XmlElement)childNodes; if (definirURI) { if (string.IsNullOrEmpty(idAttributeName)) { if (childElemen.GetAttributeNode("Id") != null) { idAttributeName = "Id"; } else if (childElemen.GetAttributeNode("id") != null) { idAttributeName = "id"; } } else { reference.Uri = "#" + childElemen.GetAttributeNode(idAttributeName).Value; } } var signedXml = new SignedXml(conteudoXML); if (!string.IsNullOrWhiteSpace(pinCertificado)) { //x509Cert.SetPinPrivateKey(pinCertificado); } reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigC14NTransform()); switch (algorithmType) { case EnumAlgorithmType.Sha256: signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; signedXml.SigningKey = x509Cert.GetRSAPrivateKey(); signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; break; default: signedXml.SigningKey = x509Cert.PrivateKey; signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; reference.DigestMethod = "http://www.w3.org/2000/09/xmldsig#sha1"; break; } // Add an enveloped transformation to the reference. reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigC14NTransform()); signedXml.AddReference(reference); var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(x509Cert)); signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); var xmlDigitalSignature = signedXml.GetXml(); if (tagAssinatura.Equals(tagAtributoId) && empresa.UnidadeFederativaCodigo == 3127701) { ///Desenvolvido especificamente para prefeitura de governador valadares listRPS.AppendChild(conteudoXML.ImportNode(xmlDigitalSignature, true)); } else { // Gravar o elemento no documento XML nodes.AppendChild(conteudoXML.ImportNode(xmlDigitalSignature, true)); } } } } } catch (CryptographicException ex) { AssinaturaValida = false; throw; } }
public static XmlDocument Assinar(XmlDocument docXML, string pUri, X509Certificate2 pCertificado) { try { // Load the certificate from the certificate store. X509Certificate2 cert = pCertificado; // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. doc = docXML; // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document. signedXml.SigningKey = cert.PrivateKey; // Create a reference to be signed. Reference reference = new Reference(); // pega o uri que deve ser assinada XmlAttributeCollection _Uri = doc.GetElementsByTagName(pUri).Item(0).Attributes; foreach (XmlAttribute _atributo in _Uri) { if (_atributo.Name == "Id") { reference.Uri = "#" + _atributo.InnerText; } } // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigC14NTransform c14 = new XmlDsigC14NTransform(); reference.AddTransform(c14); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object. KeyInfo keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(cert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } return doc; } catch (Exception ex) { throw new Exception("Erro ao efetuar assinatura digital, detalhes: " + ex.Message); } }
public static XmlDocument SignXml(string XMLtext, string SubjectName, string privateKey) { if (null == XMLtext) { throw new ArgumentNullException("XMLtext"); } if (null == SubjectName) { throw new ArgumentNullException("SubjectName"); } // Load the certificate from the certificate store. X509Certificate2 cert = new X509Certificate2(StringToByteArray(SubjectName)); // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. doc.LoadXml(XMLtext); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); RSA rsa = new RSACng(); rsa.ImportRSAPrivateKey(Convert.FromBase64String(privateKey), out _); // Add the key to the SignedXml document. signedXml.SigningKey = rsa; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object. KeyInfo keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(cert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. return(doc); }
static void Main(string[] args) { X509Certificate2 x509Certificate2 = GetCertificate("990B25F50DC7E2B548BE75AFED579448"); //X509Certificate2 x509Certificate2 = GetCertificate("0efb7eebdcda4f64a718db3ff908b085"); //X509Certificate2 x509Certificate2 = GetCertificate("2E0A6058EA90DB8C46D1FD3513A877F8"); DCinemaSecurityMessageType extraTheatreMessage = new DCinemaSecurityMessageType(); XmlSerializer xmlSerializer = new XmlSerializer(extraTheatreMessage.GetType()); extraTheatreMessage.AuthenticatedPublic = new AuthenticatedPublicType(); extraTheatreMessage.AuthenticatedPublic.Id = "AuthenticatedPublic.Id." + Guid.NewGuid().ToString(); extraTheatreMessage.AuthenticatedPublic.MessageId = "urn:uuid:" + Guid.NewGuid().ToString(); extraTheatreMessage.AuthenticatedPublic.MessageType = "http://www.smpte-ra.org/schemas/430-3/2006/ETM"; extraTheatreMessage.AuthenticatedPublic.AnnotationText = new UserText(); extraTheatreMessage.AuthenticatedPublic.AnnotationText.Value = "Empty Extra-Theatre Message"; extraTheatreMessage.AuthenticatedPublic.AnnotationText.language = "en-us"; extraTheatreMessage.AuthenticatedPublic.IssueDate = DateTime.Now; X509IssuerSerial issuerSerial = new X509IssuerSerial(); issuerSerial.IssuerName = x509Certificate2.IssuerName.Name; issuerSerial.SerialNumber = x509Certificate2.SerialNumber; extraTheatreMessage.AuthenticatedPublic.Signer = issuerSerial; extraTheatreMessage.AuthenticatedPrivate = new AuthenticatedPrivateType(); extraTheatreMessage.AuthenticatedPrivate.Id = "AuthenticatedPrivate.Id." + Guid.NewGuid().ToString(); #region Build the signature elements SignedXml signedXml = null; try { signedXml = new SignedXml(); signedXml.SigningKey = x509Certificate2.PrivateKey; //signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/ 2001/04/xmldsig-more#rsasha256"; //signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315#WithComments"; StringWriter stringWriter = new StringWriter(); xmlSerializer.Serialize(stringWriter, extraTheatreMessage); string serializedXML = stringWriter.ToString(); #region Build the AuthenticatedPublic DataObject & Reference string xmlAuthenticatedPublic = GetCleanElement(serializedXML, "AuthenticatedPublic"); XmlDocument docAuthenticatedPublic = new XmlDocument(); docAuthenticatedPublic.LoadXml(xmlAuthenticatedPublic.ToString()); //XmlAttribute attrAuthenticatedPublic = docAuthenticatedPublic.CreateAttribute("xmlns"); //attrAuthenticatedPublic.Value = "http://www.smpte-ra.org/schemas/430-3/2006/ETM"; //docAuthenticatedPublic.DocumentElement.Attributes.Append(attrAuthenticatedPublic); DataObject dataObjectAuthenticatedPublic = new DataObject("AuthenticatedPublic", "", "", docAuthenticatedPublic.DocumentElement); //DataObject dataObjectAuthenticatedPublic = new DataObject(); dataObjectAuthenticatedPublic.Data = docAuthenticatedPublic.ChildNodes; dataObjectAuthenticatedPublic.Id = "AuthenticatedPublic"; signedXml.AddObject(dataObjectAuthenticatedPublic); Reference referenceAuthenticatedPublic = new Reference(); referenceAuthenticatedPublic.Uri = "#AuthenticatedPublic"; referenceAuthenticatedPublic.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; signedXml.AddReference(referenceAuthenticatedPublic); #endregion #region Build the AuthenticatedPublic DataObject & Reference string xmlAuthenticatedPrivate = GetCleanElement(serializedXML, "AuthenticatedPrivate"); XmlDocument docAuthenticatedPrivate = new XmlDocument(); docAuthenticatedPrivate.LoadXml(xmlAuthenticatedPrivate.ToString()); //XmlAttribute attrAuthenticatedPrivate = docAuthenticatedPrivate.CreateAttribute("xmlns"); //attrAuthenticatedPrivate.Value = "http://www.smpte-ra.org/schemas/430-3/2006/FLM"; //docAuthenticatedPrivate.DocumentElement.Attributes.Append(attrAuthenticatedPrivate); DataObject dataObjectAuthenticatedPrivate = new DataObject("AuthenticatedPrivate", "", "", docAuthenticatedPrivate.DocumentElement); //DataObject dataObjectAuthenticatedPrivate = new DataObject("AuthenticatedPrivate", "", "", docAuthenticatedPrivate.DocumentElement); //dataObjectAuthenticatedPrivate.Data = docAuthenticatedPrivate.ChildNodes; //dataObjectAuthenticatedPrivate.Id = "AuthenticatedPrivate"; signedXml.AddObject(dataObjectAuthenticatedPrivate); Reference referenceAuthenticatedPrivate = new Reference(); referenceAuthenticatedPrivate.Uri = "#AuthenticatedPrivate"; referenceAuthenticatedPrivate.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; // Add the reference to the message. signedXml.AddReference(referenceAuthenticatedPrivate); #endregion // Add a KeyInfo. KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(x509Certificate2, X509IncludeOption.WholeChain)); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); XmlElement singedElement = signedXml.GetXml(); XmlSerializer signedSerializer = new XmlSerializer(singedElement.GetType()); StreamWriter signedWriter = new StreamWriter("D:\\signedSerializer.Test.xml"); signedSerializer.Serialize(signedWriter, singedElement); signedWriter.Close(); } catch (CryptographicException e) { Console.WriteLine(e.Message); } #endregion #region Fill in the signature element extraTheatreMessage.Signature = signedXml.Signature.GetXml(); #endregion xmlSerializer.Serialize(Console.Out, extraTheatreMessage); Console.WriteLine("\r\n"); TextWriter WriteFileStream = new StreamWriter(@"\Source_SMPTE\Output\ExtraTheatreMessage.xml"); xmlSerializer.Serialize(WriteFileStream, extraTheatreMessage); WriteFileStream.Close(); ServiceExtraTheatreMessageClient client = new ServiceExtraTheatreMessageClient(); string response = client.ETM(extraTheatreMessage); DCinemaSecurityMessageType existingETM = new DCinemaSecurityMessageType(); TextReader readFileStream = new StreamReader(@"\Source_SMPTE\Input\DCinemaSecurityMessageType_AMC.xml"); existingETM = (DCinemaSecurityMessageType)xmlSerializer.Deserialize(readFileStream); readFileStream.Close(); existingETM.AuthenticatedPrivate = new AuthenticatedPrivateType(); existingETM.Signature = signedXml.Signature.GetXml(); WriteFileStream = new StreamWriter(@"\Source_SMPTE\Output\Read_ExtraTheatreMessage.xml"); xmlSerializer.Serialize(WriteFileStream, existingETM); WriteFileStream.Close(); response = client.ETM(existingETM); }
/// <summary> /// O método assina digitalmente o arquivo XML passado por parâmetro e /// grava o XML assinado com o mesmo nome, sobreponto o XML informado por parâmetro. /// Disponibiliza também uma propriedade com uma string do xml assinado (this.vXmlStringAssinado) /// </summary> /// <param name="conteudoXML">Conteúdo do XML</param> /// <param name="tagAssinatura">Nome da tag onde é para ficar a assinatura</param> /// <param name="tagAtributoId">Nome da tag que tem o atributo ID, tag que vai ser assinada</param> /// <param name="x509Cert">Certificado a ser utilizado na assinatura</param> /// <param name="empresa">Índice da empresa que está solicitando a assinatura</param> /// <param name="algorithmType">Tipo de algoritimo para assinatura do XML.</param> /// <remarks> /// Autor: Wandrey Mundin Ferreira /// Data: 04/06/2008 /// </remarks> private void Assinar(XmlDocument conteudoXML, string tagAssinatura, string tagAtributoId, X509Certificate2 x509Cert, int empresa, AlgorithmType algorithmType, bool comURI) { try { if (conteudoXML.GetElementsByTagName(tagAssinatura).Count == 0) { throw new Exception("A tag de assinatura " + tagAssinatura.Trim() + " não existe no XML. (Código do Erro: 5)"); } else if (conteudoXML.GetElementsByTagName(tagAtributoId).Count == 0) { throw new Exception("A tag de assinatura " + tagAtributoId.Trim() + " não existe no XML. (Código do Erro: 4)"); } // Existe mais de uma tag a ser assinada else { XmlNodeList lists = conteudoXML.GetElementsByTagName(tagAssinatura); XmlNode listRPS = null; /// Esta condição foi feita especificamente para prefeitura de Governador Valadares pois o AtribudoID e o Elemento assinado devem possuir o mesmo nome. /// Talvez tenha que ser reavaliado. #region Governador Valadares if (tagAssinatura.Equals(tagAtributoId) && Empresas.Configuracoes[empresa].UnidadeFederativaCodigo == 3127701) { foreach (XmlNode item in lists) { if (listRPS == null) { listRPS = item; } if (item.Name.Equals(tagAssinatura)) { lists = item.ChildNodes; break; } } } #endregion Governador Valadares foreach (XmlNode nodes in lists) { foreach (XmlNode childNodes in nodes.ChildNodes) { if (!childNodes.Name.Equals(tagAtributoId)) { continue; } // Create a reference to be signed Reference reference = new Reference(); reference.Uri = ""; // pega o uri que deve ser assinada XmlElement childElemen = (XmlElement)childNodes; if (comURI) { if (childElemen.GetAttributeNode("Id") != null) { reference.Uri = "#" + childElemen.GetAttributeNode("Id").Value; } else if (childElemen.GetAttributeNode("id") != null) { reference.Uri = "#" + childElemen.GetAttributeNode("id").Value; } } // Create a SignedXml object. SignedXml signedXml = new SignedXml(conteudoXML); #if _fw46 //A3 if (!String.IsNullOrEmpty(Empresas.Configuracoes[empresa].CertificadoPIN) && clsX509Certificate2Extension.IsA3(x509Cert) && !Empresas.Configuracoes[empresa].CertificadoPINCarregado) { x509Cert.SetPinPrivateKey(Empresas.Configuracoes[empresa].CertificadoPIN); Empresas.Configuracoes[empresa].CertificadoPINCarregado = true; } if (algorithmType.Equals(AlgorithmType.Sha256)) { signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; signedXml.SigningKey = x509Cert.GetRSAPrivateKey(); } #endif if (algorithmType.Equals(AlgorithmType.Sha1)) { signedXml.SigningKey = x509Cert.PrivateKey; } // Add an enveloped transformation to the reference. reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigC14NTransform()); // Add the reference to the SignedXml object. signedXml.AddReference(reference); #if _fw46 if (algorithmType.Equals(AlgorithmType.Sha256)) { reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; } #endif // Create a new KeyInfo object KeyInfo keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(x509Cert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); if (tagAssinatura.Equals(tagAtributoId) && Empresas.Configuracoes[empresa].UnidadeFederativaCodigo == 3127701) { ///Desenvolvido especificamente para prefeitura de governador valadares listRPS.AppendChild(conteudoXML.ImportNode(xmlDigitalSignature, true)); } else { // Gravar o elemento no documento XML nodes.AppendChild(conteudoXML.ImportNode(xmlDigitalSignature, true)); } } } } } catch (CryptographicException ex) { #region #10316 /* * Solução para o problema do certificado do tipo A3 * Marcelo * 29/07/2013 */ AssinaturaValida = false; if (clsX509Certificate2Extension.IsA3(x509Cert)) { x509Cert = Empresas.ResetCertificado(empresa); if (!TesteCertificado) { throw new Exception("O certificado deverá ser reiniciado.\r\n Retire o certificado.\r\nAguarde o LED terminar de piscar.\r\n Recoloque o certificado e informe o PIN novamente.\r\n" + ex.ToString());// #12342 concatenar com a mensagem original } } else { throw; } #endregion #10316 } catch { throw; } }
/// <summary> /// Sign an xml element with the supplied cert. /// </summary> /// <param name="xmlElement">xmlElement to be signed. The signature is /// added as a node in the document, right after the Issuer node.</param> /// <param name="cert">Certificate to use when signing.</param> /// <param name="includeKeyInfo">Include public key in signed output.</param> /// <param name="signingAlgorithm">The signing algorithm to use.</param> public static void Sign( this XmlElement xmlElement, X509Certificate2 cert, bool includeKeyInfo, string signingAlgorithm) { if (xmlElement == null) { throw new ArgumentNullException(nameof(xmlElement)); } if (cert == null) { throw new ArgumentNullException(nameof(cert)); } var signedXml = new SignedXmlWithIdFix(xmlElement.OwnerDocument); // The transform XmlDsigExcC14NTransform and canonicalization method XmlDsigExcC14NTransformUrl is important for partially signed XML files // see: http://msdn.microsoft.com/en-us/library/system.security.cryptography.xml.signedxml.xmldsigexcc14ntransformurl(v=vs.110).aspx // The reference URI has to be set correctly to avoid assertion injections // For both, the ID/Reference and the Transform/Canonicalization see as well: // https://www.oasis-open.org/committees/download.php/35711/sstc-saml-core-errata-2.0-wd-06-diff.pdf section 5.4.2 and 5.4.3 signedXml.SigningKey = EnvironmentHelpers.IsNetCore ? cert.PrivateKey : ((RSACryptoServiceProvider)cert.PrivateKey) .GetSha256EnabledRSACryptoServiceProvider(); signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; signedXml.SignedInfo.SignatureMethod = signingAlgorithm; // We need a document unique ID on the element to sign it -- make one up if it's missing string id = xmlElement.GetAttribute("ID"); if (String.IsNullOrEmpty(id)) { id = "_" + Guid.NewGuid().ToString("N"); xmlElement.SetAttribute("ID", id); } var reference = new Reference { Uri = "#" + id, DigestMethod = GetCorrespondingDigestAlgorithm(signingAlgorithm) }; reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); reference.AddTransform(new XmlDsigExcC14NTransform()); signedXml.AddReference(reference); signedXml.ComputeSignature(); if (includeKeyInfo) { var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); signedXml.KeyInfo = keyInfo; } xmlElement.InsertAfter( xmlElement.OwnerDocument.ImportNode(signedXml.GetXml(), true), xmlElement["Issuer", Saml2Namespaces.Saml2Name]); }
public string SignXmlFile(XmlDocument xmlDocument, X509Certificate2 certificate, string xmlSignatureSyntax) { if (xmlDocument == null) { throw new ArgumentException($"{nameof(xmlDocument)} cannot be null. Please supply a valid xml document"); } if (certificate == null) { throw new ArgumentException($"{nameof(certificate)} cannot be null. Please supply a valid certificate"); } if (string.IsNullOrWhiteSpace(xmlSignatureSyntax)) { throw new ArgumentException($"{nameof(xmlSignatureSyntax)} cannot be null. Please supply a valid XmlSignatureSyntax"); } // Load xml and set signing parameters var signedXml = new CustomIdSignedXml(xmlDocument); signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigC14NTransformUrl; signedXml.SignedInfo.SignatureMethod = SignatureMethod; signedXml.SigningKey = certificate.GetRSAPrivateKey();; // Set the namespases var nsmgr = new XmlNamespaceManager(xmlDocument.NameTable); nsmgr.AddNamespace("ns", xmlSignatureSyntax); nsmgr.AddNamespace("ns2", NS2); // Select message node for signing var reference = new Reference(); reference.DigestMethod = DigestMethod; reference.Uri = "#" + xmlDocument.SelectSingleNode($"//ns:{MessageElementName}", nsmgr) .Attributes["messageId"].Value; signedXml.AddReference(reference); // Set signing key and sign xml data var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certificate)); signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); // Get signature var xmlDigitalSignature = signedXml.GetXml(); // Assign ds prefix AssignNameSpacePrefixToElementTree(xmlDigitalSignature, CustomPrefix); //load SignedInfo and compute final signature based on correct SignedInfo signedXml.LoadXml(xmlDigitalSignature); signedXml.SignedInfo.References.Clear(); signedXml.ComputeSignature(); // Replace signature ReplaceSignature(xmlDigitalSignature, Convert.ToBase64String(signedXml.SignatureValue)); // Append signature to the xml doc xmlDocument.DocumentElement.AppendChild(xmlDocument.ImportNode(xmlDigitalSignature, true)); using var stringWriter = new StringWriter(); using var xmlTextWriter = new XmlTextWriter(stringWriter); xmlDocument.WriteTo(xmlTextWriter); xmlTextWriter.Flush(); return(stringWriter.ToString()); }
// Třída podepíše certifikátem dokument XML // Pokud je již dokument podepsaný, přidá se další podpis public XmlDocument Sign(XmlDocument doc, X509Certificate2 cert) { // před podepisováním z dokumentu odstraníme komentáře (.NET s nimi má problémy pokud se kombinují s XPath transformacemi) XmlDocument strippedDoc = RemoveComments(doc); // definice mapování prefixů na jmenné prostory XmlNamespaceManager manager = new XmlNamespaceManager(strippedDoc.NameTable); manager.AddNamespace("dsig", "http://www.w3.org/2000/09/xmldsig#"); // zjištění kolik podpisů již v dokumentu je int signatures = strippedDoc.SelectNodes("//dsig:Signature", manager).Count; // objekt sloužící pro vytvoření podpisu SignedXml signedXml = new SignedXml(strippedDoc); // podepisovat budeme privátním klíčem z certifikátu signedXml.SigningKey = cert.PrivateKey; // podepisovat budeme pomocí RSA-SHA256 signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; // reference na podepisovaný dokument ("" znamená celý dokument) Reference reference = new Reference(); reference.Uri = ""; // pro výpočet otisku se bude používat SHA-256 reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; // digitální podpis bude přímo součástí dokumentu XML (tzv. "enveloped signature") XmlDsigEnvelopedSignatureTransform envTransform = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envTransform); // navíc budeme používat XPath transoformaci, která dovoluje přidat několik podpisů najednou XmlDsigXPathTransform xpathTransform = new XmlDsigXPathTransform(); // příprava definice XPath transformace jako struktura XML signature XmlDocument transformBody = new XmlDocument(); // podoba XPath filtru se liší podle počtu podpisů if (signatures == 0) { transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature)</dsig:XPath>"); } else { transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature) or not(ancestor-or-self::dsig:Signature/preceding-sibling::dsig:Signature[" + signatures + "])</dsig:XPath>"); } // načtení definice XPath transformace do objektu xpathTransform.LoadInnerXml(transformBody.SelectNodes("/*[1]")); // přidání XPath transformace reference.AddTransform(xpathTransform); // přidání reference do podpisu signedXml.AddReference(reference); // přidání certifikátu do podpisu KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); signedXml.KeyInfo = keyInfo; // výpočet podpisu signedXml.ComputeSignature(); // získání XML reprezentace podpisu XmlElement xmlSignature = signedXml.GetXml(); // k podpisu přidáme identifikátor, tak jak doporučuje standard ISDOC xmlSignature.SetAttribute("Id", "Signature-" + (signatures + 1)); // XML dokument pro podepsaný výsledek XmlDocument result = new XmlDocument(); // bílé znaky musíme zachovat, jinak se špatně spočte hash result.PreserveWhitespace = true; // načtení původního dokumentu result.AppendChild(result.ImportNode(strippedDoc.DocumentElement, true)); // připojení podpisu na konec dokumentu XML result.DocumentElement.AppendChild(result.ImportNode(xmlSignature, true)); return(result); }
/// <summary> /// Realiza la contrafirma de la firma actual /// </summary> /// <param name="sigDocument"></param> /// <param name="parameters"></param> public SignatureDocument CounterSign(SignatureDocument sigDocument, SignatureParameters parameters) { if (parameters.Signer == null) { throw new Exception("Es necesario un certificado válido para la firma."); } SignatureDocument.CheckSignatureDocument(sigDocument); SignatureDocument counterSigDocument = new SignatureDocument(); counterSigDocument.Document = (XmlDocument)sigDocument.Document.Clone(); counterSigDocument.Document.PreserveWhitespace = true; XadesSignedXml counterSignature = new XadesSignedXml(counterSigDocument.Document); SetSignatureId(counterSignature); counterSignature.SigningKey = parameters.Signer.SigningKey; counterSignature.HsmWrapper = parameters.Signer.HsmWrapper; _refContent = new Reference(); _refContent.Uri = "#" + sigDocument.XadesSignature.SignatureValueId; _refContent.Id = "Reference-" + Guid.NewGuid().ToString(); _refContent.Type = "http://uri.etsi.org/01903#CountersignedSignature"; _refContent.AddTransform(new XmlDsigC14NTransform()); counterSignature.AddReference(_refContent); _dataFormat = new DataObjectFormat(); _dataFormat.MimeType = "text/xml"; _dataFormat.Encoding = "UTF-8"; KeyInfo keyInfo = new KeyInfo(); keyInfo.Id = "KeyInfoId-" + counterSignature.Signature.Id; var signerCertificate = parameters.Signer.Certificate; var rsapublicKey = signerCertificate.GetRSAPublicKey(); keyInfo.AddClause(new KeyInfoX509Data((X509Certificate)signerCertificate)); keyInfo.AddClause(new RSAKeyValue((RSA)rsapublicKey)); counterSignature.KeyInfo = keyInfo; Reference referenceKeyInfo = new Reference(); referenceKeyInfo.Id = "ReferenceKeyInfo-" + counterSignature.Signature.Id; referenceKeyInfo.Uri = "#KeyInfoId-" + counterSignature.Signature.Id; counterSignature.AddReference(referenceKeyInfo); XadesObject counterSignatureXadesObject = new XadesObject(); counterSignatureXadesObject.Id = "CounterSignatureXadesObject-" + Guid.NewGuid().ToString(); counterSignatureXadesObject.QualifyingProperties.Target = "#" + counterSignature.Signature.Id; counterSignatureXadesObject.QualifyingProperties.SignedProperties.Id = "SignedProperties-" + counterSignature.Signature.Id; AddSignatureProperties(counterSigDocument, counterSignatureXadesObject.QualifyingProperties.SignedProperties.SignedSignatureProperties, counterSignatureXadesObject.QualifyingProperties.SignedProperties.SignedDataObjectProperties, counterSignatureXadesObject.QualifyingProperties.UnsignedProperties.UnsignedSignatureProperties, parameters); counterSignature.AddXadesObject(counterSignatureXadesObject); foreach (Reference signReference in counterSignature.SignedInfo.References) { signReference.DigestMethod = parameters.DigestMethod.URI; } counterSignature.SignedInfo.SignatureMethod = parameters.SignatureMethod.URI; counterSignature.AddXadesNamespace = true; counterSignature.ComputeSignature(); counterSigDocument.XadesSignature = new XadesSignedXml(counterSigDocument.Document); counterSigDocument.XadesSignature.LoadXml(sigDocument.XadesSignature.GetXml()); UnsignedProperties unsignedProperties = counterSigDocument.XadesSignature.UnsignedProperties; unsignedProperties.UnsignedSignatureProperties.CounterSignatureCollection.Add(counterSignature); counterSigDocument.XadesSignature.UnsignedProperties = unsignedProperties; counterSigDocument.UpdateDocument(); return(counterSigDocument); }
public void KeyInfoName() { KeyInfoName name = new KeyInfoName(); name.Value = "Mono::"; info.AddClause(name); Assert.Equal("<KeyInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><KeyName>Mono::</KeyName></KeyInfo>", (info.GetXml().OuterXml)); Assert.Equal(1, info.Count); }
// Sign an XML file and save the signature in a new file. public static void SignXmlFile(XmlDocument doc, string signedFileName, RSA key) { // Check the arguments. if (doc == null) { throw new ArgumentNullException("doc"); } if (signedFileName == null) { throw new ArgumentNullException("signedFileName"); } if (key == null) { throw new ArgumentNullException("key"); } // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc) { // Add the key to the SignedXml document. SigningKey = key }; // Create a reference to be signed. Reference reference = new Reference { Uri = string.Empty }; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue(key)); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. if (doc.DocumentElement != null) { doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); } if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(signedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); }
public SignatureDocument CounterSign(SignatureDocument sigDocument, SignatureParameters parameters) { if (parameters.Signer == null) { throw new Exception("Es necesario un certificado válido para la firma."); } SignatureDocument.CheckSignatureDocument(sigDocument); SignatureDocument signatureDocument = new SignatureDocument(); signatureDocument.Document = (XmlDocument)sigDocument.Document.Clone(); signatureDocument.Document.PreserveWhitespace = true; XadesSignedXml xadesSignedXml = new XadesSignedXml(signatureDocument.Document); xadesSignedXml.Signature.Id = "xmldsig-" + Guid.NewGuid().ToString(); xadesSignedXml.SignatureValueId = sigDocument.XadesSignature.Signature.Id + "-sigvalue"; xadesSignedXml.SigningKey = parameters.Signer.SigningKey; _refContent = new Reference(); _refContent.Uri = "#" + sigDocument.XadesSignature.SignatureValueId; Reference refContent = _refContent; Guid guid = Guid.NewGuid(); refContent.Id = "Reference-" + guid.ToString(); _refContent.Type = "http://uri.etsi.org/01903#CountersignedSignature"; _refContent.AddTransform(new XmlDsigC14NTransform()); xadesSignedXml.AddReference(_refContent); _mimeType = "text/xml"; _encoding = "UTF-8"; KeyInfo keyInfo = new KeyInfo(); keyInfo.Id = "KeyInfoId-" + xadesSignedXml.Signature.Id; keyInfo.AddClause(new KeyInfoX509Data(parameters.Signer.Certificate)); keyInfo.AddClause(new RSAKeyValue((RSA)parameters.Signer.SigningKey)); xadesSignedXml.KeyInfo = keyInfo; Reference reference = new Reference(); reference.Id = "ReferenceKeyInfo-" + xadesSignedXml.Signature.Id; reference.Uri = "#KeyInfoId-" + xadesSignedXml.Signature.Id; xadesSignedXml.AddReference(reference); XadesObject xadesObject = new XadesObject(); XadesObject xadesObject2 = xadesObject; guid = Guid.NewGuid(); xadesObject2.Id = "CounterSignatureXadesObject-" + guid.ToString(); xadesObject.QualifyingProperties.Target = "#" + xadesSignedXml.Signature.Id; xadesObject.QualifyingProperties.SignedProperties.Id = "SignedProperties-" + xadesSignedXml.Signature.Id; AddSignatureProperties(signatureDocument, xadesObject.QualifyingProperties.SignedProperties.SignedSignatureProperties, xadesObject.QualifyingProperties.SignedProperties.SignedDataObjectProperties, xadesObject.QualifyingProperties.UnsignedProperties.UnsignedSignatureProperties, parameters); xadesSignedXml.AddXadesObject(xadesObject); foreach (Reference reference2 in xadesSignedXml.SignedInfo.References) { reference2.DigestMethod = parameters.DigestMethod.URI; } xadesSignedXml.SignedInfo.SignatureMethod = parameters.SignatureMethod.URI; xadesSignedXml.AddXadesNamespace = true; xadesSignedXml.ComputeSignature(); signatureDocument.XadesSignature = new XadesSignedXml(signatureDocument.Document); signatureDocument.XadesSignature.LoadXml(sigDocument.XadesSignature.GetXml()); UnsignedProperties unsignedProperties = signatureDocument.XadesSignature.UnsignedProperties; unsignedProperties.UnsignedSignatureProperties.CounterSignatureCollection.Add(xadesSignedXml); signatureDocument.XadesSignature.UnsignedProperties = unsignedProperties; signatureDocument.UpdateDocument(); return(signatureDocument); }
// <Snippet2> // Sign an XML file and save the signature in a new file. public static void SignXmlFile(string FileName, string SignedFileName, string SubjectName) { if (null == FileName) { throw new ArgumentNullException("FileName"); } if (null == SignedFileName) { throw new ArgumentNullException("SignedFileName"); } if (null == SubjectName) { throw new ArgumentNullException("SubjectName"); } // Load the certificate from the certificate store. X509Certificate2 cert = GetCertificateBySubject(SubjectName); // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. doc.Load(new XmlTextReader(FileName)); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document. signedXml.SigningKey = cert.PrivateKey; // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = ""; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object. KeyInfo keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. // Create an X509IssuerSerial object and add it to the // KeyInfoX509Data object. KeyInfoX509Data kdata = new KeyInfoX509Data(cert); X509IssuerSerial xserial; xserial.IssuerName = cert.IssuerName.ToString(); xserial.SerialNumber = cert.SerialNumber; kdata.AddIssuerSerial(xserial.IssuerName, xserial.SerialNumber); keyInfo.AddClause(kdata); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. using (XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false))) { doc.WriteTo(xmltw); xmltw.Close(); } }
public void WriteContentsTo( AddressingVersion addressingVersion, XmlDictionaryWriter writer) { if (writer == null) { throw new ArgumentNullException("writer"); } #if MOBILE if (addressingVersion == AddressingVersion.None) { writer.WriteString(Uri.AbsoluteUri); } else { writer.WriteStartElement("Address", addressingVersion.Namespace); writer.WriteString(Uri.AbsoluteUri); writer.WriteEndElement(); } #else if (addressingVersion == AddressingVersion.None) { writer.WriteString(Uri.AbsoluteUri); } else { writer.WriteStartElement("Address", addressingVersion.Namespace); writer.WriteString(Uri.AbsoluteUri); writer.WriteEndElement(); if (Identity == null) { return; } if (Headers != null) { foreach (AddressHeader ah in Headers) { ah.WriteAddressHeader(writer); } } writer.WriteStartElement("Identity", Constants.WsaIdentityUri); X509CertificateEndpointIdentity x509 = Identity as X509CertificateEndpointIdentity; if (x509 != null) { KeyInfo ki = new KeyInfo(); KeyInfoX509Data x = new KeyInfoX509Data(); foreach (X509Certificate2 cert in x509.Certificates) { x.AddCertificate(cert); } ki.AddClause(x); ki.GetXml().WriteTo(writer); } else { DataContractSerializer ds = new DataContractSerializer(Identity.IdentityClaim.GetType()); ds.WriteObject(writer, Identity.IdentityClaim); } writer.WriteEndElement(); } #endif }
private string Assinar(Nota nota, X509Certificate2 x509Cert, string tagAssinatura, string uri = "") { string xmlString; using (var srReader = File.OpenText(nota.CaminhoFisico)) { xmlString = srReader.ReadToEnd(); } // Create a new XML document. var doc = new XmlDocument { PreserveWhitespace = false }; // Format the document to ignore white spaces. doc.LoadXml(xmlString); var reference = new Reference(); if (!string.IsNullOrEmpty(nota.NotaId)) { reference.Uri = "#" + tagAssinatura + nota.NotaId; } else if (!string.IsNullOrEmpty(uri)) { reference.Uri = uri; } // Create a SignedXml object. var signedXml = new SignedXml(doc) { SigningKey = x509Cert.PrivateKey }; // Add an enveloped transformation to the reference. var env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); var c14 = new XmlDsigC14NTransform(); reference.AddTransform(c14); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object var keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(x509Cert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. var xmlDigitalSignature = signedXml.GetXml(); // Gravar o elemento no documento XML var assinaturaNodes = doc.GetElementsByTagName(tagAssinatura); foreach (XmlNode nodes in assinaturaNodes) { nodes.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); break; } // Atualizar a string do XML já assinada var stringXmlAssinado = doc.OuterXml; //Atualiza a nota assinada nota.ConteudoXml = stringXmlAssinado; // Gravar o XML Assinado no HD var signedFile = nota.CaminhoFisico; var sw2 = File.CreateText(signedFile); sw2.Write(stringXmlAssinado); sw2.Close(); return(signedFile); }
private void Sign(Message message, string[] elementIdsToSign, string[] attachmentsToSign, string wssNamespace, X509Certificate2 certificate) { //Prepare XML to encrypt and sign var element = this.PrepareEncyrptSign(message); bool signEntireDocument = true; string elementToBeSigned = string.Empty; var signedMessage = new XmlDocument(); signedMessage.AppendChild(signedMessage.ImportNode(element, true)); SignatureType signAs = SignatureType.InternallyDetached; signedMessage.PreserveWhitespace = false; OverrideSignedXml signedXml = new OverrideSignedXml(signedMessage); signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; if (elementIdsToSign != null && elementIdsToSign.Length > 0) { bool isContentTransform = this.IsSignatureContentTransform; foreach (string s in elementIdsToSign) { // Create a reference to be signed. Reference reference = new Reference(string.Format("#{0}", s)); reference.AddTransform(new XmlDsigExcC14NTransform()); reference.DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; // Add the reference to the SignedXml object. signedXml.AddReference(reference); } signEntireDocument = false; } // Reference attachments to sign if (attachmentsToSign != null && attachmentsToSign.Length > 0) { bool isContentTransform = this.IsSignatureContentTransform; foreach (string attachmentId in attachmentsToSign) { // Create a reference to be signed. Reference reference = new Reference(string.Format("{0}{1}", Constants.CidUriScheme, attachmentId)); reference.DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; if (isContentTransform) { AttachmentContentSignatureTransform env = new AttachmentContentSignatureTransform(); reference.AddTransform(env); } else { AttachmentCompleteSignatureTransform env = new AttachmentCompleteSignatureTransform(); reference.AddTransform(env); } // Add the reference to the SignedXml object. signedXml.AddReference(reference); } signEntireDocument = false; } if (signEntireDocument) { Reference reference = new Reference(); reference.Uri = ""; reference.DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); signedXml.AddReference(reference); signAs = SignatureType.Enveloped; } string x509CertificateReferenceId = string.Format("{0}-{1}", Constants.IdAttributeName, Guid.NewGuid().ToString("N")); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509SecurityTokenReference(string.Format("#{0}", x509CertificateReferenceId), wssNamespace)); signedXml.KeyInfo = keyInfo; signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; RSA key = (RSACryptoServiceProvider) certificate.PrivateKey; signedXML.SigningKey = key; CidWebRequest.Message = message; signedXml.ComputeSignature(); var xmlSignature = signedXml.GetXml(); XmlDocument unsignedEnvelopeDoc = new XmlDocument(); unsignedEnvelopeDoc.LoadXml(message.MessageAsString); }
/// <summary> /// Obtém a assinatura de um objeto serializável /// </summary> /// <typeparam name="T"></typeparam> /// <param name="objeto"></param> /// <param name="id"></param> /// <param name="certificadoDigital">Informe o certificado digital</param> /// <param name="manterDadosEmCache">Validador para manter o certificado em cache</param> /// <param name="signatureMethod"></param> /// <param name="digestMethod"></param> /// <param name="cfgServicoRemoverAcentos"></param> /// <returns>Retorna um objeto do tipo Classes.Assinatura.Signature, contendo a assinatura do objeto passado como parâmetro</returns> public static Signature ObterAssinatura <T>(T objeto, string id, X509Certificate2 certificadoDigital, bool manterDadosEmCache = false, string signatureMethod = "http://www.w3.org/2000/09/xmldsig#rsa-sha1", string digestMethod = "http://www.w3.org/2000/09/xmldsig#sha1", bool cfgServicoRemoverAcentos = false) where T : class { var objetoLocal = objeto; if (id == null) { throw new Exception("Não é possível assinar um objeto evento sem sua respectiva Id!"); } try { var documento = new XmlDocument { PreserveWhitespace = true }; var xml = cfgServicoRemoverAcentos ? FuncoesXml.ClasseParaXmlString(objetoLocal).RemoverAcentos() : FuncoesXml.ClasseParaXmlString(objetoLocal); documento.LoadXml(xml); var docXml = new SignedXml(documento) { SigningKey = certificadoDigital.PrivateKey }; docXml.SignedInfo.SignatureMethod = signatureMethod; var reference = new Reference { Uri = "#" + id, DigestMethod = digestMethod }; // adicionando EnvelopedSignatureTransform a referencia var envelopedSigntature = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envelopedSigntature); var c14Transform = new XmlDsigC14NTransform(); reference.AddTransform(c14Transform); docXml.AddReference(reference); // carrega o certificado em KeyInfoX509Data para adicionar a KeyInfo var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certificadoDigital)); docXml.KeyInfo = keyInfo; docXml.ComputeSignature(); //// recuperando a representação do XML assinado var xmlDigitalSignature = docXml.GetXml(); var assinatura = FuncoesXml.XmlStringParaClasse <Signature>(xmlDigitalSignature.OuterXml); return(assinatura); } finally { //Marcos Gerene 04/08/2018 - o objeto certificadoDigital nunca será nulo, porque se ele for nulo nem as configs para criar ele teria. //Se não mantém os dados do certificado em cache libera o certificado, chamando o método reset. //if (!manterDadosEmCache & certificadoDigital == null) // certificadoDigital.Reset(); } }
// Třída podepíše certifikátem dokument XML // Pokud je již dokument podepsaný, přidá se další podpis public XmlDocument Sign(XmlDocument doc, X509Certificate2 cert) { // před podepisováním z dokumentu odstraníme komentáře (.NET s nimi má problémy pokud se kombinují s XPath transformacemi) XmlDocument strippedDoc = RemoveComments(doc); // definice mapování prefixů na jmenné prostory XmlNamespaceManager manager = new XmlNamespaceManager(strippedDoc.NameTable); manager.AddNamespace("dsig", "http://www.w3.org/2000/09/xmldsig#"); // zjištění kolik podpisů již v dokumentu je int signatures = strippedDoc.SelectNodes("//dsig:Signature", manager).Count; // objekt sloužící pro vytvoření podpisu SignedXml signedXml = new SignedXml(strippedDoc); // podepisovat budeme privátním klíčem z certifikátu signedXml.SigningKey = cert.PrivateKey; // podepisovat budeme pomocí RSA-SHA256 signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; // reference na podepisovaný dokument ("" znamená celý dokument) Reference reference = new Reference(); reference.Uri = ""; // pro výpočet otisku se bude používat SHA-256 reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; // digitální podpis bude přímo součástí dokumentu XML (tzv. "enveloped signature") XmlDsigEnvelopedSignatureTransform envTransform = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(envTransform); // navíc budeme používat XPath transoformaci, která dovoluje přidat několik podpisů najednou XmlDsigXPathTransform xpathTransform = new XmlDsigXPathTransform(); // příprava definice XPath transformace jako struktura XML signature XmlDocument transformBody = new XmlDocument(); // podoba XPath filtru se liší podle počtu podpisů if (signatures == 0) transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature)</dsig:XPath>"); else transformBody.LoadXml("<dsig:XPath xmlns:dsig='http://www.w3.org/2000/09/xmldsig#'>not(ancestor-or-self::dsig:Signature) or not(ancestor-or-self::dsig:Signature/preceding-sibling::dsig:Signature[" + signatures + "])</dsig:XPath>"); // načtení definice XPath transformace do objektu xpathTransform.LoadInnerXml(transformBody.SelectNodes("/*[1]")); // přidání XPath transformace reference.AddTransform(xpathTransform); // přidání reference do podpisu signedXml.AddReference(reference); // přidání certifikátu do podpisu KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(cert)); signedXml.KeyInfo = keyInfo; // výpočet podpisu signedXml.ComputeSignature(); // získání XML reprezentace podpisu XmlElement xmlSignature = signedXml.GetXml(); // k podpisu přidáme identifikátor, tak jak doporučuje standard ISDOC xmlSignature.SetAttribute("Id", "Signature-" + (signatures + 1)); // XML dokument pro podepsaný výsledek XmlDocument result = new XmlDocument(); // bílé znaky musíme zachovat, jinak se špatně spočte hash result.PreserveWhitespace = true; // načtení původního dokumentu result.AppendChild(result.ImportNode(strippedDoc.DocumentElement, true)); // připojení podpisu na konec dokumentu XML result.DocumentElement.AppendChild(result.ImportNode(xmlSignature, true)); return result; }
// Sign an XML file and save the signature in a new file. public static void SignXmlFile(string FileName, string SignedFileName, RSA Key, string[] ElementsToSign) { // Check the arguments. if (FileName == null) { throw new ArgumentNullException("FileName"); } if (SignedFileName == null) { throw new ArgumentNullException("SignedFileName"); } if (Key == null) { throw new ArgumentNullException("Key"); } if (ElementsToSign == null) { throw new ArgumentNullException("ElementsToSign"); } // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it's name. doc.Load(new XmlTextReader(FileName)); // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document. signedXml.SigningKey = Key; // Loop through each passed element to sign // and create a reference. foreach (string s in ElementsToSign) { // Create a reference to be signed. Reference reference = new Reference(); reference.Uri = s; // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); } // Add an RSAKeyValue KeyInfo (optional; helps recipient find key to validate). KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue((RSA)Key)); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // Append the element to the XML document. doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); if (doc.FirstChild is XmlDeclaration) { doc.RemoveChild(doc.FirstChild); } // Save the signed XML document to a file specified // using the passed string. XmlTextWriter xmltw = new XmlTextWriter(SignedFileName, new UTF8Encoding(false)); doc.WriteTo(xmltw); xmltw.Close(); }
public static string Sign(string xml, X509Certificate2 certificate) { if (xml == null) throw new ArgumentNullException("xml"); if (certificate == null) throw new ArgumentNullException("certificate"); if (!certificate.HasPrivateKey) throw new ArgumentException("certificate", "Certificate should have a private key"); XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; doc.LoadXml(xml); SignedXml signedXml = new SignedXml(doc); signedXml.SigningKey = certificate.PrivateKey; // Attach certificate KeyInfo KeyInfoX509Data keyInfoData = new KeyInfoX509Data(certificate); KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(keyInfoData); signedXml.KeyInfo = keyInfo; // Attach transforms var reference = new Reference(""); reference.AddTransform(new XmlDsigEnvelopedSignatureTransform(includeComments: false)); reference.AddTransform(new XmlDsigExcC14NTransform(includeComments: false)); signedXml.AddReference(reference); // Compute signature signedXml.ComputeSignature(); var signatureElement = signedXml.GetXml(); // Add signature to bundle doc.DocumentElement.AppendChild(doc.ImportNode(signatureElement, true)); return doc.OuterXml; }
public string AssinaXML(string aXML, string pUri, string URI, string serialCertificado) { // open the XML file //StreamReader SR = File.OpenText(pArqXMLAssinar); String vXMLString = aXML; //SR.Close(); // return parameters this.vResultado = 0; this.vResultadoString = "Assinatura realizada com sucesso"; this.vXMLStringAssinado = String.Empty; try { // checking if there is a certified used on xml sign string _xnome = ""; bool vRetorna; X509Certificate2 _X509Cert = CertificadoDigital.ObtemCertificadoDigital(serialCertificado); if (_X509Cert == null) { vRetorna = false; } else { string x; x = _X509Cert.GetKeyAlgorithm().ToString(); // Create a new XML document. XmlDocument doc = new XmlDocument(); // Format the document to ignore white spaces. doc.PreserveWhitespace = false; // Load the passed XML file using it’s name. try { doc.LoadXml(vXMLString); // cheching the elemento will be sign int qtdeRefUri = doc.GetElementsByTagName(pUri).Count; if (qtdeRefUri == 0) { this.vResultado = 4; this.vResultadoString = "A tag de assinatura " + pUri.Trim() + " não existe"; } else { if (qtdeRefUri > 1) { this.vResultado = 5; this.vResultadoString = "A tag de assinatura " + pUri.Trim() + " não é unica"; } else { try { // Create a SignedXml object. SignedXml signedXml = new SignedXml(doc); // Add the key to the SignedXml document signedXml.SigningKey = _X509Cert.PrivateKey; // Create a reference to be signed Reference reference = new Reference(); reference.Uri = URI; /*if (pUri.Trim() != "") * { * XmlAttributeCollection _Uri = doc.GetElementsByTagName(pUri).Item(0).Attributes; * * foreach (XmlAttribute _atributo in _Uri) * { * if (_atributo.Name == "Id") * reference.Uri = "#" + _atributo.InnerText; * } * } * else * { * reference.Uri = ""; * }*/ // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(env); XmlDsigC14NTransform c14 = new XmlDsigC14NTransform(); reference.AddTransform(c14); // Add the reference to the SignedXml object. signedXml.AddReference(reference); // Create a new KeyInfo object KeyInfo keyInfo = new KeyInfo(); // Load the certificate into a KeyInfoX509Data object // and add it to the KeyInfo object. keyInfo.AddClause(new KeyInfoX509Data(_X509Cert)); // Add the KeyInfo object to the SignedXml object. signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // save element on XML doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, true)); XmlDocument XMLDoc = new XmlDocument(); XMLDoc.PreserveWhitespace = false; XMLDoc = doc; // XML document already signed vXMLStringAssinado = XMLDoc.OuterXml; } catch (Exception caught) { this.vResultado = 6; this.vResultadoString = "Erro ao assinar o documento - " + caught.Message; } } } } catch (Exception caught) { this.vResultado = 3; this.vResultadoString = "XML mal formado - " + caught.Message; } } } catch (Exception caught) { this.vResultado = 1; this.vResultadoString = "Problema ao acessar o certificado digital" + caught.Message; } return(vXMLStringAssinado); }