.NET SslStream不起作用

时间:2011-01-12 22:16:15

标签: c# xmpp ssl sslstream

我正在尝试使用.net SslStream对tls隧道进行初始化,但在打开流之后我总是收到以下错误:

“无法从传输连接中读取数据:已建立的连接已被主机中的软件中止。”

建立tls连接后和发送第二条消息后。

过去四天我一直在寻找答案,但网上没有任何有用的信息!

编辑: 我正在尝试连接到talk.google.com

我正在使用MSDN的代码示例。唯一的区别是我在使用tls之前和之后发送数据我执行以下操作:

public void SecureStream()
        {
        netStream.Flush();
        sslStream = new SslStream(netStream, false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);

    sslStream.AuthenticateAsClient("talk.google.com");}

编辑:我设法消除了第一个错误(关于我如何处理发送的小错误)现在我总是得到

“无法从传输连接中读取数据:已建立的连接已被主机中的软件中止。”

edit2:我没有发送任何空格我重写了消息传递部分,我仍然有同样的问题。

我从

开始
   String streamInit = "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='google.com' version='1.0'>";
        client.Send(streamInit);

然后在接收时我有以下

  static void client_MessageReceived(SyncronousClient source, string Result)
    {


        if (Regex.IsMatch(Result, "<starttls xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"><required/></starttls>"))
        {
            String startTlS = "<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>";
            source.Send(startTlS);

        }
        else if (Regex.IsMatch(Result, "<proceed xmlns=\"urn:ietf:params:xml:ns:xmpp-tls\"/>"))
        {
            //Do TLS Magic 
            source.SecureStream();
            String streamReInit = "<stream:stream xmlns='jabber:client'xmlns:stream='http://etherx.jabber.org/streams'to='google.com'version='1.0'>";
            source.Send(streamReInit);
        }
        else if (Regex.IsMatch(Result, "<mechanisms xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\">"))
        {
            //String AuthType = "<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='X-GOOGLE-TOKEN'/>";
            String AuthType = "<auth xmlns=\"urn:ietf:params:xml:ns:xmpp-sasl\" mechanism=\"PLAIN\"/>";
            source.Send(AuthType);
        }}

2 个答案:

答案 0 :(得分:1)

这不太可能是您的问题(除非.Net已经开始在SNI下开展),但是当您调用AuthenticateAsClient时,请传入您在流中使用的相同域名(在这种情况下,{{1 }})。同样,您可能需要google.com而不是gmail.com

google.com

正如csharptest.net所提到的,请确保您没有发送额外空格的keepalive计时器,或等待TLS工作之后启动计时器。唯一可以想象你得到错误的另一种方法是,如果你没有服务器实现的密码套件,但我知道.Net SslStream可以对抗GTalk。

最后,使用现有的.Net库之一进行XMPP( 5 列出here),您可以立即开始编写更多有趣的代码。您将要遇到.Net XML系统的不足之处,当您在单次读取中开始获取部分节或多个节时,基于正则表达式的方法将无法正常工作。

答案 1 :(得分:0)

  

这对我来说真的没有意义。服务器(如果使用SSL)要求客户端在连接时执行SSL握手。因此,我不确定你的意思是“我之前发送数据......”。听起来你没有立即调用AuthenticateAsClient。如果是这种情况,我怀疑这是你的问题。 AFAIK,您不能对SSL和非SSL通信使用相同的套接字/连接连接。服务器需要SSL,或者它不支持SSL,它不应该同时执行这两种操作。

我之前的回答是无知的。实际上,似乎标准确实要求在SSL握手初始化之前连接发送和接收数据。真奇怪他们会这样做......但无论如何。在简要阅读parts of the RFC之后,似乎您应该在结束'&gt;'后立即开始SSL客户端身份验证。没有允许的尾随空格可能是你的问题吗?