Exemple #1
0
        /// <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);
        }