/// <summary> /// Carga el documento XML especificado y establece para firmar el elemento especificado en elementId /// </summary> /// <param name="xmlDocument"></param> /// <param name="elementId"></param> /// <param name="mimeType"></param> public void SetContentInternallyDetached(XmlDocument xmlDocument, string elementId, string mimeType) { _document = (XmlDocument)xmlDocument.Clone(); _document.PreserveWhitespace = true; Reference reference = new Reference(); reference.Uri = "#" + elementId; reference.Id = "Reference-" + Guid.NewGuid().ToString(); _objectReference = reference.Id; _mimeType = mimeType; if (mimeType == "text/xml") { XmlDsigC14NTransform transform = new XmlDsigC14NTransform(); reference.AddTransform(transform); } else { XmlDsigBase64Transform transform = new XmlDsigBase64Transform(); reference.AddTransform(transform); } _xadesSignedXml = new XadesSignedXml(_document); _xadesSignedXml.AddReference(reference); }
/// <summary> /// Inserta un documento para generar una firma internally detached. /// </summary> /// <param name="content"></param> /// <param name="mimeType"></param> public void SetContentInternallyDetached(byte[] content, string mimeType, string fileName = null) { _document = new XmlDocument(); XmlElement rootElement = _document.CreateElement("DOCFIRMA"); _document.AppendChild(rootElement); string id = "CONTENT-" + Guid.NewGuid().ToString(); Reference reference = new Reference(); reference.Uri = "#" + id; reference.Id = "Reference-" + Guid.NewGuid().ToString(); _objectReference = reference.Id; _mimeType = mimeType; XmlElement contentElement = _document.CreateElement("CONTENT"); if (mimeType == "text/xml") { XmlDocument doc = new XmlDocument(); doc.PreserveWhitespace = true; doc.Load(new MemoryStream(content)); contentElement.InnerXml = doc.DocumentElement.OuterXml; XmlDsigC14NTransform transform = new XmlDsigC14NTransform(); reference.AddTransform(transform); } else if (mimeType == "hash/sha256") { contentElement.SetAttribute("Encoding", "http://www.w3.org/2000/09/xmldsig#base64"); contentElement.SetAttribute("MimeType", mimeType); if (!string.IsNullOrEmpty(fileName)) { contentElement.SetAttribute("URI", Path.GetFileName(fileName)); } using (SHA256 sha2 = SHA256.Create()) { contentElement.InnerText = Convert.ToBase64String(sha2.ComputeHash(content)); } XmlDsigBase64Transform transform = new XmlDsigBase64Transform(); reference.AddTransform(transform); } else { contentElement.SetAttribute("Encoding", "http://www.w3.org/2000/09/xmldsig#base64"); contentElement.InnerText = Convert.ToBase64String(content); XmlDsigBase64Transform transform = new XmlDsigBase64Transform(); reference.AddTransform(transform); } contentElement.SetAttribute("Id", id); rootElement.AppendChild(contentElement); _xadesSignedXml = new XadesSignedXml(_document); _xadesSignedXml.AddReference(reference); }
/// <summary> /// Inserta un contenido XML para generar una firma enveloping. /// </summary> /// <param name="xmlDocument"></param> public void SetContentEveloping(XmlDocument xmlDocument) { Reference reference = new Reference(); _xadesSignedXml = new XadesSignedXml(); XmlDocument doc = (XmlDocument)xmlDocument.Clone(); doc.PreserveWhitespace = true; if (doc.ChildNodes[0].NodeType == XmlNodeType.XmlDeclaration) { doc.RemoveChild(doc.ChildNodes[0]); } //Add an object string dataObjectId = "DataObject-" + Guid.NewGuid().ToString(); System.Security.Cryptography.Xml.DataObject dataObject = new System.Security.Cryptography.Xml.DataObject(); dataObject.Data = doc.ChildNodes; dataObject.Id = dataObjectId; _xadesSignedXml.AddObject(dataObject); reference.Id = "Reference-" + Guid.NewGuid().ToString(); reference.Uri = "#" + dataObjectId; reference.Type = SignedXml.XmlDsigNamespaceUrl + "Object"; XmlDsigC14NTransform transform = new XmlDsigC14NTransform(); reference.AddTransform(transform); _objectReference = reference.Id; _mimeType = "text/xml"; _xadesSignedXml.AddReference(reference); _document = null; }
/// <summary> /// Inserta un documento para generar una firma externally detached. /// </summary> /// <param name="fileName"></param> public void SetContentExternallyDetached(string fileName) { Reference reference = new Reference(); _document = new XmlDocument(); _xadesSignedXml = new XadesSignedXml(); reference.Uri = "file://" + fileName.Replace("\\", "/"); reference.Id = "Reference-" + Guid.NewGuid().ToString(); if (reference.Uri.EndsWith(".xml") || reference.Uri.EndsWith(".XML")) { _mimeType = "text/xml"; reference.AddTransform(new XmlDsigC14NTransform()); } _objectReference = reference.Id; _xadesSignedXml.AddReference(reference); }
/// <summary> /// Realiza la contrafirma de la firma actual /// </summary> /// <param name="certificate"></param> /// <param name="signMethod"></param> public void CounterSign(X509Certificate2 certificate, SignMethod? signMethod = null) { SetSignatureId(); if (_xadesSignedXml == null) { throw new Exception("No hay ninguna firma XADES cargada previamente."); } if (certificate == null) { throw new Exception("Es necesario un certificado válido para la firma."); } if (signMethod.HasValue) { this.SignMethod = signMethod.Value; } _signCertificate = certificate; XadesSignedXml counterSignature = new XadesSignedXml(_document); SetCryptoServiceProvider(); counterSignature.SigningKey = _rsaKey; Reference reference = new Reference(); reference.Uri = "#" + _xadesSignedXml.SignatureValueId; reference.Id = "Reference-" + Guid.NewGuid().ToString(); reference.Type = "http://uri.etsi.org/01903#CountersignedSignature"; reference.AddTransform(new XmlDsigC14NTransform()); counterSignature.AddReference(reference); _objectReference = reference.Id; KeyInfo keyInfo = new KeyInfo(); keyInfo.Id = "KeyInfoId-" + _signatureId; keyInfo.AddClause(new KeyInfoX509Data((X509Certificate)_signCertificate)); keyInfo.AddClause(new RSAKeyValue((RSA)_rsaKey)); counterSignature.KeyInfo = keyInfo; Reference referenceKeyInfo = new Reference(); referenceKeyInfo.Id = "ReferenceKeyInfo-" + _signatureId; referenceKeyInfo.Uri = "#KeyInfoId-" + _signatureId; counterSignature.AddReference(referenceKeyInfo); counterSignature.Signature.Id = _signatureId; counterSignature.SignatureValueId = _signatureValueId; XadesObject counterSignatureXadesObject = new XadesObject(); counterSignatureXadesObject.Id = "CounterSignatureXadesObject-" + Guid.NewGuid().ToString(); counterSignatureXadesObject.QualifyingProperties.Target = "#" + _signatureId; counterSignatureXadesObject.QualifyingProperties.SignedProperties.Id = "SignedProperties-" + _signatureId; AddSignatureProperties(counterSignatureXadesObject.QualifyingProperties.SignedProperties.SignedSignatureProperties, counterSignatureXadesObject.QualifyingProperties.SignedProperties.SignedDataObjectProperties, counterSignatureXadesObject.QualifyingProperties.UnsignedProperties.UnsignedSignatureProperties, "text/xml", _signCertificate); counterSignature.AddXadesObject(counterSignatureXadesObject); foreach (Reference signReference in counterSignature.SignedInfo.References) { signReference.DigestMethod = _refsMethodUri; } counterSignature.AddXadesNamespace = true; counterSignature.ComputeSignature(); UnsignedProperties unsignedProperties = _xadesSignedXml.UnsignedProperties; unsignedProperties.UnsignedSignatureProperties.CounterSignatureCollection.Add(counterSignature); _xadesSignedXml.UnsignedProperties = unsignedProperties; UpdateDocument(); _xadesSignedXml = new XadesSignedXml(_document); XmlNode xmlNode = _document.SelectSingleNode("//*[@Id='" + _signatureId + "']"); _xadesSignedXml.LoadXml((XmlElement)xmlNode); }
/// <summary> /// Añade una firma al documento /// </summary> /// <param name="certificate"></param> /// <param name="signMethod"></param> public void CoSign(X509Certificate2 certificate, SignMethod? signMethod = null) { if (_xadesSignedXml == null) { throw new Exception("No hay ninguna firma XADES creada previamente."); } if (certificate == null) { throw new Exception("Es necesario un certificado válido para la firma."); } Reference refContent = _xadesSignedXml.SignedInfo.References[0] as Reference; if (refContent == null) { throw new Exception("No se ha podido encontrar la referencia del contenido firmado."); } if (_xadesSignedXml.XadesObject.QualifyingProperties.SignedProperties.SignedDataObjectProperties.DataObjectFormatCollection.Count > 0) { foreach (DataObjectFormat dof in _xadesSignedXml.XadesObject.QualifyingProperties.SignedProperties.SignedDataObjectProperties.DataObjectFormatCollection) { if (dof.ObjectReferenceAttribute == ("#" + refContent.Id)) { _mimeType = dof.MimeType; break; } } } var destination = _xadesSignedXml.GetSignatureElement().ParentNode; _xadesSignedXml = new XadesSignedXml(_document); refContent.Id = "Reference-" + Guid.NewGuid().ToString(); _xadesSignedXml.AddReference(refContent); if (destination.NodeType != XmlNodeType.Document) { _xadesSignedXml.SignatureNodeDestination = (XmlElement)destination; } else { _xadesSignedXml.SignatureNodeDestination = ((XmlDocument)destination).DocumentElement; } _objectReference = refContent.Id; SetSignatureId(); Sign(certificate, signMethod); }
/// <summary> /// Construye el documento enveloped /// </summary> private void CreateEnvelopedDocument() { Reference reference = new Reference(); _xadesSignedXml = new XadesSignedXml(_document); reference.Id = "Reference-" + Guid.NewGuid().ToString(); reference.Uri = ""; for (int i = 0; i < _document.DocumentElement.Attributes.Count; i++) { if (_document.DocumentElement.Attributes[i].Name.Equals("id", StringComparison.InvariantCultureIgnoreCase)) { reference.Uri = "#" + _document.DocumentElement.Attributes[i].Value; break; } } XmlDsigEnvelopedSignatureTransform xmlDsigEnvelopedSignatureTransform = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(xmlDsigEnvelopedSignatureTransform); _objectReference = reference.Id; _xadesSignedXml.AddReference(reference); }
private void addCounterSignatureButton_Click(object sender, System.EventArgs e) { X509Certificate2 certificateForCounterSignature = this.LetUserChooseCertificate(); if (certificateForCounterSignature != null) { this.xadesSignedXml.SignatureValueId = this.signatureValueIdTextBox.Text; XmlElement parentSignatureXmlElement = this.xadesSignedXml.GetXml(); XmlDocument parentSignatureXmlDocument = new XmlDocument(); parentSignatureXmlDocument.AppendChild(parentSignatureXmlDocument.ImportNode(parentSignatureXmlElement, true)); XadesSignedXml counterSignature = new XadesSignedXml(parentSignatureXmlDocument); RSACryptoServiceProvider rsaKey = (RSACryptoServiceProvider) this.Certificate.PrivateKey; counterSignature.SigningKey = rsaKey; KeyInfo keyInfo = new KeyInfo(); keyInfo.AddClause(new KeyInfoX509Data((X509Certificate) certificateForCounterSignature)); keyInfo.AddClause(new RSAKeyValue(rsaKey)); counterSignature.KeyInfo = keyInfo; Cert cert = new Cert(); cert.IssuerSerial.X509IssuerName = certificateForCounterSignature.IssuerName.Name; cert.IssuerSerial.X509SerialNumber = certificateForCounterSignature.SerialNumber; cert.CertDigest.DigestMethod.Algorithm = SignedXml.XmlDsigSHA1Url; cert.CertDigest.DigestValue = certificateForCounterSignature.GetCertHash(); counterSignature.Signature.Id = "CounterSignatureId"; XadesObject counterSignatureXadesObject = new XadesObject(); counterSignatureXadesObject.Id = "CounterSignatureXadesObjectId"; counterSignatureXadesObject.QualifyingProperties.Target = "#CounterSignatureId"; counterSignatureXadesObject.QualifyingProperties.SignedProperties.Id = "CounterSignatureSignedProperiesId"; Reference newReference = new Reference(); newReference.Uri = "#" + this.xadesSignedXml.SignatureValueId; counterSignature.AddReference(newReference); SignedSignatureProperties signedSignatureProperties = counterSignatureXadesObject.QualifyingProperties.SignedProperties.SignedSignatureProperties; signedSignatureProperties.SigningCertificate.CertCollection.Add(cert); signedSignatureProperties.SigningTime = DateTime.Parse(this.signingTimeTextBox.Text); signedSignatureProperties.SignaturePolicyIdentifier.SignaturePolicyImplied = true; counterSignature.AddXadesObject(counterSignatureXadesObject); counterSignature.ComputeSignature(); UnsignedProperties unsignedProperties = this.xadesSignedXml.UnsignedProperties; unsignedProperties.UnsignedSignatureProperties.CounterSignatureCollection.Add(counterSignature); this.xadesSignedXml.UnsignedProperties = unsignedProperties; this.ShowSignature(); } }
private static XadesSignedXml CreateFromXmlDocument(XmlDocument envelopedSignatureXmlDocument) { XmlDsigEnvelopedSignatureTransform xmlDsigEnvelopedSignatureTransform; Reference reference; reference = new Reference(); var xadesSignedXml = new XadesSignedXml(envelopedSignatureXmlDocument); reference.Uri = ""; reference.Id = "xml_ref_id"; //TODO jbonilla - Parameter? //reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; reference.DigestMethod = SignedXml.XmlDsigSHA1Url; // ETSI TS 103 171 V2.1.1 // 6.2.4 Transforms within ds:Reference element { //XmlDsigC14NTransform xmlDsigC14NTransform = new XmlDsigC14NTransform(); //reference.AddTransform(xmlDsigC14NTransform); xmlDsigEnvelopedSignatureTransform = new XmlDsigEnvelopedSignatureTransform(); reference.AddTransform(xmlDsigEnvelopedSignatureTransform); //jbonilla - Para permitir multifirmas (co-firmas) Dictionary<string, string> namespaces = new Dictionary<string, string>(); namespaces.Add("ds", "http://www.w3.org/2000/09/xmldsig#"); var xmlDsigXPathTransform = CreateXPathTransform("not(ancestor-or-self::ds:Signature)", namespaces); reference.AddTransform(xmlDsigXPathTransform); } xadesSignedXml.AddReference(reference); // ETSI TS 103 171 V2.1.1 // 6.2.2 Canonicalization of ds:SignedInfo element xadesSignedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigC14NTransformUrl;//"http://www.w3.org/2001/10/xml-exc-c14n#"; //xadesSignedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; xadesSignedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url; return xadesSignedXml; }