Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public KeyInfoNode addSecurityTokenReference()
        {
            XmlElement securityTokenRef = SecurityTokenReference.xmlKeyInfoSecurityTokenReference(_doc, uuid);
            var        keyInfoData      = new KeyInfoNode(securityTokenRef);

            return(keyInfoData);
        }
Пример #2
0
        /// <summary>
        ///     This method is only used to sign the autenticacion service
        /// </summary>
        public static XmlElement SignAuthenticationRequest(XmlElement xmlElement, X509Certificate2 x509Certificate2, string referenceUri, XmlElement securityTokenReferenceElement)
        {
            var signedXml = new SignedXmlWithId(xmlElement)
            {
                SigningKey = x509Certificate2.GetRSAPrivateKey()
            };

            signedXml.SignedInfo.SignatureMethod        = SignedXml.XmlDsigRSASHA1Url;
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;

            var reference = new Reference
            {
                Uri          = referenceUri,
                DigestMethod = SignedXml.XmlDsigSHA1Url
            };

            reference.AddTransform(new XmlDsigExcC14NTransform());
            signedXml.AddReference(reference);

            var keyInfo     = new KeyInfo();
            var keyInfoNode = new KeyInfoNode
            {
                Value = securityTokenReferenceElement
            };

            keyInfo.AddClause(keyInfoNode);
            signedXml.KeyInfo = keyInfo;

            signedXml.ComputeSignature();

            return(signedXml.GetXml());
        }
