C# SSLStream:“对 SSPI 的调用失败”异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13122093/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
SSLStream: "A Call to SSPI Failed" Exception
提问by Tearsdontfalls
I have a strange problem: I wrote a server and client in c# based on .net2 which are chatting over the .net 2 SslStream. There is 1 Connection for sending commands between Cl and S and theres one connection for sending files between cl and s.
Locally all is working fine on my windows machine. But if I run the server on my Linux server(with mono), sharing files doesnt work in certain situations. I have different Categories for files, and in 2 of 3 its working, in the third, the server hangs on SSLStream.AuthenticateAsServer(....);and the client throws a Exception with the Message "A Call to SSPI Failed, see inner exception".
The innerexception is a System.ComponentModel.Win32Exception with the Message "The message received was unexpected or badly formatted."
我有一个奇怪的问题:我在基于 .net2 的 c# 中编写了一个服务器和客户端,它们通过 .net 2 SslStream 聊天。Cl 和 S 之间有 1 个连接用于发送命令,cl 和 s 之间有一个连接用于发送文件。
在本地,我的 Windows 机器上一切正常。但是如果我在我的 Linux 服务器上运行服务器(使用单声道),在某些情况下共享文件不起作用。我有不同的文件类别,在 3 个中的 2 个中它的工作,在第三个中,服务器挂起,SSLStream.AuthenticateAsServer(....);客户端抛出一个异常,消息为“对 SSPI 的调用失败,请参阅内部异常”。内部异常是 System.ComponentModel.Win32Exception,带有消息“收到的消息意外或格式错误”。
I think that my way to run it on linux could be wrong. Actually Im using VS2012 for local developing and when I want to put it on the server I upload the compiled exe by VS and Im using mono server.exeto start it. But I also tried to use monodevelop on Windows to compile it(compiled stuff from monodevelop does also work locally) and use it on the linux server, but this ended in the same result.
我认为我在 linux 上运行它的方式可能是错误的。实际上我使用 VS2012 进行本地开发,当我想把它放在服务器上时,我上传了 VS 编译的 exe,我使用mono server.exe它来启动它。但是我也尝试在 Windows 上使用 monodevelop 来编译它(从 monodevelop 编译的东西也可以在本地工作)并在 linux 服务器上使用它,但这以相同的结果结束。
Any help will be greatly appreciated.
任何帮助将不胜感激。
Heres my shortened Code:
这是我缩短的代码:
Client:
客户:
//gets auth guid before, then it does
Thread Thre = new Thread(sendfile);
Thre.Start(authguid);
private void sendfile(string guid){
TcpClient cl = new TcpClient();
cl.Connect(hostname, 8789);
SslStream Stream = new SslStream(cl.GetStream(), true, new RemoteCertificateValidationCallback(ServerConnector.ValidateServerCertificate));
Stream.AuthenticateAsClient(hostname);//throws the exception
//sends auth guid and file
}
Server:
服务器:
public class FServer
{
protected static bool halt = false;
protected List<FConnection> connections;
private TcpListener tcpServer;
private IPEndPoint ipEnde = new IPEndPoint(IPAddress.Any, 8789);
private delegate void dlgAccept();
private dlgAccept accepting;
private IAsyncResult resAccept;
public FServer()
{
tcpServer = new TcpListener(ipEnde);
connections = new List<FConnection>();
tcpServer.Start();
accepting = new dlgAccept(accept);
resAccept = accepting.BeginInvoke(null, null);
}
public void accept()
{
do
{
if (tcpServer.Pending())
connections.Add(new FConnection(tcpServer.AcceptTcpClient(), this));
else
Thread.Sleep(750);
} while (!halt && tcpServer != null);
}
public class FConnection
{
public SslStream stream;
//.....some other properties
public static bool ValidateClientCertificate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
return true;
}
public FConnection(TcpClient cl, FServer inst)
{
instance = inst;
client = cl;
stream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateClientCertificate), null);
stream.AuthenticateAsServer(instance.mainserver.serverCert, false, SslProtocols.Tls, false);//hangs sometimes on this
if (stream.IsAuthenticated && stream.IsEncrypted)
{
}
else
{
this.Dispose();
}
//auth and receiving file
}
}
}
采纳答案by Tearsdontfalls
Ok I researched about the innerexception a bit deeper and found the solution here:
好的,我对内部异常进行了更深入的研究,并在这里找到了解决方案:
The credit goes to paksysfrom MSDN
归功于MSDN 的paksys
The problem is in the client and i changed
问题出在客户端,我改变了
Stream.AuthenticateAsClient(hostname);
to
到
X509Certificates.X509Certificate2Collection xc = new X509Certificates.X509Certificate2Collection();
Stream.AuthenticateAsClient(hostname, xc, Security.Authentication.SslProtocols.Tls, false);
回答by Hudvoy
I just had the same problem and the accepted answer was not working for me. The problem was that the server certificate was using SHA-2. Here is the code I use to fix it:
我只是遇到了同样的问题,接受的答案对我不起作用。问题是服务器证书使用的是 SHA-2。这是我用来修复它的代码:
X509Certificates.X509Certificate2Collection xc = new X509Certificates.X509Certificate2Collection();
Stream.AuthenticateAsClient(hostname, xc, Security.Authentication.SslProtocols.Tls12, false);
- Note that the only difference with the accepted answer is the sslProtocol
- 请注意,与接受的答案的唯一区别是 sslProtocol
Hope it can help someone
希望它可以帮助某人

