带有 Soap 扩展的 ASMX Web 服务 - 加密方法问题

发布于 2024-08-07 12:24:35 字数 3289 浏览 8 评论 0原文

我尝试在 ASP.NET Web 服务中发送和加密 SOAP 消息。

//I have Crypt class, which input parameters is Stream:
public class CryptUtility
 {
      public virtual Stream EncryptAndSingXml (Stream inputStream)
      {
         XmlTextReader reader = new XmlTextReader(inputStream);
         XmlDocument doc = new XmlDocument();
         doc.Load(reader);

         // in this place I encrypt and sign SOAP message
         foreach (string xPathQuery in soapElement)
          {
          XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
            foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
              {
                // method EncryptString crypt only string from XmlNode
                nodeToEncrypt.InnerXml = EncryptString();
              }
           }

         // !!!
         //               I        THINK  HERE IS A PROBLEM 
         //
         //it return plain stream, no encrypt stream
         MemoryStream retStream = new MemoryStream();
         XmlTextWriter writer = new XmlTextWriter(retStream, Encoding.UTF8);
         doc.Save(retStream);
         return retStream;
      }
 }

我在 Soap 扩展类中使用了 CryptUtility 对象:

public class SoapMsg : SoapExtension
 {
     private CryptUtility cryptUtil; //this object crypt and sing SOAP message
     //  ...

     //this method copy stream
     private void CopyStream(Stream from, Stream to)
     {
     TextReader reader = new StreamReader(from);
     TextWriter writer = new StreamWriter(to);
     writer.Write(reader.ReadToEnd());
     writer.Flush();
     }

     //this method sing and encrypt SOAP message, I call this method in stage  AfterSerialize
     private void CryptMessage()
     {
     newStream.Position = 0;
     Stream retStream = cryptUtil.EncryptAndSingXml(newStream);
     retStream.Position = 0;
     CopyStream(retStream, oldStream);
     }

     public override void ProcessMessage(SoapMessage message)
     {
       switch (message.Stage)
         {
           case SoapMessageStage.BeforeSerialize:
              break;
           case SoapMessageStage.AfterSerialize:
           {
           // call the crypt and sing method
           CryptMessage();
           //save the SOAP message, the message is not encrypt
           Log(message, "AfterSerialize");
           }
             break;
           case SoapMessageStage.BeforeDeserialize:
              break;
           case SoapMessageStage.AfterDeserialize:
               break;
            default:
              throw new ArgumentException("error.");
           }

        }
     // ...
 }

问题是,当我在 AfterDeserialize 中记录 SOAP 消息时,XML 是纯文本,但应该加密 有人可以帮助我,哪里可能有问题,或者我可以做什么坏事?

