我有一个简单的C#应用程序,通过TLS与远程服务器通信。当我尝试“AuthenticateAsClient”时,我立刻收到了可怕的“客户端和服务器无法通信,因为它们没有通用的算法。”
所以,我打破了一条线索并观察到“Client Hello”完成并提供了一个密码套件列表。 “服务器Hello”使用“Client Hello”中提供的列表中的证书和选定的密码套件完成。然而,我接下来希望看到“CIPHER CHANGE SPEC”,但是,客户端会重置/确认连接,然后失败,我不明白为什么。服务器正在发送TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA(0xC014)。
我尝试了什么:
我怀疑服务器证书有问题,但已确认其KeySpec为1且验证正确。其证书链验证。即使从服务器导出并移动到我的客户端框(没有私钥),验证链似乎也没问题。
我已经通过IISCrypto工具验证了AES_256已在服务器和客户端上启用并可用。但是,我注意到,尽管我指定了TLS 1.2,但线路跟踪显示服务器仅响应TLS 1.0。我将客户端指向另一台机器上的另一个应用程序实例,但它确实响应了TLS 1.2,并且工作正常 - 但是使用了不同的密码套件:TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384(0xC028)。
我也尝试过相反的极端,迫使应用程序下降到TLS 1.0对“好”(工作)服务器,结果是相同的 - 它仍然有效。
我认为未能发送CIPHER CHANGE SPEC是因为可能不正确的确定它没有通用的算法,但是如果它不可用,客户怎么能提供呢?某些密码规范中的某些内容是否会被“损坏”,直到实际使用它们才能实现?
为了完整起见,我已经摘录了将SSL连接到一个小型控制台应用程序的程序部分,这似乎很简单,但我已经在这里复制了有人看到我正在做的事情不正确的事情:
static void Main(string[] args)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
int portNumber = 9999999; //edited for obvious reasons
TcpClient x = new TcpClient("the.server.name", portNumber);
var foo = new System.Net.Security.SslStream(x.GetStream(), false,
(a,b,c,d) => {
Console.WriteLine("connected");
return true;
});
foo.AuthenticateAsClient("the.server.name");
Console.WriteLine(foo.CipherAlgorithm.ToString());
}