Пример #3
0
        public static XmlElement GenerateSecurity(XmlDocument document,
                                                  X509Certificate2 certificate,
                                                  string prefix,
                                                  string id,
                                                  string iteration = "")
        {
            XmlNodeList  nodeList     = null;
            XmlElement   elemSecurity = null;
            FSSSignedXml signer       = new FSSSignedXml(document);

            signer.SigningKey = certificate.PrivateKey;

            KeyInfo    keyInfo = new KeyInfo();
            XmlElement keySecurityTokenReference =
                document.CreateElement("wsse", "SecurityTokenReference", WsdlServiceHandle.xmlns_wsse);
            XmlElement keyReference = document.CreateElement("wsse", "Reference", WsdlServiceHandle.xmlns_wsse);

            keyReference.SetAttribute("URI", $"#http://eln.fss.ru/actor/mo/{WsdlServiceHandle.ogrn}");
            keySecurityTokenReference.AppendChild(keyReference);
            KeyInfoNode keyInfoData = new KeyInfoNode(keySecurityTokenReference);

            keyInfo.AddClause(keyInfoData);
            signer.KeyInfo = keyInfo;

            Reference reference =
                new Reference($"#{prefix}_{id}{(String.IsNullOrEmpty(iteration) ? "" : $"_{iteration}")}");
        : super(securityToken, true /* addTimestamp */)
    {
        EwsUtilities.ValidateParam(securityToken, "securityToken");
        EwsUtilities.ValidateParam(securityTokenReference, "securityTokenReference");

        SafeXmlDocument doc = new SafeXmlDocument();

        doc.PreserveWhitespace = true;
        doc.LoadXml(securityTokenReference);
        this.keyInfoNode = new KeyInfoNode(doc.DocumentElement);
    }
Пример #5
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PartnerTokenCredentials"/> class.
        /// </summary>
        /// <param name="securityToken">The token.</param>
        /// <param name="securityTokenReference">The token reference.</param>
        internal PartnerTokenCredentials(string securityToken, string securityTokenReference)
            : base(securityToken, true /* addTimestamp */)
        {
            EwsUtilities.ValidateParam(securityToken, "securityToken");
            EwsUtilities.ValidateParam(securityTokenReference, "securityTokenReference");

            SafeXmlDocument doc = new SafeXmlDocument();

            doc.PreserveWhitespace = true;
            doc.LoadXml(securityTokenReference);
            this.keyInfoNode = new KeyInfoNode(doc.DocumentElement);
        }
Пример #6
0
        public void InvalidKeyNode()
        {
            string      bad = "<Test></Test>";
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(bad);

            KeyInfoNode node1 = new KeyInfoNode();

            node1.LoadXml(null);
            Assert.Null(node1.GetValue());
        }
Пример #7
0
        public void InvalidKeyNode()
        {
            string      bad = "<Test></Test>";
            XmlDocument doc = new XmlDocument();

            doc.LoadXml(bad);

            KeyInfoNode node1 = new KeyInfoNode();

            // LAMESPEC: No ArgumentNullException is thrown if value == null
            node1.LoadXml(null);
            Assert.IsNull(node1.Value, "Value==null");
        }
Пример #8
0
        public void KeyInfoNode()
        {
            string      test = "<Test>KeyInfoNode</Test>";
            XmlDocument doc  = new XmlDocument();

            doc.LoadXml(test);

            KeyInfoNode node = new KeyInfoNode(doc.DocumentElement);

            info.AddClause(node);
            Assert.AreEqual("<KeyInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><Test xmlns=\"\">KeyInfoNode</Test></KeyInfo>", (info.GetXml().OuterXml), "node");
            Assert.AreEqual(1, info.Count, "node count");
        }
Пример #9
0
        private XmlElement siganatureXML(XmlDocument doc, Parametros parametro)
        {
            if (doc == null)
            {
                throw new ArgumentException("xmlDoc");
            }


            PrivateKeyRSACryptoServiceWC3 privaKeryRSQ = new PrivateKeyRSACryptoServiceWC3(parametro.certificado.getX509Certificate2());

            privaKeryRSQ.extraerPrivateKeyRSACryptoServiceProvider();



            SignedInfoWC3 signeInfo = new SignedInfoWC3(doc, parametro.UUIDiRamdon);
            KeyInfoNode   info      = signeInfo.addSecurityTokenReference();
            KeyInfo       keyInfo   = new KeyInfo();

            keyInfo.AddClause(info);



            ReferenceWC3 referenceXML = new ReferenceWC3($"#_0", SignedXml.XmlDsigSHA1Url);

            referenceXML.addDigestMethod();
            referenceXML.addUri();
            referenceXML.addTransform();



            var signedXml = new SignedXmlWithId(doc);


            signedXml.SigningKey = parametro.certificado.getX509Certificate2().PrivateKey;


            signedXml.SignedInfo.SignatureMethod        = SignedXml.XmlDsigRSASHA1Url;
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            signedXml.AddReference(referenceXML.getRefence());



            signedXml.KeyInfo = keyInfo;



            signedXml.ComputeSignature();
            XmlElement xmlDigitalSignature = signedXml.GetXml();

            return(xmlDigitalSignature);
        }
Пример #10
0
        public void ImportKeyNode()
        {
            string      value = "<KeyName xmlns=\"http://www.w3.org/2000/09/xmldsig#\">Mono::</KeyName>";
            XmlDocument doc   = new XmlDocument();

            doc.LoadXml(value);

            KeyInfoNode node1 = new KeyInfoNode();

            node1.LoadXml(doc.DocumentElement);

            string s = (node1.GetXml().OuterXml);

            Assert.Equal(value, s);
        }
Пример #11
0
        public void NewKeyNode()
        {
            string      test = "<Test></Test>";
            XmlDocument doc  = new XmlDocument();

            doc.LoadXml(test);

            KeyInfoNode node1 = new KeyInfoNode();

            node1.Value = doc.DocumentElement;
            XmlElement xel = node1.GetXml();

            KeyInfoNode node2 = new KeyInfoNode(node1.Value);

            node2.LoadXml(xel);

            Assert.AreEqual((node1.GetXml().OuterXml), (node2.GetXml().OuterXml), "node1==node2");
        }
Пример #12
0
        private EncryptedData CreateEncryptedData(string dataId, string keyId)
        {
            var encryptedData = new EncryptedData();

            encryptedData.Type             = EncryptedXml.XmlEncElementContentUrl;
            encryptedData.EncryptionMethod = new EncryptionMethod(EncryptedXml.XmlEncAES256Url);
            encryptedData.Id = dataId;
            var tokenReference = Document.CreateElement("wsse:SecurityTokenReference", Manager.LookupNamespace("wsse"));

            tokenReference.SetAttribute("TokenType", Manager.LookupNamespace("wsse11"), "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#EncryptedKey");
            var reference = Document.CreateElement("wsse:Reference", Manager.LookupNamespace("wsse"));

            reference.SetAttribute("URI", "#" + keyId);
            tokenReference.AppendChild(reference);
            var infoNode = new KeyInfoNode(tokenReference);

            encryptedData.KeyInfo.AddClause(infoNode);
            return(encryptedData);
        }
Пример #13
0
        /// <summary>
        /// Firmar y Encriptar el Documento XML usando un Certificado x509.
        /// </summary>
        /// <param name="xmldoc">el documento XML a firmar y encriptar.</param>
        /// <param name="certificado">el certificado para poder firmar el XML</param>
        /// <param name="certificadopublico">el certificado publico para poder encriptar</param>
        /// <returns></returns>
        private static XmlDocument FirmaryEncriptarSoapRequest(XmlDocument xmldoc, X509Certificate2 certificadoPrivado, X509Certificate2 certificadopublico)
        {
            #region Firmar
            //añadir las referencias de espacios de nombres para asegurarnos de que podamos trabajar contra
            //cualquier documento elemento XML sin importar el nombramiento de los Tags siempre y cuando sepamos sus Namespaces.
            XmlNamespaceManager namespaceManager = new XmlNamespaceManager(xmldoc.NameTable);
            namespaceManager.AddNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            namespaceManager.AddNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            namespaceManager.AddNamespace("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");

            //Seleccionar el Header para agregarle elementos.
            XmlElement headerNode = xmldoc.DocumentElement.SelectSingleNode("//soapenv:Header", namespaceManager) as XmlElement;
            //Creamos el nodo de seguridad <Security>
            XmlElement securityNode = xmldoc.CreateElement("wsse", "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            securityNode.SetAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            securityNode.SetAttribute("mustUnderstand", "http://schemas.xmlsoap.org/soap/envelope/", "1");
            XmlAttribute mustUnderstandSecurityAttribute = securityNode.GetAttributeNode("mustUnderstand");
            mustUnderstandSecurityAttribute.Prefix = "soapenv";



            #region Preparar elementos a ser firmados


            //Ahora vamos a crear otro BinarySecurityToken

            //Ahora creamos un BinarySecurityToken que será el certificado x509 de la clave privada
            //Con este BinarySecurityToken se espera que el receptor pueda verificar el Digest de la firma que se
            //genera con este BinarySecurityToken.
            //este BinarySecurityToken es firmado también.

            XmlElement binarySecurityTokenNode2 = xmldoc.CreateElement("wsse", "BinarySecurityToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            //El atributo EncodingType dice cómo el Token está codificado, en este caso, Base64Binary.
            binarySecurityTokenNode2.SetAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
            //El atributo ValueType indica qué es el BinarySecurityToken, en este caso un Certificado X509v3.
            binarySecurityTokenNode2.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");

            binarySecurityTokenNode2.SetAttribute("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", XmlElementsIds.PrivateKeyBinarySecurityTokenUri);
            XmlAttribute attribute2 = binarySecurityTokenNode2.GetAttributeNode("Id");
            attribute2.Prefix = "wsu";
            binarySecurityTokenNode2.InnerText = Convert.ToBase64String(certificadoPrivado.GetRawCertData());

            //Creamos una estampa de tiempo, la cuál será firmada también:

            Timestamp timestamp = new Timestamp();
            timestamp.TtlInSeconds = 5000;

            //El body también será firmado, pero todavía no tiene los atributos requeridos para que pueda ser firmado
            //Aquí se los agrego.

            //Ahora vamos a ponerle un Id.
            XmlElement body = xmldoc.DocumentElement.SelectSingleNode("//soapenv:Body", namespaceManager) as XmlElement;
            body.SetAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            body.SetAttribute("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", XmlElementsIds.BodyId);
            var bodyId = body.GetAttributeNode("Id");
            bodyId.Prefix = "wsu";

            #endregion

            #region Agregar elementos a ser firmados al nodo Security



            securityNode.AppendChild(timestamp.GetXml(xmldoc));
            securityNode.AppendChild(binarySecurityTokenNode2);
            //agregar
            headerNode.AppendChild(securityNode);
            //el body ya existe, y no pertenece al nodo security.

            #endregion

            //Al momento de computar la firma, la clase SignedXml buscará las referencias previamente puestas, (las busca por los Id de cada uno
            //de los elementos a ser firmados.
            //y firmará los elementos que las referencias han referenciado
            //valga la redundancia.

            #region Crear firma XML


            //Ahora vamos a agregar un elemento Signature, que representa la firma digital.

            SignedXml signedXml = new SignedXmlWithId(xmldoc);

            signedXml.Signature.Id = "SIG-3";
            //la canonicalización indica como se deben interpretar los espacios en blanco y similares
            //porque el valor de firma puede cambiar inclusive cuando hayan espacios u otros caracteres-
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            //cual fue el algoritmo usado para firmar.
            signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url;

            //Cada una de las referencias apunta a un Id, que deberán tener los elementos
            //a ser firmados.


            System.Security.Cryptography.Xml.Reference reference = new System.Security.Cryptography.Xml.Reference
            {
                Uri = "#" + XmlElementsIds.PrivateKeyBinarySecurityTokenUri
            };
            reference.AddTransform(new XmlDsigExcC14NTransform(""));
            reference.DigestMethod = SignedXml.XmlDsigSHA1Url;

            System.Security.Cryptography.Xml.Reference reference2 = new System.Security.Cryptography.Xml.Reference
            {
                Uri = "#" + timestamp.Id
            };
            reference2.AddTransform(new XmlDsigExcC14NTransform("wsse lib soapenv"));
            reference2.DigestMethod = SignedXml.XmlDsigSHA1Url;

            System.Security.Cryptography.Xml.Reference reference3 = new System.Security.Cryptography.Xml.Reference
            {
                Uri = "#" + XmlElementsIds.BodyId
            };
            reference3.AddTransform(new XmlDsigExcC14NTransform("lib"));
            reference3.DigestMethod = SignedXml.XmlDsigSHA1Url;


            signedXml.SignedInfo.AddReference(reference);
            signedXml.SignedInfo.AddReference(reference2);
            signedXml.SignedInfo.AddReference(reference3);
            signedXml.SigningKey = certificadoPrivado.PrivateKey; //la clave privada para firmar.

            //La Keyinfo representa un identificador de un Token de seguridad.
            //en el caso de las firmas, identifica cómo encontrar el token que se usó para firmar.
            KeyInfo keyInfoInsideSignature = new KeyInfo();
            keyInfoInsideSignature.Id = "KI-D313N3M1G0";

            //en este caso Una referencia a un token de seguridad.
            SecurityTokenReference securityTokenReferenceInsideSignature = new SecurityTokenReference();
            securityTokenReferenceInsideSignature.Id        = "STR-SecurityTokenReference";
            securityTokenReferenceInsideSignature.ValueType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
            securityTokenReferenceInsideSignature.Reference = XmlElementsIds.PrivateKeyBinarySecurityTokenUri; //El BinarySecurityToken que contiene el Certificado x509v3 usado para la firma (usando su clave privada)
            KeyInfoClause keyInfoClauseInsideSignature = new KeyInfoNode(securityTokenReferenceInsideSignature.GetXml());
            keyInfoInsideSignature.AddClause(keyInfoClauseInsideSignature);

            signedXml.KeyInfo = keyInfoInsideSignature;


            signedXml.ComputeSignature();

            //revisar que la firma sea válida.(para propósitos de desarrollo)
            bool    firstcheck    = signedXml.CheckSignature(certificadoPrivado, true);
            XmlNode signatureNode = signedXml.GetXml(); //Finalmente ya obtenemos un elemento <signature> totalmente formado y listo para ser anexado al nodo <security>
            #endregion


            securityNode.AppendChild(signatureNode);



            #endregion

            #region Encriptar

            //Ahora vamos a obtener el certificado público, y usar su clave para encriptar el contenido del body

            Encriptar(ref xmldoc, "lib:quotationCarGenericRq", certificadopublico, ref securityNode);

            #endregion

            //Devolver un XML Firmado y Encriptado.
            #region testing, se puede dejar comentado:
            //HttpWebRequest req = (HttpWebRequest)WebRequest.Create("https://wsqa.libertycolombia.com.co:8443/soa-infra/services/GenericAuto/GenericAutoQuotation/GenericAutoQuotationMediator_ep");
            //req.Headers.Add("SOAPAction", "urn:quotationCarGeneric");
            //req.Method = "POST";
            //req.UserAgent = "Apache-HttpClient/4.1.1 (java 1.5)";
            //req.ContentType = "text/xml;charset=\"utf-8\"";
            //req.Host = "wsqa.libertycolombia.com.co:8443";

            ////XmlDocument xmldoctest = new XmlDocument();
            ////xmldoctest.Load(@"C:\Users\CarlosAlbertoFiguere\Desktop\test.xml");

            //using (Stream stream = req.GetRequestStream())
            //{
            //    using (StreamWriter streamWriter = new StreamWriter(stream))
            //    {
            //        streamWriter.Write(xmldoc.OuterXml);

            //    }

            //}
            //try
            //{
            //    WebResponse lol = req.GetResponse();
            //    string response = (new StreamReader(lol.GetResponseStream())).ReadToEnd();

            //}
            //catch (WebException wex)
            //{
            //    string response = (new StreamReader(wex.Response.GetResponseStream())).ReadToEnd();
            //}
            #endregion

            return(xmldoc);
        }
Пример #14
0
        /// <summary>
        /// Метод подписи XML подписью органа власти
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="certificate"></param>
        /// <returns></returns>
        private XmlDocument SignMessage2XX(XmlDocument xml, IntPtr certificate)
        {
            try
            {
                // Удаляем тэг Actor
                string message = string.Empty;

                try
                {
                    log.LogDebug("Пытаемся удалить атрибут 'Actor'.");
                    message = SoapDSigUtil.RemoveActor(xml);
                    log.LogDebug("Атрибут 'Actor' успешно удален.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке удалить атрибут 'Actor'. {ex.Message}.");
                }

                XmlDocument doc = new XmlDocument()
                {
                    PreserveWhitespace = true
                };

                try
                {
                    doc.LoadXml(message);
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при формировании XML после удаления атрибута 'Actor'. {ex.Message}.");
                }

                try
                {
                    log.LogDebug("Получаем значение тэга для подписи.");
                    this.tagForSign = this.FindSmevTagForSign(doc);
                    log.LogDebug($"Значение тэга для подписи получено. {tagForSign}.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке получить тэг с элементом для подписи. {ex.Message}.");
                }

                SmevSignedXml signedXml = new SmevSignedXml(doc);

                try
                {
                    log.LogDebug($"Выполняем добавление элемента Reference в XML.");

                    signedXml = (SmevSignedXml)SmevXmlHelper.AddReference(doc, signedXml, certificate,
                                                                          SignWithId,
                                                                          mrVersion,
                                                                          ElemForSign,
                                                                          ref idCounter,
                                                                          tagForSign,
                                                                          tagForSignNamespaceUri,
                                                                          namespaceIdAttr: NamespaceUri.OasisWSSecurityUtility
                                                                          );

                    log.LogDebug($"Добавление элемента Reference в XML выполнено успешно.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке добавить элемент Reference. {ex.Message}.");
                }

                signedXml.NamespaceForReference             = NamespaceUri.OasisWSSecurityUtility;
                signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;

                try
                {
                    log.LogDebug($"Пытаемся получить значение SignatureMethod.");
                    signedXml.SignedInfo.SignatureMethod = SignServiceUtils.GetSignatureMethod(SignServiceUtils.GetAlgId(certificate));
                    log.LogDebug($"Значение SignatureMethod успешно получено: {signedXml.SignedInfo.SignatureMethod}.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке получить значение метода подписи. {ex.Message}.");
                }

                XmlElement keyInfoElem        = doc.CreateElement("KeyInfo", NamespaceUri.WSXmlDSig);
                XmlElement binaryTokenElem    = doc.CreateElement("wsse", "BinarySecurityToken", NamespaceUri.OasisWSSecuritySecext);
                XmlElement tokenReferenceElem = doc.CreateElement("wsse", "SecurityTokenReference", NamespaceUri.OasisWSSecuritySecext);

                XmlElement referenceElem = doc.CreateElement("wsse", "Reference", NamespaceUri.OasisWSSecuritySecext);

                string       certId                = "uuid-" + Guid.NewGuid().ToString();
                XmlAttribute idAttr                = doc.CreateAttribute("u", "Id", NamespaceUri.OasisWSSecurityUtility);
                XmlAttribute valueTypeTokenAttr    = doc.CreateAttribute("ValueType");
                XmlAttribute encodingTypeTokenAttr = doc.CreateAttribute("EncodingType");

                idAttr.Value                = certId;
                valueTypeTokenAttr.Value    = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
                encodingTypeTokenAttr.Value = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary";

                binaryTokenElem.Attributes.Append((XmlAttribute)doc.ImportNode(idAttr, true));
                binaryTokenElem.Attributes.Append((XmlAttribute)doc.ImportNode(valueTypeTokenAttr, true));
                binaryTokenElem.Attributes.Append((XmlAttribute)doc.ImportNode(encodingTypeTokenAttr, true));

                X509Certificate2 cert = SignServiceUtils.GetX509Certificate2(certificate);
                binaryTokenElem.InnerText = Convert.ToBase64String(cert.RawData);

                XmlAttribute valueTypeAttr = doc.CreateAttribute("ValueType");
                valueTypeAttr.Value = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
                referenceElem.Attributes.Append((XmlAttribute)doc.ImportNode(valueTypeAttr, true));

                XmlAttribute uriAttr = doc.CreateAttribute("URI");
                uriAttr.Value = "#" + certId;

                referenceElem.Attributes.Append((XmlAttribute)doc.ImportNode(uriAttr, true));
                tokenReferenceElem.PrependChild(doc.ImportNode(referenceElem, true));
                keyInfoElem.PrependChild(doc.ImportNode(tokenReferenceElem, true));

                try
                {
                    KeyInfoNode keyNode = new KeyInfoNode(tokenReferenceElem);
                    KeyInfo     keyInfo = new KeyInfo();
                    keyInfo.AddClause(keyNode);
                    signedXml.KeyInfo = keyInfo;
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при формировании элемента KeyInfo. {ex.Message}.");
                }

                try
                {
                    log.LogDebug($"Пытаемся вычислить подпись.");
                    signedXml.ComputeSignatureWithoutPrivateKey(xmldsigPrefix, certificate);
                    log.LogDebug($"Вычисление подписи выполнено успешно.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке вычислить подпись для XML. {ex.Message}.");
                }

                XmlElement signatureElem = null;

                try
                {
                    log.LogDebug("Пытаемся получить элемент с подписью.");
                    signatureElem = signedXml.GetXml(xmldsigPrefix);
                    log.LogDebug("Элемент с подписью успешно получен.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке получить элемент содержащий подпись. {ex.Message}.");
                }

                try
                {
                    log.LogDebug("Пытаемся добавить подпись в XML содержимое.");
                    FillSignatureElement(doc, signatureElem, certificate, binaryTokenElem);
                    log.LogDebug("Подпись успешно добавлена.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке заполнить XML информацией о подписи. {ex.Message}.");
                }

                try
                {
                    log.LogDebug("Пытаемся добавить атрибут 'Actor'.");
                    SoapDSigUtil.AddActor(doc);
                    log.LogDebug("Атрибут 'Actor' успешно добавлен.");
                }
                catch (Exception ex)
                {
                    throw new Exception($"Ошибка при попытке добавить атрибут 'Actor'. {ex.Message}.");
                }

                return(doc);
            }
            catch (Exception ex)
            {
                log.LogError($"Ошибка при попытке подписать XML. {ex.Message}.");
                throw new CryptographicException($"Ошибка при попытке подписать XML для версии {mrText[mrVersion]}. {ex.Message}.");
            }
            finally
            {
                SignServiceUtils.FreeHandleCertificate(certificate);
            }
        }
Пример #15
0
        public XmlDocument SignMessage(XmlDocument xmlDoc)
        {
            var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);

            namespaceManager.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");
            namespaceManager.AddNamespace("u", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

            var soapHeaderNode = xmlDoc.DocumentElement?.SelectSingleNode("//s:Header", namespaceManager) as XmlElement;
            var bodyNode       = xmlDoc.DocumentElement?.SelectSingleNode("//s:Body", namespaceManager) as XmlElement;

            if (bodyNode == null)
            {
                throw new Exception("No body tag found.");
            }

            var uuid = $"id-{Guid.NewGuid()}";
            var uuidSecurityToken = $"id-{Guid.NewGuid()}";

            var timestamp = xmlDoc.CreateElement("u", "Timestamp", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            var created   = xmlDoc.CreateElement("u", "Created", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            var expires   = xmlDoc.CreateElement("u", "Expires", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

            timestamp.SetAttribute("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", uuidSecurityToken);
            created.InnerText = DateTime.Now.ToString("yyyy-MM-ddTHH':'mm':'ss'.'fffZ");
            expires.InnerText = DateTime.Now.AddMinutes(5).ToString("yyyy-MM-ddTHH':'mm':'ss'.'fffZ");
            timestamp.AppendChild(created);
            timestamp.AppendChild(expires);
            soapHeaderNode?.AppendChild(timestamp);

            var securityNode = xmlDoc.CreateElement(
                prefix: "o",
                localName: "Security",
                namespaceURI: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
                );

            securityNode.SetAttribute("mustUnderstand", "http://schemas.xmlsoap.org/soap/envelope/", "1");

            var binarySecurityTokenElement = xmlDoc.CreateElement("o", "BinarySecurityToken", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

            binarySecurityTokenElement.SetAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
            binarySecurityTokenElement.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
            binarySecurityTokenElement.SetAttribute("Id", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd", uuid);
            binarySecurityTokenElement.InnerText = SecurityToken;

            securityNode.AppendChild(binarySecurityTokenElement);
            soapHeaderNode?.AppendChild(securityNode);

            var signedXml = new SignedXmlWithId(xmlDoc);

            signedXml.SignedInfo.SignatureMethod = SignatureMethod;
            signedXml.SigningKey = RsaKey;

            var securityTokenRef = xmlDoc.CreateElement("o", "SecurityTokenReference", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            var oRef             = xmlDoc.CreateElement("o", "Reference", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

            oRef.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
            oRef.SetAttribute("URI", $"#{uuid}");
            securityTokenRef.AppendChild(oRef);

            var keyInfo     = new KeyInfo();
            var keyInfoData = new KeyInfoNode(securityTokenRef);

            keyInfo.AddClause(keyInfoData);
            signedXml.KeyInfo = keyInfo;
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;

            var reference = new Reference
            {
                Uri          = $"#{uuid}",
                DigestMethod = DigestMethod
            };

            reference.AddTransform(new XmlDsigExcC14NTransform());
            signedXml.AddReference(reference);
            signedXml.ComputeSignature();

            var signedElement = signedXml.GetXml();

            securityNode.AppendChild(signedElement);
            return(xmlDoc);
        }