.NET SslStream 不工作
我正在尝试使用 .net SslStream 初始化 tls 隧道,但打开流后我总是收到以下错误:
“无法从传输连接读取数据:已建立的连接被主机中的软件中止。”
在我建立 tls 连接并发送第二条消息后。
在过去的四天里我一直在寻找答案,但网上没有任何有用的信息!
编辑: 我正在尝试连接到 talk.google.com
,并且正在使用 MSDN 中的代码示例。唯一的区别是我在使用 tls 之前发送数据,并且在使用 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);
}}
I am trying inialise a tls tunnel with the .net SslStream but after opening the stream I always get the following error:
"Unable to read data from the transport connection: An established connection was aborted by the software in your host machine."
After I establish a tls connection and after sending a second message.
I've been searching for an answer for the last four days but there isn't any helpful information online!
edit:
I am trying to connect to talk.google.com
and I'm using the code sample from MSDN. Only difference is that I'm sending data before and when it is time to use tls i do the following:
public void SecureStream()
{
netStream.Flush();
sslStream = new SslStream(netStream, false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
sslStream.AuthenticateAsClient("talk.google.com");}
edit: I managed to eliminate the first error (small bug on how i was handling the send) now I always get
"Unable to read data from the transport connection: An established connection was aborted by the software in your host machine."
edit2: Im not sending any whitespaces I rewrote the message passing part and I still have the same problem.
I start with
String streamInit = "<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='google.com' version='1.0'>";
client.Send(streamInit);
Then on receive I have the following
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);
}}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这不太可能是您的问题(除非 .Net 已开始在幕后执行 SNI),但是当您调用 AuthenticateAsClient 时,请传入您在流的 to 属性中使用的相同域名(在本例中为
google.com )。此外,您可能需要
gmail.com
而不是google.com
:正如 csharptest.net 提到的,确保您没有发送额外空格的 keepalive 计时器,或者等待 TLS 工作后启动计时器。我可以想象您遇到该错误的唯一其他方法是如果您没有服务器实现的密码套件,但我知道 .Net SslStream 对 GTalk 有效。
最后,使用 XMPP 的现有 .Net 库之一(列出了 5 这里),您可以立即开始编写更多有趣的代码。您将遇到 .Net XML 系统的不足之处,并且当您开始在一次读取中获取部分节或多个节时,基于正则表达式的方法将不起作用。
It's unlikely to be your problem (unless .Net has started doing SNI under the covers), but when you call AuthenticateAsClient, pass in the same domain name that you used in your stream's to attribute (in this case,
google.com
). As well, you might needgmail.com
instead ofgoogle.com
:As csharptest.net alluded to, make sure you don't have a keepalive timer that sends extra whitespace, or wait to start the timer until after TLS works. The only other way I can imagine your getting that error is if you don't have a ciphersuite that the server implements, but I know the .Net SslStream works against GTalk.
Lastly, use one of the existing .Net libraries for XMPP (there are 5 listed here), and you can start writing much more fun code right away. You're about to run into the inadequacies of the .Net XML system, and your regex-based approach won't work when you start getting partial stanzas or multiple stanzas in a single read.
上面我之前的回答是无知的。事实上,该标准确实要求连接在 SSL 握手初始化之前发送和接收数据。他们会这么做真的很奇怪……但无论如何。简要阅读 RFC 的部分后,您似乎应该启动 SSL 客户端在结束“>”后立即进行身份验证。不允许尾随空格,这可能是您的问题?
My previous answer above was in ignorance. Indeed it appears that the standard does in fact require that the connect send and receive data prior to the initialization of the SSL handshake. Really odd that they would do that... but whatever. After briefly reading through parts of the RFC it appears that you are expected to begin the SSL client auth immediately after the closing '>'. No trailing whitespace allowed which may be your problem?