예제 #1
0
        public static bool CheckSignature(XmlDocument doc)
        {
            var nodeList = doc.GetElementsByTagName(
                "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

            for (var curSignature = 0; curSignature < nodeList.Count; curSignature++)
            {
                // Создаем объект SignedXml для проверки подписи документа.
                var signedXml = new SmevSignedXml(doc);

                // Вытаскиваем сертификат из подписи
                var certificateNode = ((XmlElement)(nodeList[curSignature])).GetElementsByTagName("BinarySecurityToken",
                                                                                                  "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
                var rawCertData = Convert.FromBase64String(certificateNode[0].InnerText);
                var certificate = new X509Certificate2(rawCertData);

                var signature = ((XmlElement)nodeList[curSignature]).GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl)[0];
                signedXml.LoadXml((XmlElement)signature);



                // Проверяем подпись
                var result = signedXml.CheckSignature(certificate, false);

                if (!result)
                {
                    return(false);
                }
            }

            return(true);
        }
예제 #2
0
        public static bool CheckSignature(XmlDocument doc)
        {
            var nodeList = doc.GetElementsByTagName(
               "Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");

            for (var curSignature = 0; curSignature < nodeList.Count; curSignature++)
            {
                // Создаем объект SignedXml для проверки подписи документа.
                var signedXml = new SmevSignedXml(doc);

                // Вытаскиваем сертификат из подписи
                var certificateNode = ((XmlElement)(nodeList[curSignature])).GetElementsByTagName("BinarySecurityToken",
                                                                                               "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
                var rawCertData = Convert.FromBase64String(certificateNode[0].InnerText);
                var certificate = new X509Certificate2(rawCertData);

                var signature = ((XmlElement)nodeList[curSignature]).GetElementsByTagName("Signature", SignedXml.XmlDsigNamespaceUrl)[0];
                signedXml.LoadXml((XmlElement)signature);

                // Проверяем подпись
                var result = signedXml.CheckSignature(certificate, false);

                if (!result)
                    return false;
            }

            return true;
        }
예제 #3
0
        public static string SignMessage(string message, string certificateID, X509Certificate2 certificate)
        {
            var document = new XmlDocument
            {
                PreserveWhitespace = false
            };

            document.LoadXml(message);

            // Добавляем XmlDeclaration -не думаю что это необходимо
            if (!(document.FirstChild is XmlDeclaration))
            {
                var declaration = document.CreateXmlDeclaration("1.0", "UTF-8", string.Empty);
                document.InsertBefore(declaration, document.FirstChild);
            }

            // Добавляем необходимые неймспейсы
            var ns = new XmlNamespaceManager(document.NameTable);

            ns.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");
            var envelope = document.DocumentElement.SelectSingleNode(@"//s:Envelope", ns) as XmlElement;

            if (envelope == null)
            {
                throw new ApplicationException("Не найден тэг Envelope");
            }
            envelope.SetAttribute("xmlns:wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            envelope.SetAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            envelope.SetAttribute("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#");

            // Ищем body и добавляем ему wsu:Id
            var body = document.DocumentElement.SelectSingleNode(@"//s:Body", ns) as XmlElement;

            if (body == null)
            {
                throw new ApplicationException("Не найден тэг Body");
            }
            body.RemoveAllAttributes();
            var id = document.CreateAttribute("wsu", "Id",
                                              "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

            id.InnerText = "body";
            body.Attributes.Append(id);

            // Получаем подпись
            var mySignedXml = new SmevSignedXml(document)
            {
                SigningKey = certificate.PrivateKey
            };
            var reference = new Reference
            {
                Uri          = "#body",
                DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#gostr3411"
            };
            var excC14Ntransform = new XmlDsigExcC14NTransform();

            reference.AddTransform(excC14Ntransform);
            mySignedXml.AddReference(reference);
            var keyInfo = new KeyInfo();

            keyInfo.AddClause(new KeyInfoX509Data(certificate));
            mySignedXml.KeyInfo = keyInfo;
            mySignedXml.SignedInfo.CanonicalizationMethod = excC14Ntransform.Algorithm;
            mySignedXml.SignedInfo.SignatureMethod        = "http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411";
            mySignedXml.ComputeSignature("ds");

            // Вставляем подпись в сообщение
            var namespaceManager = GetNewFilledNamespaceManager(document.NameTable);

            document.SelectSingleNode("/s:Envelope", namespaceManager).InsertBefore(document.CreateNode(XmlNodeType.Element, "s", "Header", namespaceManager.LookupNamespace("s")), document.SelectSingleNode("/s:Envelope/s:Body", namespaceManager));
            document.SelectSingleNode("/s:Envelope/s:Header", namespaceManager).AppendChild(document.CreateNode(XmlNodeType.Element, "wsse", "Security", namespaceManager.LookupNamespace("wsse"))).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "s", "actor", namespaceManager.LookupNamespace("s"))).InnerText = "http://smev.gosuslugi.ru/actors/smev";
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security", namespaceManager).AppendChild(document.CreateNode(XmlNodeType.Element, "wsse", "BinarySecurityToken", namespaceManager.LookupNamespace("wsse")));
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security", namespaceManager).AppendChild(document.CreateNode(XmlNodeType.Element, "ds", "Signature", namespaceManager.LookupNamespace("ds")));
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/wsse:BinarySecurityToken", namespaceManager).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "EncodingType", "")).InnerText = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary";
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/wsse:BinarySecurityToken", namespaceManager).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "ValueType", "")).InnerText    = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/wsse:BinarySecurityToken", namespaceManager).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "wsu", "Id", namespaceManager.LookupNamespace("wsu"))).InnerText = certificateID;
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/wsse:BinarySecurityToken", namespaceManager).InnerText = mySignedXml.GetXml("ds").SelectSingleNode("/ds:KeyInfo/ds:X509Data/ds:X509Certificate", namespaceManager).InnerText;
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/ds:Signature", namespaceManager).AppendChild(document.ImportNode(mySignedXml.GetXml("ds").SelectSingleNode("/ds:SignedInfo", namespaceManager), true));
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/ds:Signature", namespaceManager).AppendChild(document.ImportNode(mySignedXml.GetXml("ds").SelectSingleNode("/ds:SignatureValue", namespaceManager), true));
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/ds:Signature", namespaceManager).AppendChild(document.CreateNode(XmlNodeType.Element, "ds", "KeyInfo", namespaceManager.LookupNamespace("ds"))).AppendChild(document.CreateNode(XmlNodeType.Element, "wsse", "SecurityTokenReference", namespaceManager.LookupNamespace("wsse"))).AppendChild(document.CreateNode(XmlNodeType.Element, "wsse", "Reference", namespaceManager.LookupNamespace("wsse"))).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "URI", "")).InnerText = "#" + certificateID;
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/ds:Signature/ds:KeyInfo/wsse:SecurityTokenReference/wsse:Reference", namespaceManager).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "ValueType", "")).InnerText = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";

            message = document.OuterXml;
            message = message.Replace("<s:Header />", "");
            return(message);
        }
