public XmlElement SignInformationCardXML(XmlDocument doc, X509Certificate2 cert) { SignedXml signed = new SignedXml(); signed.SigningKey = cert.PrivateKey; signed.Signature.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; Reference reference = new Reference(); reference.Uri = "#_Object_InfoCard"; reference.AddTransform( new XmlDsigExcC14NTransform()); signed.AddReference(reference); KeyInfo info = new KeyInfo(); KeyInfoX509Data certData = new KeyInfoX509Data(cert, X509IncludeOption.WholeChain); info.AddClause(certData); signed.KeyInfo = info; DataObject cardData = new DataObject("_Object_InfoCard", null, null, doc.DocumentElement); signed.AddObject(cardData); signed.ComputeSignature(); XmlElement e = signed.GetXml(); return(e); }
/// <summary> /// Signiert ein Xml-Document. /// </summary> /// <param name="xDoc">Das Dokument welches die Daten enthält die signiert werden sollen.</param> /// <param name="privateKey">Der private Schlüssel.</param> /// <returns>Gibt ein Xml Element mit den Signierten daten zurück.</returns> public static XmlElement SignXmlDocument(XmlDocument xDoc, string privateKey) { var signedXml = new SignedXml(); System.Security.Cryptography.RSA pvk = System.Security.Cryptography.RSA.Create(); pvk.FromXmlString(privateKey); signedXml.SigningKey = pvk; var dataObject = new DataObject(); dataObject.Id = "content"; dataObject.Data = xDoc.ChildNodes; signedXml.AddObject(dataObject); var reference = new Reference(); reference.Uri = "#content"; signedXml.AddReference(reference); var keyinfo = new KeyInfo(); keyinfo.AddClause(new RSAKeyValue(pvk)); signedXml.KeyInfo = keyinfo; signedXml.ComputeSignature(); return(signedXml.GetXml()); }
public string Sign(string xmlDocument, RSA rsaKey) { CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"); var xml = new XmlDocument { PreserveWhitespace = true }; xml.LoadXml(xmlDocument); if (xml.DocumentElement == null) { throw new CryptographicException($"The xml you are trying to Sign is invalid. \n {xmlDocument}"); } var signedXml = new SignedXml(xml) { SigningKey = rsaKey }; //signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; var dataObject = new DataObject(Guid.NewGuid().ToString(), "", "", xml.DocumentElement); signedXml.AddObject(dataObject); var x509Data = new KeyInfoX509Data(); var x509Certificate2 = new X509Certificate2("NPPAutomationClient.pem"); if (x509Certificate2.SerialNumber == null) { throw new CryptographicException("The X509Certificate you are trying to use is invalid. The Serial number is null."); } var keyInfo = new KeyInfo(); var keyInfoX509Data = new KeyInfoX509Data(); keyInfoX509Data.AddIssuerSerial(x509Certificate2.Issuer, x509Certificate2.SerialNumber); keyInfoX509Data.AddCertificate(x509Certificate2); keyInfo.AddClause(keyInfoX509Data); keyInfo.LoadXml(x509Data.GetXml()); var reference = new Reference { Uri = $"#{dataObject.Id}", DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256" }; var env = new XmlDsigC14NTransform(); reference.AddTransform(env); signedXml.AddReference(reference); signedXml.ComputeSignature(); var xmlDigitalSignature = signedXml.GetXml(); //xml.DocumentElement?.AppendChild(xml.ImportNode(xmlDigitalSignature, true)); return(xml.ImportNode(xmlDigitalSignature, true).OuterXml); }
internal override XmlDocument SignXml(XmlDocument xmlDoc, Pkcs12Store keyStore, string keyStorePasswort, string signaturAlgorithmus) { System.Security.Cryptography.X509Certificates.X509Certificate2 cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(CertHelper.ConvertPkcs12ToByteArray(keyStore, keyStorePasswort), keyStorePasswort); SignedXml signedXml = new SignedXml(xmlDoc); signedXml.SigningKey = cert.PrivateKey; KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data keyInfoData = new KeyInfoX509Data(cert); keyInfo.AddClause(keyInfoData); signedXml.KeyInfo = keyInfo; // the DataObject has to point to a XmlNodeList DataObject dataObject = new DataObject(); dataObject.Id = "MyObjectID1"; dataObject.Data = new CustomXmlNodeList(new[] { xmlDoc.DocumentElement }); signedXml.AddObject(dataObject); // Add the reference to the SignedXml object. Reference reference = new Reference(); reference.Uri = "#MyObjectID1"; signedXml.AddReference(reference); // Create a reference to be signed. if (c14) { XmlDsigC14NTransform env = new XmlDsigC14NTransform(); reference.AddTransform(env); } // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); // create detached envelope XmlDocument envelope = new XmlDocument(); envelope.AppendChild(envelope.CreateElement("Envelope")); envelope.DocumentElement.AppendChild( envelope.ImportNode(xmlDigitalSignature, true)); return(envelope); }
private void OpprettReferanser(SignedXml signaturnode, IEnumerable <IAsiceAttachable> referanser) { foreach (var item in referanser) { signaturnode.AddReference(Sha256Referanse(item)); } signaturnode.AddObject( new QualifyingPropertiesObject( _sertifikat, "#Signature", referanser.ToArray(), _xml.DocumentElement) ); signaturnode.AddReference(SignedPropertiesReferanse()); }
private void AddReferences() { foreach (var item in Attachables) { _signatureNode.AddReference(Sha256Reference(item)); } _signatureNode.AddObject( new QualifyingPropertiesObject( Certificate, "#Signature", Attachables, _xml.DocumentElement ) ); _signatureNode.AddReference(SignedPropertiesReference()); }
public static string SignXMLX509Data(string strXML) { string strResult = ""; try { SignedXml signedXml = new SignedXml(); // Get the signature key. For this demo, we look for keys associated with a certificate in the "MY" store RSACryptoServiceProvider rsa = null; X509Certificate x509Cert = null; GetSignatureKey(out rsa, out x509Cert); if (rsa == null) { return(""); } signedXml.SigningKey = rsa; Reference reference = new Reference(); reference.Uri = "#object-1"; reference.Type = "http://www.w3.org/2000/09/xmldsig#Object"; // Add an object System.Security.Cryptography.Xml.DataObject obj = new System.Security.Cryptography.Xml.DataObject(); XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; doc.LoadXml(strXML); obj.Data = doc.ChildNodes; obj.Id = "object-1"; signedXml.AddObject(obj); signedXml.AddReference(reference); KeyInfo keyInfo = new KeyInfo(); // Include the certificate raw data with the signed file keyInfo.AddClause(new KeyInfoX509Data(x509Cert)); signedXml.KeyInfo = keyInfo; // compute the signature signedXml.ComputeSignature(); strResult = signedXml.GetXml().OuterXml; } catch (Exception exc) { MessageBox.Show(exc.ToString(), Messages.ExceptionTitle, MessageBoxButtons.OK, MessageBoxIcon.Stop); return(strResult); } return(strResult); }
static void Main(String[] args) { // Create example data to sign. XmlDocument document = new XmlDocument(); XmlNode node = document.CreateNode(XmlNodeType.Element, "", "MyElement", "samples"); node.InnerText = "This is some text"; document.AppendChild(node); Console.Error.WriteLine("Data to sign:\n" + document.OuterXml + "\n"); // Create the SignedXml message. SignedXml signedXml = new SignedXml(); RSA key = RSA.Create(); signedXml.SigningKey = key; // Create a data object to hold the data to sign. DataObject dataObject = new DataObject(); dataObject.Data = document.ChildNodes; dataObject.Id = "MyObjectId"; // Add the data object to the signature. signedXml.AddObject(dataObject); // Create a reference to be able to package everything into the // message. Reference reference = new Reference(); reference.Uri = "#MyObjectId"; // Add it to the message. signedXml.AddReference(reference); // Add a KeyInfo. KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new RSAKeyValue(key)); signedXml.KeyInfo = keyInfo; // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature. XmlElement xmlSignature = signedXml.GetXml(); Console.WriteLine(xmlSignature.OuterXml); }
public static void SignXmlDocument(Stream sourceXmlFile, Stream destinationXmlFile, X509Certificate2 certificate) { // Carico il documento XML XmlDocument doc = new XmlDocument(); doc.Load(sourceXmlFile); // Preparo un DOMDocument che conterrà il risultato XmlDocument outputDocument = new XmlDocument(); // Recupero un riferimento all'intero contenuto del documento XML XmlNodeList elementsToSign = doc.SelectNodes(String.Format("/{0}", doc.DocumentElement.Name)); // Costruisco la firma SignedXml signedXml = new SignedXml(); System.Security.Cryptography.Xml.DataObject dataSignature = new System.Security.Cryptography.Xml.DataObject { Data = elementsToSign, Id = doc.DocumentElement.Name }; signedXml.AddObject(dataSignature); Reference reference = new Reference { Uri = String.Format("#{0}", dataSignature.Id) }; signedXml.AddReference(reference); if ((certificate != null) && (certificate.HasPrivateKey)) { signedXml.SigningKey = certificate.PrivateKey; KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certificate)); signedXml.KeyInfo = keyInfo; signedXml.ComputeSignature(); // Aggiungo la firma al nuovo documento di output outputDocument.AppendChild( outputDocument.ImportNode(signedXml.GetXml(), true)); outputDocument.Save(destinationXmlFile); } }
/// <summary> /// Signs the given <paramref name="openXmlPackage"/>, using the given /// <paramref name="certificate"/>. /// </summary> /// <param name="openXmlPackage">The <see cref="OpenXmlPackage"/>.</param> /// <param name="certificate">The <see cref="X509Certificate2"/>.</param> public static void Sign(OpenXmlPackage openXmlPackage, X509Certificate2 certificate) { if (openXmlPackage == null) { throw new ArgumentNullException(nameof(openXmlPackage)); } if (certificate == null) { throw new ArgumentNullException(nameof(certificate)); } RSA privateKey = certificate.GetRSAPrivateKey(); using SHA256 hashAlgorithm = SHA256.Create(); // Create KeyInfo. var keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data(certificate)); // Create a Signature XmlElement. var signedXml = new SignedXml { SigningKey = privateKey, KeyInfo = keyInfo }; signedXml.Signature.Id = Constants.PackageSignatureId; signedXml.SignedInfo.SignatureMethod = Constants.SignatureMethod; signedXml.AddReference(CreatePackageObjectReference()); signedXml.AddObject(CreatePackageObject(openXmlPackage.Package, hashAlgorithm)); signedXml.ComputeSignature(); XmlElement signature = signedXml.GetXml(); // Get or create the DigitalSignatureOriginPart. DigitalSignatureOriginPart dsOriginPart = openXmlPackage.GetPartsOfType <DigitalSignatureOriginPart>().FirstOrDefault() ?? openXmlPackage.AddNewPart <DigitalSignatureOriginPart>(); var xmlSignaturePart = dsOriginPart.AddNewPart <XmlSignaturePart>(); // Write the Signature XmlElement to the XmlSignaturePart. using Stream stream = xmlSignaturePart.GetStream(FileMode.Create, FileAccess.Write); using XmlWriter writer = XmlWriter.Create(stream); signature.WriteTo(writer); }
//public static byte[] SignBodyParameter(XmlDocument doc, RSA key) //{ // var responseXml = doc.GetElementsByTagName("xml")[0]; // var docForSign = new XmlDocument(); // docForSign.LoadXml(responseXml.InnerText); // if (docForSign.FirstChild.Name == "xml") // docForSign.RemoveChild(docForSign.FirstChild); // var signedXml = new SignedXml // { // SigningKey = key // }; // var objectID = docForSign.FirstChild.Name; // var dataObject = new DataObject // { // Data = docForSign.ChildNodes, // Id = objectID // }; // signedXml.AddObject(dataObject); // signedXml.AddReference(new Reference($"#{objectID}")); // signedXml.ComputeSignature(); // //var realXml = signedXml.GetXml().OuterXml; // //var el = new XElement("Root", realXml); // //responseXml.InnerXml = el.LastNode.ToString(); // //responseXml.InnerXml = System.Web.HttpUtility.HtmlEncode(signedXml.GetXml().OuterXml); // var s = System.Security.SecurityElement.Escape(signedXml.GetXml().OuterXml); // responseXml.InnerText = System.Security.SecurityElement.Escape(signedXml.GetXml().OuterXml); // //new XmlElement() // //responseXml.InnerXml = signedXml.GetXml().OuterXml.Replace("&", "&").Replace("<", "<").Replace(">", ">").Replace(""", """).Replace("'", "'"); // return signedXml.SignatureValue; //} public static (string signedEnvelope, byte[] signature) SignBodyParameter(string envelope, RSA key) { var doc = new XmlDocument(); doc.LoadXml(envelope); var responseXml = doc.GetElementsByTagName("xml")[0]; var docForSign = new XmlDocument(); docForSign.LoadXml(responseXml.InnerText); if (docForSign.FirstChild.Name == "xml") { docForSign.RemoveChild(docForSign.FirstChild); } var signedXml = new SignedXml { SigningKey = key }; var objectID = docForSign.FirstChild.Name; var dataObject = new DataObject { Data = docForSign.ChildNodes, Id = objectID }; signedXml.AddObject(dataObject); signedXml.AddReference(new Reference($"#{objectID}")); signedXml.ComputeSignature(); var securityElement = SecurityElement.FromString(envelope); var k = securityElement.SearchForChildByTag("s:Body").SearchForChildByTag("RegisterResponse").SearchForChildByTag("xml"); k.Text = SecurityElement.Escape(signedXml.GetXml().OuterXml); return(securityElement.ToString(), signedXml.SignatureValue); }
public void SaveCard(InformationCard card, X509Certificate2 cert, string filename) { XmlDocument doc = CreateInformationCardXML(card); SignedXml signed = new SignedXml(); signed.SigningKey = cert.PrivateKey; signed.Signature.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; Reference reference = new Reference(); reference.Uri = "#_Object_InfoCard"; reference.AddTransform( new XmlDsigExcC14NTransform()); signed.AddReference(reference); KeyInfo info = new KeyInfo(); KeyInfoX509Data certData = new KeyInfoX509Data(cert, X509IncludeOption.WholeChain); info.AddClause(certData); signed.KeyInfo = info; DataObject cardData = new DataObject("_Object_InfoCard", null, null, doc.DocumentElement); signed.AddObject(cardData); signed.ComputeSignature(); XmlElement e = signed.GetXml(); XmlTextWriter fileWriter = new XmlTextWriter(filename, Encoding.UTF8); e.WriteTo(fileWriter); //doc.WriteTo(fileWriter); //Added fileWriter.Flush(); fileWriter.Close(); }
protected override void CreateAndAddReferenceTo(SignedXml signedXml, XmlDocument document, string inputPath, string xpathToNodeToSign) { if (signedXml == null) { throw new InvalidParameterException("Signed Xml cannot be null"); } if (document == null) { throw new InvalidParameterException("Xml document cannot be null"); } if (document.DocumentElement == null) { throw new InvalidParameterException("Xml document must have root element"); } var signatureReference = new Reference("#documentdata"); signatureReference.AddTransform(new XmlDsigExcC14NTransform()); signedXml.AddReference(signatureReference); var dataObject = new DataObject("documentdata", "", "", document.DocumentElement); signedXml.AddObject(dataObject); }
public void SerializeAndSign(string filename, X509Certificate2 cert) { MemoryStream stream = new MemoryStream(); XmlWriter writer = XmlWriter.Create(stream); writer.WriteStartElement(XmlNames.WSIdentity.InfoCardElement, XmlNames.WSIdentity.Namespace); // // write the InformationCardReference element // writer.WriteAttributeString(XmlNames.Xml.Language, XmlNames.Xml.Namespace, m_language); writer.WriteStartElement(XmlNames.WSIdentity.InfoCardRefElement, XmlNames.WSIdentity.Namespace); writer.WriteElementString(XmlNames.WSIdentity.CardIdElement, XmlNames.WSIdentity.Namespace, m_cardId); writer.WriteElementString(XmlNames.WSIdentity.CardVersionElement, XmlNames.WSIdentity.Namespace, m_cardVersion); writer.WriteEndElement(); // // card name // if (!String.IsNullOrEmpty(m_cardName)) { writer.WriteStartElement(XmlNames.WSIdentity.CardNameElement, XmlNames.WSIdentity.Namespace); writer.WriteString(m_cardName); writer.WriteEndElement(); } // // card image // if (null != m_logo && 0 != m_logo.Length) { writer.WriteStartElement(XmlNames.WSIdentity.CardImageElement, XmlNames.WSIdentity.Namespace); if (!String.IsNullOrEmpty(m_mimeType)) { writer.WriteAttributeString(XmlNames.WSIdentity.MimeTypeAttribute, m_mimeType); } string val = Convert.ToBase64String(m_logo); writer.WriteString(val); writer.WriteEndElement(); } // // card issuer uri // writer.WriteStartElement(XmlNames.WSIdentity.IssuerElement, XmlNames.WSIdentity.Namespace); writer.WriteString(m_issuerId); writer.WriteEndElement(); // // issue time // writer.WriteStartElement(XmlNames.WSIdentity.TimeIssuedElement, XmlNames.WSIdentity.Namespace); writer.WriteString(XmlConvert.ToString(m_issuedOn, XmlDateTimeSerializationMode.Utc)); writer.WriteEndElement(); // // expiry time // writer.WriteStartElement(XmlNames.WSIdentity.TimeExpiresElement, XmlNames.WSIdentity.Namespace); writer.WriteString(XmlConvert.ToString(m_expiresOn, XmlDateTimeSerializationMode.Utc)); writer.WriteEndElement(); // // Start the tokenservice list // writer.WriteStartElement(XmlNames.WSIdentity.TokenServiceListElement, XmlNames.WSIdentity.Namespace); EndpointAddressBuilder eprBuilder = new EndpointAddressBuilder(); eprBuilder.Uri = new Uri(m_issuerId); eprBuilder.Identity = new X509CertificateEndpointIdentity(cert); if (null != m_mexUri) { MetadataReference mexRef = new MetadataReference(); mexRef.Address = new EndpointAddress(m_mexUri); mexRef.AddressVersion = AddressingVersion.WSAddressing10; MetadataSection mexSection = new MetadataSection(); mexSection.Metadata = mexRef; MetadataSet mexSet = new MetadataSet(); mexSet.MetadataSections.Add(mexSection); MemoryStream memStream = new MemoryStream(); XmlTextWriter writer1 = new XmlTextWriter(memStream, System.Text.Encoding.UTF8); mexSet.WriteTo(writer1); writer1.Flush(); memStream.Seek(0, SeekOrigin.Begin); XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memStream, XmlDictionaryReaderQuotas.Max); eprBuilder.SetMetadataReader(reader); } m_epr = eprBuilder.ToEndpointAddress(); writer.WriteStartElement(XmlNames.WSIdentity.TokenServiceElement, XmlNames.WSIdentity.Namespace); // // Write the EndPointReference // m_epr.WriteTo(AddressingVersion.WSAddressing10, writer); // // Write the UserCredential Element // writer.WriteStartElement(XmlNames.WSIdentity.UserCredentialElement, XmlNames.WSIdentity.Namespace); // // Write the hint // if (!String.IsNullOrEmpty(m_hint)) { writer.WriteStartElement(XmlNames.WSIdentity.DisplayCredentialHintElement, XmlNames.WSIdentity.Namespace); writer.WriteString(m_hint); writer.WriteEndElement(); } switch (m_cardType) { case DefaultValues.CardType.UserNamePassword: writer.WriteStartElement(XmlNames.WSIdentity.UserNamePasswordCredentialElement, XmlNames.WSIdentity.Namespace); if (!string.IsNullOrEmpty(m_credentialIdentifier)) { writer.WriteStartElement(XmlNames.WSIdentity.UserNameElement, XmlNames.WSIdentity.Namespace); writer.WriteString(m_credentialIdentifier); writer.WriteEndElement(); } writer.WriteEndElement(); break; case DefaultValues.CardType.KerberosAuth: writer.WriteStartElement(XmlNames.WSIdentity.KerberosV5CredentialElement, XmlNames.WSIdentity.Namespace); writer.WriteEndElement(); break; case DefaultValues.CardType.SelfIssuedAuth: writer.WriteStartElement(XmlNames.WSIdentity.SelfIssuedCredentialElement, XmlNames.WSIdentity.Namespace); if (!string.IsNullOrEmpty(m_credentialIdentifier)) { writer.WriteStartElement(XmlNames.WSIdentity.PrivatePersonalIdentifierElement, XmlNames.WSIdentity.Namespace); writer.WriteString(m_credentialIdentifier); writer.WriteEndElement(); } else { throw new InvalidDataException("No PPID was specified"); } writer.WriteEndElement(); break; case DefaultValues.CardType.SmartCard: writer.WriteStartElement(XmlNames.WSIdentity.X509V3CredentialElement, XmlNames.WSIdentity.Namespace); writer.WriteStartElement(XmlNames.XmlDSig.X509DataElement, XmlNames.XmlDSig.Namespace); if (!string.IsNullOrEmpty(m_credentialIdentifier)) { writer.WriteStartElement(XmlNames.WSSecurityExt.KeyIdentifierElement, XmlNames.WSSecurityExt.Namespace); writer.WriteAttributeString(XmlNames.WSSecurityExt.ValueTypeAttribute, null, XmlNames.WSSecurityExt.Sha1ThumbrpintKeyTypeValue); writer.WriteString(m_credentialIdentifier); writer.WriteEndElement(); } else { throw new InvalidDataException("No thumbprint was specified"); } writer.WriteEndElement(); writer.WriteEndElement(); break; default: break; } writer.WriteEndElement(); //end of user credential writer.WriteEndElement(); // end of tokenservice writer.WriteEndElement(); //end of tokenservice list // // tokentypes // writer.WriteStartElement(XmlNames.WSIdentity.SupportedTokenTypeListElement, XmlNames.WSIdentity.Namespace); foreach (string type in m_tokenTypes) { writer.WriteElementString(XmlNames.WSTrust.TokenType, XmlNames.WSTrust.Namespace, type); } writer.WriteEndElement(); // // claims // writer.WriteStartElement(XmlNames.WSIdentity.SupportedClaimTypeListElement, XmlNames.WSIdentity.Namespace); foreach (ClaimInfo clm in m_supportedClaims) { writer.WriteStartElement(XmlNames.WSIdentity.SupportedClaimTypeElement, XmlNames.WSIdentity.Namespace); writer.WriteAttributeString(XmlNames.WSIdentity.UriAttribute, clm.Id); if (!String.IsNullOrEmpty(clm.DisplayTag)) { writer.WriteElementString(XmlNames.WSIdentity.DisplayTagElement, XmlNames.WSIdentity.Namespace, clm.DisplayTag); } if (!String.IsNullOrEmpty(clm.Description)) { writer.WriteElementString(XmlNames.WSIdentity.DescriptionElement, XmlNames.WSIdentity.Namespace, clm.Description); } writer.WriteEndElement(); } writer.WriteEndElement(); // // RequireAppliesTo // if (m_requireAppliesTo) { writer.WriteElementString(XmlNames.WSIdentity.RequireAppliesToElement, XmlNames.WSIdentity.Namespace, null); } // // Privacy Notice // if (!String.IsNullOrEmpty(m_privacyNoticeAt)) { writer.WriteStartElement(XmlNames.WSIdentity.PrivacyNoticeAtElement, XmlNames.WSIdentity.Namespace); writer.WriteString(m_privacyNoticeAt); writer.WriteEndElement(); } writer.WriteEndElement(); writer.Close(); // // Sign the xml content // stream.Position = 0; XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = false; doc.Load(stream); SignedXml signed = new SignedXml(); signed.SigningKey = cert.PrivateKey; signed.Signature.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; Reference reference = new Reference(); reference.Uri = "#_Object_InfoCard"; reference.AddTransform( new XmlDsigExcC14NTransform()); signed.AddReference(reference); KeyInfo info = new KeyInfo(); KeyInfoX509Data data = new KeyInfoX509Data(cert, X509IncludeOption.WholeChain); info.AddClause(data); signed.KeyInfo = info; DataObject cardData = new DataObject("_Object_InfoCard", null, null, doc.DocumentElement); signed.AddObject(cardData); signed.ComputeSignature(); XmlElement e = signed.GetXml(); XmlTextWriter fileWriter = new XmlTextWriter(filename, Encoding.UTF8); e.WriteTo(fileWriter); fileWriter.Flush(); fileWriter.Close(); }
public static void SaveCard(InformationCard card, X509Certificate2 cert, string filename) { MemoryStream stream = new MemoryStream(); XmlWriter writer = XmlWriter.Create(stream); writer.WriteStartElement("InformationCard", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteAttributeString("lang", "http://www.w3.org/XML/1998/namespace", "en-US"); writer.WriteStartElement("InformationCardReference", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteElementString("CardId", "http://schemas.xmlsoap.org/ws/2005/05/identity", card.CardReference.CardID); writer.WriteElementString("CardVersion", "http://schemas.xmlsoap.org/ws/2005/05/identity", card.CardReference.CardVersion.ToString()); writer.WriteEndElement(); if (card.CardName != null && card.CardName.Length > 0) { writer.WriteStartElement("CardName", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(card.CardName); writer.WriteEndElement(); } if (card.CardImage != null && card.CardImage.ImageName.Length > 0) { writer.WriteStartElement("CardImage", "http://schemas.xmlsoap.org/ws/2005/05/identity"); if (card.CardImage != null && card.CardImage.ImageMimeType != null && card.CardImage.ImageMimeType.Length > 0) { writer.WriteAttributeString("MimeType", card.CardImage.ImageMimeType); } FileInfo cardImage = new FileInfo(card.CardImage.ImageName); if (cardImage.Exists) { byte[] cardImageBytes = new byte[cardImage.Length]; using (FileStream imageFS = cardImage.OpenRead()) { imageFS.Read(cardImageBytes, 0, cardImageBytes.Length); } string imageBase64 = Convert.ToBase64String(cardImageBytes); writer.WriteString(imageBase64); writer.WriteEndElement(); } } writer.WriteStartElement("Issuer", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(card.Issuer); writer.WriteEndElement(); //writer.WriteStartElement("IssuerName", "http://schemas.xmlsoap.org/ws/2005/05/identity"); //writer.WriteString(card.IssuerName); //writer.WriteEndElement(); writer.WriteStartElement("TimeIssued", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(XmlConvert.ToString(card.TimeIssued, XmlDateTimeSerializationMode.Utc)); writer.WriteEndElement(); writer.WriteStartElement("TimeExpires", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(XmlConvert.ToString(card.TimeExpires, XmlDateTimeSerializationMode.Utc)); writer.WriteEndElement(); writer.WriteStartElement("TokenServiceList", "http://schemas.xmlsoap.org/ws/2005/05/identity"); foreach (TokenService ts in card.TokenServiceList) { EndpointAddressBuilder endpointBuilder = new EndpointAddressBuilder(); endpointBuilder.Uri = new Uri(ts.EndpointReference.Address); endpointBuilder.Identity = new X509CertificateEndpointIdentity(RetrieveCertificate(ts.EndpointReference.Identity)); if (null != ts.EndpointReference.Mex) { MetadataReference mexReference = new MetadataReference(); mexReference.Address = new EndpointAddress(ts.EndpointReference.Mex); mexReference.AddressVersion = AddressingVersion.WSAddressing10; MetadataSection mexSection = new MetadataSection(); mexSection.Metadata = mexReference; MetadataSet mexSet = new MetadataSet(); mexSet.MetadataSections.Add(mexSection); MemoryStream mexMemoryStream = new MemoryStream(); XmlTextWriter mexWriter = new XmlTextWriter(mexMemoryStream, System.Text.Encoding.UTF8); mexSet.WriteTo(mexWriter); mexWriter.Flush(); mexMemoryStream.Seek(0, SeekOrigin.Begin); XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(mexMemoryStream, XmlDictionaryReaderQuotas.Max); endpointBuilder.SetMetadataReader(reader); writer.WriteStartElement("TokenService", "http://schemas.xmlsoap.org/ws/2005/05/identity"); EndpointAddress endpoint = endpointBuilder.ToEndpointAddress(); endpoint.WriteTo(AddressingVersion.WSAddressing10, writer); writer.WriteStartElement("UserCredential", "http://schemas.xmlsoap.org/ws/2005/05/identity"); if (ts.UserCredential.DisplayCredentialHint != null && ts.UserCredential.DisplayCredentialHint.Length > 0) { writer.WriteStartElement("DisplayCredentialHint", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(ts.UserCredential.DisplayCredentialHint); writer.WriteEndElement(); } switch (ts.UserCredential.UserCredentialType) { case CredentialType.UsernameAndPassword: writer.WriteStartElement("UsernamePasswordCredential", "http://schemas.xmlsoap.org/ws/2005/05/identity"); if (!string.IsNullOrEmpty(ts.UserCredential.Value)) { writer.WriteStartElement("Username", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(ts.UserCredential.Value); writer.WriteEndElement(); } writer.WriteEndElement(); break; case CredentialType.Kerberos: writer.WriteStartElement("KerberosV5Credential", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteEndElement(); break; case CredentialType.SmartCard: writer.WriteStartElement("X509V3Credential", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteStartElement("X509Data", "http://www.w3.org/2000/09/xmldsig#"); if (!string.IsNullOrEmpty(ts.UserCredential.Value)) { writer.WriteStartElement("KeyIdentifier", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); writer.WriteAttributeString("ValueType", null, "http://docs.oasis-open.org/wss/2004/xx/oasis-2004xx-wss-soap-message-security-1.1#ThumbprintSHA1"); writer.WriteString(RetrieveCertificate(ts.UserCredential.Value).Thumbprint); writer.WriteEndElement(); } else { throw new InvalidDataException("No thumbprint was specified"); } writer.WriteEndElement(); writer.WriteEndElement(); break; default: break; } writer.WriteEndElement(); writer.WriteEndElement(); } } writer.WriteEndElement(); //end of tokenservice list // // tokentypes // writer.WriteStartElement("SupportedTokenTypeList", "http://schemas.xmlsoap.org/ws/2005/05/identity"); foreach (TokenType tokenType in card.AcceptedTokenTypes) { writer.WriteElementString("TokenType", "http://schemas.xmlsoap.org/ws/2005/02/trust", tokenType.Uri); } writer.WriteEndElement(); // // claims // writer.WriteStartElement("SupportedClaimTypeList", "http://schemas.xmlsoap.org/ws/2005/05/identity"); foreach (CardClaim claim in card.SupportedClaimTypeList) { writer.WriteStartElement("SupportedClaimType", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteAttributeString("Uri", claim.Uri); if (!String.IsNullOrEmpty(claim.DisplayTag)) { writer.WriteElementString("DisplayTag", "http://schemas.xmlsoap.org/ws/2005/05/identity", claim.DisplayTag); } if (!String.IsNullOrEmpty(claim.Description)) { writer.WriteElementString("Description", "http://schemas.xmlsoap.org/ws/2005/05/identity", claim.Description); } writer.WriteEndElement(); } writer.WriteEndElement(); if (card.RequireRPIdentification) { writer.WriteElementString("RequireAppliesTo", "http://schemas.xmlsoap.org/ws/2005/05/identity", card.RequireRPIdentification.ToString()); } if (!String.IsNullOrEmpty(card.PrivacyNotice)) { writer.WriteStartElement("PrivacyNotice", "http://schemas.xmlsoap.org/ws/2005/05/identity"); writer.WriteString(card.PrivacyNotice); writer.WriteEndElement(); } writer.WriteEndElement(); writer.Close(); stream.Position = 0; XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = false; doc.Load(stream); SignedXml signed = new SignedXml(); signed.SigningKey = cert.PrivateKey; signed.Signature.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; Reference reference = new Reference(); reference.Uri = "#_Object_InfoCard"; reference.AddTransform( new XmlDsigExcC14NTransform()); signed.AddReference(reference); KeyInfo info = new KeyInfo(); KeyInfoX509Data certData = new KeyInfoX509Data(cert, X509IncludeOption.WholeChain); info.AddClause(certData); signed.KeyInfo = info; DataObject cardData = new DataObject("_Object_InfoCard", null, null, doc.DocumentElement); signed.AddObject(cardData); signed.ComputeSignature(); XmlElement e = signed.GetXml(); XmlTextWriter fileWriter = new XmlTextWriter(filename, Encoding.UTF8); e.WriteTo(fileWriter); //doc.WriteTo(fileWriter); //Added fileWriter.Flush(); fileWriter.Close(); }
/// <summary> /// Signs a XML file (enveloping signature) using a digital certificate /// </summary> /// <param name="encodingPath">Used for non-xml, the root path of the document being signed, used for temporary encoding file</param> /// <param name="signatureType">This will be XML or Non-XML</param> /// <param name="xml">The XML data to sign represented as byte array</param> /// <param name="certFile">The certificate file to use for signing</param> /// <param name="certPassword">The certificate password</param> /// <param name="signWithSha256">Sign the document using SHA-256</param> /// <returns>The signed data represented as byte array</returns> private static byte[] SignEnvelopingXml(XmlSignatureType signatureType, byte[] xml, byte[] certFile, string certPassword, bool signWithSha256, string encodingPath = "") { if (xml == null || xml.Length == 0) { // invalid XML array throw new Exception("Nothing to sign!"); } // load certificate X509Certificate2 certificate = LoadSigningCertificate(certFile, certPassword, signWithSha256); if (!certificate.HasPrivateKey) { // invalid certificate throw new Exception("Specified certificate not suitable for signing!"); } using (MemoryStream stream = new MemoryStream(xml)) { // go to the beginning of the stream stream.Flush(); stream.Position = 0; // create new XmlDocument from stream XmlDocument doc = new XmlDocument() { PreserveWhitespace = true }; doc.Load(stream); // create transform (for canonicalization method & reference) XmlDsigExcC14NTransform transform = new XmlDsigExcC14NTransform(); // create new SignedXml from XmlDocument SignedXml signed = GenerateSignedXml(doc, certificate, signWithSha256); } //If this is NOT XML, then we have to convert it and stick it in XML first if (signatureType == XmlSignatureType.NonXML) { //base64 encode it string strEncodedImage; strEncodedImage = System.Convert.ToBase64String(xml, 0, xml.Length); //create a small xml file and put the encoded Image data inside // Create an XmlWriterSettings object with the correct options. XmlWriter writer = null; XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; settings.IndentChars = ("\t"); settings.OmitXmlDeclaration = false; settings.NewLineHandling = NewLineHandling.Replace; settings.CloseOutput = true; string metadataFileName = encodingPath + "\\TempEncoded.xml"; // Create the XmlWriter object and write some content. writer = XmlWriter.Create(metadataFileName, settings); writer.WriteStartElement("Wrapper", ""); writer.WriteString(strEncodedImage); writer.WriteEndElement(); //Close the XmlTextWriter. writer.WriteEndDocument(); writer.Close(); writer.Flush(); xml = File.ReadAllBytes(encodingPath + "\\TempEncoded.xml"); } using (MemoryStream stream = new MemoryStream(xml)) { // go to the beginning of the stream stream.Flush(); stream.Position = 0; // create new XmlDocument from stream XmlDocument doc = new XmlDocument() { PreserveWhitespace = true }; doc.Load(stream); // create transform (for canonicalization method & reference) XmlDsigExcC14NTransform transform = new XmlDsigExcC14NTransform(); // create new SignedXml from XmlDocument SignedXml signed = GenerateSignedXml(doc, certificate, signWithSha256); signed.SignedInfo.CanonicalizationMethod = transform.Algorithm; // get nodes (use XPath to include FATCA declaration) XmlNodeList nodes = doc.DocumentElement.SelectNodes("/*"); // define data object DataObject dataObject = new DataObject() { Data = nodes, Id = "FATCA" }; // add the data we are signing as a sub-element (object) of the signature element signed.AddObject(dataObject); // create reference Reference reference = new Reference(string.Format("#{0}", dataObject.Id)); reference.AddTransform(transform); if (signWithSha256) { // SHA-256 digest reference.DigestMethod = RSAPKCS1SHA256SignatureDescription.ReferenceDigestMethod; } // add reference to document signed.AddReference(reference); // include KeyInfo object & compute signature signed.KeyInfo = CreateKeyInfoFromCertificate(certificate); signed.ComputeSignature(); // get signature XmlElement xmlDigitalSignature = signed.GetXml(); // XML declaration string xmlDeclaration = string.Empty; if (doc.FirstChild is XmlDeclaration) { // include declaration xmlDeclaration = doc.FirstChild.OuterXml; } // return signature as byte array return(Encoding.UTF8.GetBytes(string.Concat(xmlDeclaration, xmlDigitalSignature.OuterXml))); } }
/////////////////////////////////////////////////////////////////////// /// /// <summary> /// Carry out the Sign command. /// </summary> /// static void DoSignCommand(string title, X509Certificate2 certificate) { Console.WriteLine(); Console.WriteLine("Signing Xml file \"" + fileNames[0] + "\"..."); Console.WriteLine(); // display more details for verbose operation. if (verbose) { DisplayDetail(null, certificate, detached); } SignedXml signedXml = new SignedXml(); ICspAsymmetricAlgorithm csp = (ICspAsymmetricAlgorithm)certificate.PrivateKey; if (csp.CspKeyContainerInfo.RandomlyGenerated) { throw new InternalException("Internal error: This certificate does not have a corresponding private key."); } signedXml.SigningKey = (AsymmetricAlgorithm)csp; Console.WriteLine(signedXml.SigningKey.ToXmlString(false)); if (detached) { Reference reference = new Reference(); reference.Uri = "file://" + Path.GetFullPath((string)fileNames[0]); signedXml.AddReference(reference); } else { Reference reference = new Reference(); reference.Uri = "#object-1"; // Add an object XmlDocument dataObject = new XmlDocument(); dataObject.PreserveWhitespace = true; XmlElement dataElement = (XmlElement)dataObject.CreateElement("DataObject", SignedXml.XmlDsigNamespaceUrl); dataElement.AppendChild(dataObject.CreateTextNode(new UTF8Encoding(false).GetString(ReadFile((string)fileNames[0])))); dataObject.AppendChild(dataElement); DataObject obj = new DataObject(); obj.Data = dataObject.ChildNodes; obj.Id = "object-1"; signedXml.AddObject(obj); signedXml.AddReference(reference); } signedXml.KeyInfo = new KeyInfo(); if (includeOptions.Count == 0) { signedXml.KeyInfo.AddClause(new KeyInfoX509Data(certificate, X509IncludeOption.ExcludeRoot)); } else { KeyInfoX509Data keyInfoX509Data = new KeyInfoX509Data(); foreach (IncludeOptions includeOption in includeOptions) { switch (includeOption) { case IncludeOptions.ExcludeRoot: case IncludeOptions.EndCertOnly: case IncludeOptions.WholeChain: keyInfoX509Data = new KeyInfoX509Data(certificate, (X509IncludeOption)includeOption); break; case IncludeOptions.SubjectName: keyInfoX509Data.AddSubjectName(certificate.SubjectName.Name); break; case IncludeOptions.SKI: X509ExtensionCollection extensions = certificate.Extensions; foreach (X509Extension extension in extensions) { if (extension.Oid.Value == "2.5.29.14") // OID for SKI extension { X509SubjectKeyIdentifierExtension ski = extension as X509SubjectKeyIdentifierExtension; if (ski != null) { keyInfoX509Data.AddSubjectKeyId(ski.SubjectKeyIdentifier); break; } } } break; case IncludeOptions.IssuerSerial: keyInfoX509Data.AddIssuerSerial(certificate.IssuerName.Name, certificate.SerialNumber); break; } signedXml.KeyInfo.AddClause(keyInfoX509Data); } } // compute the signature signedXml.ComputeSignature(); XmlElement xmlDigitalSignature = signedXml.GetXml(); // write it out XmlTextWriter xmltw = new XmlTextWriter((string)fileNames[1], new UTF8Encoding(false)); xmlDigitalSignature.WriteTo(xmltw); xmltw.Close(); Console.WriteLine(); Console.WriteLine("Signature written to file \"" + fileNames[1] + "\"."); Console.WriteLine(); return; }
/// <summary> /// Gets the references. /// </summary> /// <param name="signedXml">The signed XML.</param> /// <param name="document">The document.</param> /// <param name="xmlPath">The XML path.</param> /// <param name="namespaceManager">The namespace manager.</param> /// <param name="documentLocation">The document location.</param> /// <returns>IEnumerable<Reference>.</returns> IEnumerable <Reference> GetReferences( SignedXml signedXml, XmlDocument document, string xmlPath, XmlNamespaceManager namespaceManager, Uri documentLocation) { XmlNodeList elements = null; if (SignatureLocation == SignatureLocation.Enveloping) { // ignore the path - it doesn't make sense - always sign the document's root element and import it into /Signature/Object xmlPath = _xPathRootElement; } if (xmlPath != null) { elements = document.SelectNodes(xmlPath, namespaceManager); if (elements.Count == 1 && elements[0] is XmlDocument) { // the path points to the document node elements = null; } } if (elements == null) { // sign the whole document var reference = new Reference(); if (SignatureLocation == SignatureLocation.Enveloped) { reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); } if (SignatureLocation == SignatureLocation.Detached && documentLocation != null && !documentLocation.IsFile) { reference.Uri = documentLocation.ToString(); } else { reference.Uri = ""; } yield return(reference); } else { // build a set of all possible unique ID attribute names: var nameIds = new HashSet <string> { "id", "Id", "ID" }; // these are always here if (IdAttributeNames != null) { nameIds.UnionWith(IdAttributeNames); // add the custom ones } else { nameIds.Add(XmlConstants.Id); // add the XML standard one } var nsManager = XmlConstants.GetXmlNamespaceManager(document); // a set of all unique id-s in the document will help us generate new unique xml:Id-s var xmlIds = new HashSet <string>(); foreach (var name in nameIds) { xmlIds.UnionWith( document.SelectNodes( string.Format(CultureInfo.InvariantCulture, _xPathAllAttributes, name), nsManager) .OfType <XmlAttribute>() .Select(a => a.Value) .Distinct()); } var id = 0; foreach (var element in elements.OfType <XmlElement>()) { string xmlId = null; if (SignatureLocation == SignatureLocation.Enveloping) { // we need a new unique xml:Id for the Object element xmlId = GetNewId(ref id, xmlIds); // wrap the root element in a /Signature/Object element signedXml.AddObject( new DataObject { Data = elements, // contains the root element only Id = xmlId, // add the xml:Id to the object, so that we can refer to it from the reference object }); } else { // find a unique ID - any one of the set should do foreach (var name in nameIds) { if (element.SelectSingleNode("@" + name, nsManager) is XmlAttribute attribute && attribute.Value != null) { xmlId = attribute.Value; break; } } // if it doesn't have unique id, generate a new one and add it to the element, so that we can refer to it from the reference object if (string.IsNullOrWhiteSpace(xmlId)) { xmlId = GetNewId(ref id, xmlIds); var attribute = document.CreateAttribute(XmlConstants.Prefix, XmlConstants.IdLocalName, XmlConstants.Namespace); attribute.Value = xmlId; element.Attributes.Append(attribute); } } // create the reference object var reference = new Reference("#" + xmlId) { DigestMethod = _digestMethod }; switch (HashAlgorithmName) { case Algorithms.Hash.Sha256: reference.AddTransform(new XmlDsigExcC14NTransform()); break; #pragma warning disable 0612, 0618 // Type or member is obsolete - used for bacwards compatibility case Algorithms.Hash.Sha1: reference.AddTransform(new XmlDsigC14NTransform()); break; #pragma warning restore 0612, 0618 // Type or member is obsolete - used for bacwards compatibility } if (SignatureLocation == SignatureLocation.Enveloped) { reference.AddTransform(new XmlDsigEnvelopedSignatureTransform()); } yield return(reference); } } }
static DCinemaSecurityMessageType SignETM(DCinemaSecurityMessageType extraTheatreMessage, X509Certificate2 x509Certificate2) { 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 xmlSerializer = new XmlSerializer(typeof(DCinemaSecurityMessageType)); 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(@"\SOURCE_SMPTE\Output\signedSerializer.Test.xml"); signedSerializer.Serialize(signedWriter, singedElement); signedWriter.Close(); } catch (CryptographicException e) { Console.WriteLine(e.Message); } extraTheatreMessage.Signature = signedXml.Signature.GetXml(); return(extraTheatreMessage); }
/// <summary> /// Signs a XML file (enveloping signature) using a digital certificate /// </summary> /// <param name="xml">The XML data to sign represented as byte array</param> /// <param name="certFile">The certificate file to use for signing</param> /// <param name="certPassword">The certificate password</param> /// <param name="signWithSha256">Sign the document using SHA-256</param> /// <returns>The signed data represented as byte array</returns> private static byte[] SignEnvelopingXml(byte[] xml, string certFile, string certPassword, bool signWithSha256) { if (xml == null || xml.Length == 0) { // invalid XML array throw new Exception("Nothing to sign!"); } // load certificate X509Certificate2 certificate = LoadSigningCertificate(certFile, certPassword, signWithSha256); if (!certificate.HasPrivateKey) { // invalid certificate throw new Exception("Specified certificate not suitable for signing!"); } using (MemoryStream stream = new MemoryStream(xml)) { // go to the beginning of the stream stream.Flush(); stream.Position = 0; // create new XmlDocument from stream XmlDocument doc = new XmlDocument() { PreserveWhitespace = true }; doc.Load(stream); // craete transform (for canonicalization method & reference) XmlDsigExcC14NTransform transform = new XmlDsigExcC14NTransform(); // create new SignedXml from XmlDocument SignedXml signed = GenerateSignedXml(doc, certificate, signWithSha256); signed.SignedInfo.CanonicalizationMethod = transform.Algorithm; // get nodes (use XPath to include FATCA declaration) XmlNodeList nodes = doc.DocumentElement.SelectNodes("/*"); // define data object DataObject dataObject = new DataObject() { Data = nodes, Id = "FATCA" }; // add the data we are signing as a sub-element (object) of the signature element signed.AddObject(dataObject); // create reference Reference reference = new Reference(string.Format("#{0}", dataObject.Id)); reference.AddTransform(transform); if (signWithSha256) { // SHA-256 digest reference.DigestMethod = RSAPKCS1SHA256SignatureDescription.ReferenceDigestMethod; } // add reference to document signed.AddReference(reference); // include KeyInfo object & compute signature signed.KeyInfo = CreateKeyInfoFromCertificate(certificate); signed.ComputeSignature(); // get signature XmlElement xmlDigitalSignature = signed.GetXml(); // XML declaration string xmlDeclaration = string.Empty; if (doc.FirstChild is XmlDeclaration) { // include declaration xmlDeclaration = doc.FirstChild.OuterXml; } // return signature as byte array return(Encoding.UTF8.GetBytes(string.Concat(xmlDeclaration, xmlDigitalSignature.OuterXml))); } }
//tutorial - https://www.asptricks.net/2015/09/sign-xmldocument-with-x509certificate2.html internal static XmlDocument GetSignedXMLDocument(XmlDocument xmlDocument, X509Certificate2 certificate, long procedureSerial = -1, string reason = "") { //Before signing, should check if current document sign is valid or not, if current document is invalid, then new sign should not be added - not implemented yet, but should be if (CheckIfDocumentPreviouslySigned(xmlDocument)) { bool?isLastSignVerified = VerifyLastSign(xmlDocument); if (isLastSignVerified == false) { MessageBox.Show("The file was TEMPERED after last sign !!"); return(null); //Last Sign Not Verified } } //Then sign the xml try { //MessageBox.Show(certificate.Subject); SignedXml signedXml = new SignedXml(xmlDocument); signedXml.SigningKey = certificate.PrivateKey; // Create a reference to be signed Reference reference = new Reference(); ///////////////////// reference.Uri = ""; //"#" + procedureSerial; //reference.Type = reason; //reference.Id = DateTime.UtcNow.Ticks.ToString(); Tsa tsa = new Tsa(); string signedTsaString = tsa.GetSignedHashFromTsa(xmlDocument); DateTime?tsaTime = Tsa.GetTsaTimeFromSignedHash(signedTsaString); //reference.Id = Base64EncodedCurrentTime(tsaTime); reference.Id = signedTsaString; //bool status = Tsa.ValidateTimestamp(xmlDocument, reference.Id); //reference.TransformChain = ; ///////////////////// // Add an enveloped transformation to the reference. XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform(true); reference.AddTransform(env); // Add the reference to the SignedXml object. signedXml.AddReference(reference); //canonicalize XmlDsigC14NTransform c14t = new XmlDsigC14NTransform(); reference.AddTransform(c14t); KeyInfo keyInfo = new KeyInfo(); KeyInfoX509Data keyInfoData = new KeyInfoX509Data(certificate); KeyInfoName kin = new KeyInfoName(); //kin.Value = "Public key of certificate"; kin.Value = certificate.FriendlyName; RSA rsa = (RSA)certificate.PublicKey.Key; RSAKeyValue rkv = new RSAKeyValue(rsa); keyInfo.AddClause(rkv); keyInfo.AddClause(kin); keyInfo.AddClause(keyInfoData); signedXml.KeyInfo = keyInfo; //////////////////////////////////////////Add Other Data as we need//// // Add the data object to the signature. //CreateMetaDataObject("Name", GetNetworkTime()); signedXml.AddObject(CreateMetaDataObject(procedureSerial, reason)); /////////////////////////////////////////////////////////////////////// // Compute the signature. signedXml.ComputeSignature(); // Get the XML representation of the signature and save // it to an XmlElement object. XmlElement xmlDigitalSignature = signedXml.GetXml(); xmlDocument.DocumentElement.AppendChild( xmlDocument.ImportNode(xmlDigitalSignature, true) ); ///////////////////// } catch (Exception exception) { MessageBox.Show("Internal System Error during sign"); throw exception; } return(xmlDocument); }
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); }