0

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

客户端是winforms 应用程序。

如果我只加密 SOAP 消息,它工作得很好。

如果我只压缩 SOAP 消息,它也很好用。

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

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

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

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

  2. 在客户端发送。

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

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

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

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

以下是 zip 和 crypt SOAP 的 Web 服务端方法:

    //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;
    }

强文本

4

1 回答 1

1

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

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

于 2009-12-13T16:43:28.317 回答