压缩和加密 SOAP - ASP.NET Web 服务

发布于 2024-08-14 18:22:01 字数 8765 浏览 4 评论 0原文

我需要建议。我在 Web 服务和客户端上压缩和加密 SOAP 消息。

客户端是winforms应用程序。

如果我只加密 SOAP 消息,效果很好。

如果我只压缩 SOAP 消息,它也可以很好地工作。

我在 crypt 和 zip SOAP 上使用 SOAP 扩展。

我使用 AES - 高级加密标准 - Rijndael 并在压缩时使用 http://sourceforge.net/projects 中的 SharpZipLib /sharpdevelop/

问题是我在客户端发送数据集。

  1. 首先,我在 Web 服务端压缩并加密 SOAP。

  2. 在客户端上发送。

  3. 在客户端,我从流加载 XML。但它以这个错误结束: 根级别的数据无效。第 1 行,位置 2234。

这是代码,我在其中从流加载 XML:

        var doc = new XmlDocument();
        using (var reader = new XmlTextReader(inputStream))
        {
            doc.Load(reader);
        }

有什么建议吗?谢谢...

以下是Web服务端压缩和加密SOAP的方法:

    //encrypt string
    private static string EncryptString(string @string, string initialVector, string salt, string password,
                         string hashAlgorithm, int keySize, int passwordIterations)
    {
        byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector);
        byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(@string);

        var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations);
        byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);
        var symmetricKey = new RijndaelManaged();
        symmetricKey.Mode = CipherMode.CBC;
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initialVectorBytes);

        using (var memStream = new MemoryStream())
        {
            var cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write);
            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
            cryptoStream.FlushFinalBlock();

            var serializer = new XmlSerializer(typeof(byte[]));
            var sb = new StringBuilder();
            TextWriter writer = new StringWriter(sb);
            serializer.Serialize(writer, memStream.ToArray());
            writer.Flush();

            var doc = new XmlDocument();
            doc.LoadXml(sb.ToString());
            if (doc.DocumentElement != null) return doc.DocumentElement.InnerXml;
        }
        return "";
    }

    //zip string
    private static byte[] ZipArray(string stringToZip)
    {
        byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToZip);
        var ms = new MemoryStream();

        // SharpZipLib.Zip,
        var zipOut = new ZipOutputStream(ms);
        var zipEntry = new ZipEntry("ZippedFile");
        zipOut.PutNextEntry(zipEntry);


        zipOut.SetLevel(7);
        zipOut.Write(inputByteArray, 0, inputByteArray.Length);
        zipOut.Finish();
        zipOut.Close();

        return ms.ToArray();
    }


    //zip and encrypt SOAP
    public virtual Stream OutSoap(string[] soapElement, Stream inputStream)
    {

            #region Load XML from SOAP

            var doc = new XmlDocument();

            using (XmlReader reader = XmlReader.Create(inputStream))
            {
                doc.Load(reader);
            }

            var nsMan = new XmlNamespaceManager(doc.NameTable);
            nsMan.AddNamespace("soap",
                               "http://schemas.xmlsoap.org/soap/envelope/");

            #endregion Load XML from SOAP

            #region Zip SOAP

            XmlNode bodyNode = doc.SelectSingleNode(@"//soap:Body", nsMan);

            bodyNode = bodyNode.FirstChild.FirstChild;

            while (bodyNode != null)
            {
                if (bodyNode.InnerXml.Length > 0)
                {
                    // Zip
                    byte[] outData = ZipArray(bodyNode.InnerXml);

                    bodyNode.InnerXml = Convert.ToBase64String(outData);

                }
                bodyNode = bodyNode.NextSibling;
            }

            #endregion Zip SOAP

            #region Crypt SOAP

            foreach (string xPathQuery in soapElement)
            {
                XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
                if (nodesToEncrypt != null)
                    foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
                    {
                        //Encrypt
                        nodeToEncrypt.InnerXml = EncryptString(nodeToEncrypt.InnerXml,
                                                               user.IV, user.Salt, user.Password, user.HashType,
                                                               user.KeySize, user.PasswordIterations);
                    }
            }

            #endregion Crypt SOAP

            inputStream.Position = 0;
            var settings = new XmlWriterSettings { Encoding = Encoding.UTF8 };
            using (XmlWriter writer = XmlWriter.Create(inputStream, settings))
            {

                 doc.WriteTo(writer);
                 return inputStream;
            }

    }

