/// <summary> /// Create a XAdES-BES signature, singing the the part with the provided reference. /// </summary> /// <remarks> /// <para> /// Creates a signature, where only the requested element is signed. It /// returns a detached signature that can be used seperatly or /// added to the document. Before it can be added, it should be /// imported. /// </para> /// </remarks> /// <example> /// <code language="C#"> /// var xigner = new XadesCreator(certificate); /// xigner.TimestampProvider = new TSA.EHealthTimestampProvider(tsa); /// xigner.DataTransforms.Add(new XmlDsigBase64Transform()); /// xigner.DataTransforms.Add(new OptionalDeflateTransform()); /// var xades = xigner.CreateXadesT(document, "datailID"); /// </code> /// </example> /// <param name="doc">XML document contains an element with an "Id" equal to the reference parameter</param> /// <param name="reference">The reference of the elmement to sign, without the #-sign</param> /// <returns>The XML-signature element containing the required XAdES structures.</returns> /// <exception cref="ArgumentNullException">When the doc argument is null</exception> public XmlElement CreateXadesBes(XmlDocument doc, String reference) { if (doc == null) { throw new ArgumentNullException("doc", "An xml document must be provider"); } //prepare to sign Guid sId = Guid.NewGuid(); var signedXml = new Internal.ExtendedSignedXml(doc); //Set the signingg key signedXml.SigningKey = (AsymmetricAlgorithm)Certificate?.GetRSAPrivateKey() ?? Certificate?.GetECDsaPrivateKey(); signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl; if (signedXml.SigningKey is RSA) { signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"; } else { signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256"; } //Add the data reference var dataRef = new Reference(reference == null ? "" : "#" + reference); dataRef.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; if (DataTransforms.Count == 0) { if (reference == null) { dataRef.AddTransform(new XmlDsigEnvelopedSignatureTransform()); } else { dataRef.AddTransform(new XmlDsigExcC14NTransform()); } } else { foreach (var transform in DataTransforms) { dataRef.AddTransform(transform); } } signedXml.AddReference(dataRef); //add the xades reference var xadesRef = new Reference("#idSignedProperties"); xadesRef.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256"; xadesRef.Type = "http://uri.etsi.org/01903#SignedProperties"; xadesRef.AddTransform(new XmlDsigExcC14NTransform()); signedXml.AddReference(xadesRef); //Add key info up to, but not including the root CertificateChain .Where(c => c.Subject != c.Issuer) .ToList() .ForEach(c => signedXml.KeyInfo.AddClause(new KeyInfoX509Data(c))); //Add data target.Value = "#_" + sId.ToString("D"); signTime.InnerText = DateTime.UtcNow.ToString("yyyy-MM-ddTHH:mm:ssK", CultureInfo.InvariantCulture); certDigestVal.InnerText = Convert.ToBase64String(SHA256.Create().ComputeHash(Certificate?.RawData)); issuerName.InnerText = Certificate?.Issuer; serialNbr.InnerText = new BigInteger(Certificate?.GetSerialNumber()).ToString(CultureInfo.InvariantCulture); var dataObject = new DataObject(); dataObject.LoadXml(signObject); signedXml.AddObject(dataObject); //Compute the signature signedXml.ComputeSignature(); //Add the ID to the signature XmlElement ret = signedXml.GetXml(); XmlAttribute sIdAttr = ret.OwnerDocument.CreateAttribute("Id"); sIdAttr.Value = "_" + sId.ToString("D"); ret.Attributes.Append(sIdAttr); return(ret); }