2009-12-13 103 views
0

我需要建議。我在Web服務和客戶端上壓縮和隱藏SOAP消息。壓縮和加密SOAP - ASP.NET web服務

客戶端是winforms應用程序。

如果我只隱藏SOAP消息,它的效果很好。

如果我只壓縮SOAP消息,它也很好。

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

我使用AES - 高級加密標準 - Rijndael和compresion我使用SharpZipLib從http://sourceforge.net/projects/sharpdevelop/

問題是我在客戶端發送數據集。

  1. 首先,我在zip服務端對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; 
    } 

strong text

+1

爲什麼不直接使用WCF來完成這一切? – 2010-01-24 19:56:43

回答

1

我不知道爲什麼你的未加密的XML不會解析,但我認爲你的第一步應該是將解密的數據轉儲到終端看到你正在回來的文字。也許這個過程破壞你的數據,或者你有一個編碼問題。

或者,您可以將服務器配置爲使用httpsgzip compression來實現相同的目標。用這種方法你不會失去任何安全性,這是迄今爲止更爲標準的做事方式。你也可以看看MS對WS-Security標準的支持