【发布时间】:2015-05-27 09:05:04
【问题描述】:
我正在尝试连接到以 openssl 开头的测试服务器(这种有限的密码套件组合是有意的):
openssl s_server -accept 443 -www -tls1_2 -cipher ECDHE:DHE:EDH -cert selfsignedcert.pem -key sskey.pem
我使用的代码和msdn的类似
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 call to SSPI failed, see inner exception.,其中内部异常显示:The Local Security Authority cannot be contacted。通过查看wireshark,我可以说TLS 握手以Server Hello, Certificate, Server Key Exchange, Server Hello Done 结尾,而选择的密码套件是TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x009f)。
我可以用 Firefox 访问该 url,但不能用 IE(它只是说“此页面无法显示”)所以它看起来像 schannel 问题。
当我使用所有密码套件 (-cipher ALL) 启动服务器时,一切正常(IE 和代码)。有没有办法在不修改服务器配置的情况下使其工作?
Stacktrace 以防万一
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。
【问题讨论】:
-
尝试给你自己的 DH 参数,至少 1024 位。 s_server 的默认值为弱 512 位,IE 可能无法接受。
-
@SteffenUllrich 谢谢,使用自定义 1024 位参数有所帮助。但我的问题是如何连接到该服务器而不更改它的配置,即。如何在 schannel 中绕过此保护措施
-
我认为绕过此检查不是一个好主意,请参阅weakdh.org。并期望其他浏览器和库也能得到这个限制。 OpenSSL forks BoringSSL 和 LibreSSL 也有一段时间的 1024 位限制,但没有办法绕过它。但是您可能会使用更新的 OpenSSL 版本(1.02 之后),它们不再使用 s_server 中的 512 位 DH 默认值。
-
我知道这一点。问题是我正在使用我的程序来验证远程服务器的 SSL/TLS 配置(坏证书、弱密码套件等),所以我需要它来连接不安全的服务。到目前为止,schannel 似乎不适合这份工作。