无法连接到仅使用密码套件短暂的SSL服务器(本地安全机构无法联系)

问题描述:

我试图连接到测试服务器,开始与OpenSSL的(这有限的密码套件组合意):

I'm trying to connect to the test server started with openssl (this limited ciphersuite combination is intended):

openssl s_server -accept 443 -www -tls1_2 -cipher ECDHE:DHE:EDH -cert selfsignedcert.pem -key sskey.pem

我使用的代码类似于MSDN的

The code I use is similar to msdn's

public static bool ValidateServerCertificate(
      object sender,
      X509Certificate certificate,
      X509Chain chain,
      SslPolicyErrors sslPolicyErrors)
{
        return true;
}

...

var client = new TcpClient(target, port);
SslStream sslStream = new SslStream(client.GetStream(), false,ValidateServerCertificate,null);
sslStream.AuthenticateAsClient(target, null, SslProtocols.Tls12, false);



但我在最后一行得到一个例外: A调用SSPI失败,请参见内部异常,其中内部异常说:本地安全机构无法联系。通过查看Wireshark的我可以说,TLS握手与结束服务器你好,证书,服务器密钥交换,服务器Hello完成和所选择的密码套件是 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009f)

But I'm getting an exception at the last line: A call to SSPI failed, see inner exception., where inner exception says: The Local Security Authority cannot be contacted. By looking at wireshark I can say that the TLS handshake ends with Server Hello, Certificate, Server Key Exchange, Server Hello Done and the chosen ciphersuite is TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009f).

我可以存取权限与Firefox的URL,但不与IE浏览器(它只是说无法显示此页面),所以它看起来像SCHANNEL问题。

I can acces the url with Firefox, but not with IE (it just says "This page can’t be displayed") so it looks like schannel issue.

一切工作正常(IE和代码),当我启动服务器的所有密码套件( -cipher ALL )。有没有一种方法,使其无需修改服务器的配置工作?

Everything works fine (IE and the code) when I start the server with all ciphersuites (-cipher ALL). Is there a way to make it work without modifying server's config?

堆栈跟踪,以防万一。

    at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)

我使用Windows 8.1与最新的更新。

I'm using Windows 8.1 with latest updates.

我已经成功设置使用Windows注册表SCHANNEL最小密钥长度。

I've managed to set the minimum key length for schannel using windows registry.

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\KeyExchangeAlgorithms\Diffie-Hellman]
"ClientMinKeyBitLength"=dword:00000200

但它不是所期望的解决方案,因为它改变了设置整个系统,我想在我的应用范围暂时只有设置它。

But it's not the desired solution, because it changes the setting for the whole system and I would like to set it temporarily and only in the scope of my application.