예제 #4
0
        public static string SignMessage(string message, string certificateID, X509Certificate2 certificate)
        {
            var document = new XmlDocument
            {
                PreserveWhitespace = false
            };
            document.LoadXml(message);

            // Добавляем XmlDeclaration -не думаю что это необходимо
            if (!(document.FirstChild is XmlDeclaration))
            {
                var declaration = document.CreateXmlDeclaration("1.0", "UTF-8", string.Empty);
                document.InsertBefore(declaration, document.FirstChild);
            }

            // Добавляем необходимые неймспейсы
            var ns = new XmlNamespaceManager(document.NameTable);
            ns.AddNamespace("s", "http://schemas.xmlsoap.org/soap/envelope/");
            var envelope = document.DocumentElement.SelectSingleNode(@"//s:Envelope", ns) as XmlElement;
            if (envelope == null)
            {
                throw new ApplicationException("Не найден тэг Envelope");
            }
            envelope.SetAttribute("xmlns:wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
            envelope.SetAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            envelope.SetAttribute("xmlns:ds", "http://www.w3.org/2000/09/xmldsig#");

            // Ищем body и добавляем ему wsu:Id
            var body = document.DocumentElement.SelectSingleNode(@"//s:Body", ns) as XmlElement;
            if (body == null)
                throw new ApplicationException("Не найден тэг Body");
            body.RemoveAllAttributes();
            var id = document.CreateAttribute("wsu", "Id",
                                                      "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
            id.InnerText = "body";
            body.Attributes.Append(id);

            // Получаем подпись
            var mySignedXml = new SmevSignedXml(document)
            {
                SigningKey = certificate.PrivateKey
            };
            var reference = new Reference
            {
                Uri = "#body",
                DigestMethod = "http://www.w3.org/2001/04/xmldsig-more#gostr3411"
            };
            var excC14Ntransform = new XmlDsigExcC14NTransform();
            reference.AddTransform(excC14Ntransform);
            mySignedXml.AddReference(reference);
            var keyInfo = new KeyInfo();
            keyInfo.AddClause(new KeyInfoX509Data(certificate));
            mySignedXml.KeyInfo = keyInfo;
            mySignedXml.SignedInfo.CanonicalizationMethod = excC14Ntransform.Algorithm;
            mySignedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#gostr34102001-gostr3411";
            mySignedXml.ComputeSignature("ds");

            // Вставляем подпись в сообщение
            var namespaceManager = GetNewFilledNamespaceManager(document.NameTable);
            document.SelectSingleNode("/s:Envelope", namespaceManager).InsertBefore(document.CreateNode(XmlNodeType.Element, "s", "Header", namespaceManager.LookupNamespace("s")), document.SelectSingleNode("/s:Envelope/s:Body", namespaceManager));
            document.SelectSingleNode("/s:Envelope/s:Header", namespaceManager).AppendChild(document.CreateNode(XmlNodeType.Element, "wsse", "Security", namespaceManager.LookupNamespace("wsse"))).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "s", "actor", namespaceManager.LookupNamespace("s"))).InnerText = "http://smev.gosuslugi.ru/actors/smev";
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security", namespaceManager).AppendChild(document.CreateNode(XmlNodeType.Element, "wsse", "BinarySecurityToken", namespaceManager.LookupNamespace("wsse")));
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security", namespaceManager).AppendChild(document.CreateNode(XmlNodeType.Element, "ds", "Signature", namespaceManager.LookupNamespace("ds")));
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/wsse:BinarySecurityToken", namespaceManager).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "EncodingType", "")).InnerText = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary";
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/wsse:BinarySecurityToken", namespaceManager).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "ValueType", "")).InnerText = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/wsse:BinarySecurityToken", namespaceManager).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "wsu", "Id", namespaceManager.LookupNamespace("wsu"))).InnerText = certificateID;
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/wsse:BinarySecurityToken", namespaceManager).InnerText = mySignedXml.GetXml("ds").SelectSingleNode("/ds:KeyInfo/ds:X509Data/ds:X509Certificate", namespaceManager).InnerText;
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/ds:Signature", namespaceManager).AppendChild(document.ImportNode(mySignedXml.GetXml("ds").SelectSingleNode("/ds:SignedInfo", namespaceManager), true));
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/ds:Signature", namespaceManager).AppendChild(document.ImportNode(mySignedXml.GetXml("ds").SelectSingleNode("/ds:SignatureValue", namespaceManager), true));
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/ds:Signature", namespaceManager).AppendChild(document.CreateNode(XmlNodeType.Element, "ds", "KeyInfo", namespaceManager.LookupNamespace("ds"))).AppendChild(document.CreateNode(XmlNodeType.Element, "wsse", "SecurityTokenReference", namespaceManager.LookupNamespace("wsse"))).AppendChild(document.CreateNode(XmlNodeType.Element, "wsse", "Reference", namespaceManager.LookupNamespace("wsse"))).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "URI", "")).InnerText = "#" + certificateID;
            document.SelectSingleNode("/s:Envelope/s:Header/wsse:Security/ds:Signature/ds:KeyInfo/wsse:SecurityTokenReference/wsse:Reference", namespaceManager).Attributes.SetNamedItem(document.CreateNode(XmlNodeType.Attribute, "ValueType", "")).InnerText = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";

            message = document.OuterXml;
            message = message.Replace("<s:Header />", "");
            return message;
        }