因为首先我在 SoapMsg 类中使用 EncryptAndSingXml 方法作为 void,并且它工作正常!!! 像这样的东西:

 public class SoapMsg : SoapExtension
 {
 //...
      public void EncryptAndSingXml()
      {...}
 //...
     public override void ProcessMessage(SoapMessage message)
     {
       switch (message.Stage)
         {
           //...
           case SoapMessageStage.AfterSerialize:
           EncryptAndSingXml();
               break;
           //...
        }
     // ...
 }

但是当我将c类CryptUtility和方法EncryptAndSingXml()设置为虚拟时它不起作用。 :( 有人可以帮助我吗?

I try sing and encrypt SOAP message in ASP.NET Web Service.

//I have Crypt class, which input parameters is Stream:
public class CryptUtility
 {
      public virtual Stream EncryptAndSingXml (Stream inputStream)
      {
         XmlTextReader reader = new XmlTextReader(inputStream);
         XmlDocument doc = new XmlDocument();
         doc.Load(reader);

         // in this place I encrypt and sign SOAP message
         foreach (string xPathQuery in soapElement)
          {
          XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
            foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
              {
                // method EncryptString crypt only string from XmlNode
                nodeToEncrypt.InnerXml = EncryptString();
              }
           }

         // !!!
         //               I        THINK  HERE IS A PROBLEM 
         //
         //it return plain stream, no encrypt stream
         MemoryStream retStream = new MemoryStream();
         XmlTextWriter writer = new XmlTextWriter(retStream, Encoding.UTF8);
         doc.Save(retStream);
         return retStream;
      }
 }

I used CryptUtility object in Soap extension class:

public class SoapMsg : SoapExtension
 {
     private CryptUtility cryptUtil; //this object crypt and sing SOAP message
     //  ...

     //this method copy stream
     private void CopyStream(Stream from, Stream to)
     {
     TextReader reader = new StreamReader(from);
     TextWriter writer = new StreamWriter(to);
     writer.Write(reader.ReadToEnd());
     writer.Flush();
     }

     //this method sing and encrypt SOAP message, I call this method in stage  AfterSerialize
     private void CryptMessage()
     {
     newStream.Position = 0;
     Stream retStream = cryptUtil.EncryptAndSingXml(newStream);
     retStream.Position = 0;
     CopyStream(retStream, oldStream);
     }

     public override void ProcessMessage(SoapMessage message)
     {
       switch (message.Stage)
         {
           case SoapMessageStage.BeforeSerialize:
              break;
           case SoapMessageStage.AfterSerialize:
           {
           // call the crypt and sing method
           CryptMessage();
           //save the SOAP message, the message is not encrypt
           Log(message, "AfterSerialize");
           }
             break;
           case SoapMessageStage.BeforeDeserialize:
              break;
           case SoapMessageStage.AfterDeserialize:
               break;
            default:
              throw new ArgumentException("error.");
           }

        }
     // ...
 }

Problem is, when I log SOAP message in AfterDeserialize the XML is plain text, but it should be encrypt
Can somebody help me, where can be problem , or what can I do bad?

Because first I use method EncryptAndSingXml as void in class SoapMsg, and it work correct!!!
Something like this :

 public class SoapMsg : SoapExtension
 {
 //...
      public void EncryptAndSingXml()
      {...}
 //...
     public override void ProcessMessage(SoapMessage message)
     {
       switch (message.Stage)
         {
           //...
           case SoapMessageStage.AfterSerialize:
           EncryptAndSingXml();
               break;
           //...
        }
     // ...
 }

But when I makec class CryptUtility and method EncryptAndSingXml() as virtual it doesn't work. :(
Can somebody help me ?

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

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

发布评论

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

评论(1

香草可樂 2024-08-14 12:24:35

看起来您根本没有修改 message

并且,请显示您在何处创建 CryptUtility 实例。

另外,你的代码很糟糕。试试这个:

public class CryptUtility
{
    public virtual Stream EncryptAndSingXml(Stream inputStream, IEnumerable<string> soapElement)
    {
        XmlDocument doc = new XmlDocument();
        using (XmlReader reader = XmlReader.Create(inputStream))
        {
            doc.Load(reader);
        }

        // in this place I encrypt and sign SOAP message
        XmlNamespaceManager nsMan = new XmlNamespaceManager(doc.NameTable);
        foreach (string xPathQuery in soapElement)
        {
            XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
            foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
            {
                // method EncryptString crypt only string from XmlNode
                nodeToEncrypt.InnerXml = EncryptString(nodeToEncrypt.InnerXml);
            }
        }

        // !!!
        //               I        THINK  HERE IS A PROBLEM 
        //
        //it return plain stream, no encrypt stream
        using (MemoryStream retStream = new MemoryStream())
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = Encoding.UTF8;
            using (XmlWriter writer = XmlWriter.Create(retStream, settings))
            {
                doc.WriteTo(writer);
            }
            return retStream;
        }
    }
}

public class SoapMsg : SoapExtension
{
    private CryptUtility cryptUtil; //this object crypt and sing SOAP message
    //  ...

    //this method copy stream
    private void CopyStream(Stream from, Stream to)
    {
        using (TextReader reader = new StreamReader(from))
        {
            using (TextWriter writer = new StreamWriter(to))
            {
                writer.Write(reader.ReadToEnd());
                writer.Flush();
            }
        }
    }

    //this method sing and encrypt SOAP message, I call this method in stage  AfterSerialize
    private void CryptMessage()
    {
        newStream.Position = 0;
        using (Stream retStream = cryptUtil.EncryptAndSingXml(newStream))
        {
            retStream.Position = 0;
            CopyStream(retStream, oldStream);
        }
    }

    public override void ProcessMessage(SoapMessage message)
    {
        switch (message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                {
                    // call the crypt and sing method
                    CryptMessage();
                    //save the SOAP message, the message is not encrypt
                    Log(message, "AfterSerialize");
                }
                break;
            case SoapMessageStage.BeforeDeserialize:
                break;
            case SoapMessageStage.AfterDeserialize:
                break;
            default:
                throw new ArgumentException("error.");
        }

    }
    // ...
}

It doesn't look like you are modifying message at all!

And, please show where you create an instance of CryptUtility.

Also, your code is pretty bad. Try this:

public class CryptUtility
{
    public virtual Stream EncryptAndSingXml(Stream inputStream, IEnumerable<string> soapElement)
    {
        XmlDocument doc = new XmlDocument();
        using (XmlReader reader = XmlReader.Create(inputStream))
        {
            doc.Load(reader);
        }

        // in this place I encrypt and sign SOAP message
        XmlNamespaceManager nsMan = new XmlNamespaceManager(doc.NameTable);
        foreach (string xPathQuery in soapElement)
        {
            XmlNodeList nodesToEncrypt = doc.SelectNodes(xPathQuery, nsMan);
            foreach (XmlNode nodeToEncrypt in nodesToEncrypt)
            {
                // method EncryptString crypt only string from XmlNode
                nodeToEncrypt.InnerXml = EncryptString(nodeToEncrypt.InnerXml);
            }
        }

        // !!!
        //               I        THINK  HERE IS A PROBLEM 
        //
        //it return plain stream, no encrypt stream
        using (MemoryStream retStream = new MemoryStream())
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Encoding = Encoding.UTF8;
            using (XmlWriter writer = XmlWriter.Create(retStream, settings))
            {
                doc.WriteTo(writer);
            }
            return retStream;
        }
    }
}

and

public class SoapMsg : SoapExtension
{
    private CryptUtility cryptUtil; //this object crypt and sing SOAP message
    //  ...

    //this method copy stream
    private void CopyStream(Stream from, Stream to)
    {
        using (TextReader reader = new StreamReader(from))
        {
            using (TextWriter writer = new StreamWriter(to))
            {
                writer.Write(reader.ReadToEnd());
                writer.Flush();
            }
        }
    }

    //this method sing and encrypt SOAP message, I call this method in stage  AfterSerialize
    private void CryptMessage()
    {
        newStream.Position = 0;
        using (Stream retStream = cryptUtil.EncryptAndSingXml(newStream))
        {
            retStream.Position = 0;
            CopyStream(retStream, oldStream);
        }
    }

    public override void ProcessMessage(SoapMessage message)
    {
        switch (message.Stage)
        {
            case SoapMessageStage.BeforeSerialize:
                break;
            case SoapMessageStage.AfterSerialize:
                {
                    // call the crypt and sing method
                    CryptMessage();
                    //save the SOAP message, the message is not encrypt
                    Log(message, "AfterSerialize");
                }
                break;
            case SoapMessageStage.BeforeDeserialize:
                break;
            case SoapMessageStage.AfterDeserialize:
                break;
            default:
                throw new ArgumentException("error.");
        }

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