这是客户端解密和uzip SOAP的代码:

   //decrypt string
   private static string DecryptString(string @string, string initialVector, string salt, string password,
                         string hashAlgorithm, int keySize, int passwordIterations)
    {
        byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector);
        byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
        byte[] cipherTextBytes = Convert.FromBase64String(@string);

        var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations);
        byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);
        var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC };
        ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initialVectorBytes);

        using (var memStream = new MemoryStream(cipherTextBytes))
        {
            var cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read);

            var plainTextBytes = new byte[cipherTextBytes.Length];
            int byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);

            return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);
        }
    }


    //unzip string
    private static byte[] UnzipArray(string stringToUnzip)
    {

        byte[] inputByteArray = Convert.FromBase64String(stringToUnzip);
        var ms = new MemoryStream(inputByteArray);
        var ret = new MemoryStream();

        // SharpZipLib.Zip
        var zipIn = new ZipInputStream(ms);
        var theEntry = zipIn.GetNextEntry();
        var buffer = new Byte[2048];
        int size = 2048;

        while (true)
        {
            size = zipIn.Read(buffer, 0, buffer.Length);
            if (size > 0)
            {
                ret.Write(buffer, 0, size);
            }
            else
            {
                break;
            }
        }
        return ret.ToArray();
    }


    public virtual Stream  InSoap(Stream inputStream, string[] soapElement)
    {

        #region Load XML from SOAP

        var doc = new XmlDocument();
        using (var reader = new XmlTextReader(inputStream))
        {
            doc.Load(reader);
        }
        var nsMan = new XmlNamespaceManager(doc.NameTable);
        nsMan.AddNamespace("soap",
                           "http://schemas.xmlsoap.org/soap/envelope/");

        #endregion Load XML from SOAP


        #region Decrypt SOAP

        foreach (string xPathQuery in soapElement)
            {
                XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
                if (nodesToEncrypt != null)
                    foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
                    {
                        nodeToEncrypt.InnerXml = DecryptString(nodeToEncrypt.InnerXml, saltPhrase, passwordPhrase, initialVector,
                                          hashAlgorithm, passwordIterations, keySize);
                    }
            }

         #endregion Decrypt SOAP

         #region UnZip SOAP

         XmlNode node = doc.SelectSingleNode("//soap:Body", nsMan);
         node = node.FirstChild.FirstChild;


         while (node != null)
            {
                if (node.InnerXml.Length > 0)
                {

                    byte[] outData = UnzipArray(node.InnerXml);
                    string sTmp = Encoding.UTF8.GetString(outData);

                    node.InnerXml = sTmp;
                }

                node = node.NextSibling;
            }

         #endregion UnZip SOAP

        var retStream = new MemoryStream();
        doc.Save(retStream);
        return retStream;
    }

强文本

I need advice. I zip and crypt SOAP message on web service and client side.

Client is winforms app.

If I only crypt SOAP message, it works good.

If I only zip SOAP message it also works good.

I use SOAP extension on crypt and zip SOAP.

I use AES - Advanced Encryption Standard - Rijndael and on compresion I use SharpZipLib from http://sourceforge.net/projects/sharpdevelop/.

The problem is I send dataset on client.

  1. Firstly I zip and secondly encrypt SOAP on web service side.

  2. Send on client.

  3. On client side I load XML from stream. But it finish with this error :
    Data at the root level is invalid. Line 1, position 2234.

Here is the code, where I load XML from stream:

        var doc = new XmlDocument();
        using (var reader = new XmlTextReader(inputStream))
        {
            doc.Load(reader);
        }

Any advice ? Thank you...

Here are methods on web service side which zip and crypt SOAP :

    //encrypt string
    private static string EncryptString(string @string, string initialVector, string salt, string password,
                         string hashAlgorithm, int keySize, int passwordIterations)
    {
        byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector);
        byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(@string);

        var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations);
        byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);
        var symmetricKey = new RijndaelManaged();
        symmetricKey.Mode = CipherMode.CBC;
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initialVectorBytes);

        using (var memStream = new MemoryStream())
        {
            var cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write);
            cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
            cryptoStream.FlushFinalBlock();

            var serializer = new XmlSerializer(typeof(byte[]));
            var sb = new StringBuilder();
            TextWriter writer = new StringWriter(sb);
            serializer.Serialize(writer, memStream.ToArray());
            writer.Flush();

            var doc = new XmlDocument();
            doc.LoadXml(sb.ToString());
            if (doc.DocumentElement != null) return doc.DocumentElement.InnerXml;
        }
        return "";
    }

    //zip string
    private static byte[] ZipArray(string stringToZip)
    {
        byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToZip);
        var ms = new MemoryStream();

        // SharpZipLib.Zip,
        var zipOut = new ZipOutputStream(ms);
        var zipEntry = new ZipEntry("ZippedFile");
        zipOut.PutNextEntry(zipEntry);


        zipOut.SetLevel(7);
        zipOut.Write(inputByteArray, 0, inputByteArray.Length);
        zipOut.Finish();
        zipOut.Close();

        return ms.ToArray();
    }


    //zip and encrypt SOAP
    public virtual Stream OutSoap(string[] soapElement, Stream inputStream)
    {

            #region Load XML from SOAP

            var doc = new XmlDocument();

            using (XmlReader reader = XmlReader.Create(inputStream))
            {
                doc.Load(reader);
            }

            var nsMan = new XmlNamespaceManager(doc.NameTable);
            nsMan.AddNamespace("soap",
                               "http://schemas.xmlsoap.org/soap/envelope/");

            #endregion Load XML from SOAP

            #region Zip SOAP

            XmlNode bodyNode = doc.SelectSingleNode(@"//soap:Body", nsMan);

            bodyNode = bodyNode.FirstChild.FirstChild;

            while (bodyNode != null)
            {
                if (bodyNode.InnerXml.Length > 0)
                {
                    // Zip
                    byte[] outData = ZipArray(bodyNode.InnerXml);

                    bodyNode.InnerXml = Convert.ToBase64String(outData);

                }
                bodyNode = bodyNode.NextSibling;
            }

            #endregion Zip SOAP

            #region Crypt SOAP

            foreach (string xPathQuery in soapElement)
            {
                XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
                if (nodesToEncrypt != null)
                    foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
                    {
                        //Encrypt
                        nodeToEncrypt.InnerXml = EncryptString(nodeToEncrypt.InnerXml,
                                                               user.IV, user.Salt, user.Password, user.HashType,
                                                               user.KeySize, user.PasswordIterations);
                    }
            }

            #endregion Crypt SOAP

            inputStream.Position = 0;
            var settings = new XmlWriterSettings { Encoding = Encoding.UTF8 };
            using (XmlWriter writer = XmlWriter.Create(inputStream, settings))
            {

                 doc.WriteTo(writer);
                 return inputStream;
            }

    }

Here is a code on client side which decrypt and uzip SOAP :

   //decrypt string
   private static string DecryptString(string @string, string initialVector, string salt, string password,
                         string hashAlgorithm, int keySize, int passwordIterations)
    {
        byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector);
        byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt);
        byte[] cipherTextBytes = Convert.FromBase64String(@string);

        var derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations);
        byte[] keyBytes = derivedPassword.GetBytes(keySize / 8);
        var symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC };
        ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initialVectorBytes);

        using (var memStream = new MemoryStream(cipherTextBytes))
        {
            var cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read);

            var plainTextBytes = new byte[cipherTextBytes.Length];
            int byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);

            return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount);
        }
    }


    //unzip string
    private static byte[] UnzipArray(string stringToUnzip)
    {

        byte[] inputByteArray = Convert.FromBase64String(stringToUnzip);
        var ms = new MemoryStream(inputByteArray);
        var ret = new MemoryStream();

        // SharpZipLib.Zip
        var zipIn = new ZipInputStream(ms);
        var theEntry = zipIn.GetNextEntry();
        var buffer = new Byte[2048];
        int size = 2048;

        while (true)
        {
            size = zipIn.Read(buffer, 0, buffer.Length);
            if (size > 0)
            {
                ret.Write(buffer, 0, size);
            }
            else
            {
                break;
            }
        }
        return ret.ToArray();
    }


    public virtual Stream  InSoap(Stream inputStream, string[] soapElement)
    {

        #region Load XML from SOAP

        var doc = new XmlDocument();
        using (var reader = new XmlTextReader(inputStream))
        {
            doc.Load(reader);
        }
        var nsMan = new XmlNamespaceManager(doc.NameTable);
        nsMan.AddNamespace("soap",
                           "http://schemas.xmlsoap.org/soap/envelope/");

        #endregion Load XML from SOAP


        #region Decrypt SOAP

        foreach (string xPathQuery in soapElement)
            {
                XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
                if (nodesToEncrypt != null)
                    foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
                    {
                        nodeToEncrypt.InnerXml = DecryptString(nodeToEncrypt.InnerXml, saltPhrase, passwordPhrase, initialVector,
                                          hashAlgorithm, passwordIterations, keySize);
                    }
            }

         #endregion Decrypt SOAP

         #region UnZip SOAP

         XmlNode node = doc.SelectSingleNode("//soap:Body", nsMan);
         node = node.FirstChild.FirstChild;


         while (node != null)
            {
                if (node.InnerXml.Length > 0)
                {

                    byte[] outData = UnzipArray(node.InnerXml);
                    string sTmp = Encoding.UTF8.GetString(outData);

                    node.InnerXml = sTmp;
                }

                node = node.NextSibling;
            }

         #endregion UnZip SOAP

        var retStream = new MemoryStream();
        doc.Save(retStream);
        return retStream;
    }

strong text

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

流殇 2024-08-21 18:22:01

我不确定为什么你的未加密的 xml 无法解析,但我认为你的第一步应该是将解密的数据转储到终端,以准确查看你返回的文本。也许该过程会以某种方式损坏您的数据,或者您遇到编码问题。

或者,您可以将服务器配置为使用 httpsgzip 压缩 来实现相同的目标。使用这种方法您不会失去任何安全性,这是迄今为止更标准的做事方法。您还可以查看 MS 对 WS-Security 的支持标准

I'm not sure why your unencrypted xml won't parse, but I think you're first step should be to dump the decrypted data to the terminal to see exactly what text you're getting back. Perhaps the process corrupts your data somehow, or you have an encoding issue.

Alternatively, you could configure your server to use https and gzip compression to achieve the same goal. You won't loose any security with this approach and this is by far the more standard way to do things. You can also have a look at MS's support for the WS-Security standard

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文