【发布时间】:2020-01-09 08:08:37
【问题描述】:
我正在尝试用 C# 构建一个在 localhost 上运行的简单 TLS Web 服务器。在这种情况下,我希望服务器做的就是发出重定向。为此,我使用 Microsoft 提供的 SslStream 类。从表面上看,它似乎很容易使用。我遇到的问题是 chrome 似乎并不喜欢我的 HTTPS。 (代码在底部)
回复很简单:"HTTP/1.1 301 Moved Permanently\r\nCache-Control: no-store\r\nLocation: https://google.com/"
使用 HTTP 实现时,页面会按预期重定向,客户端 (Chrome) 或服务器上不会出现错误或异常。
但是,当使用我的 HTTPS 实现时,我从 chrome 中得到了类似的东西:
无法访问此网站
网页在.....
ERR_RESPONSE_HEADERS_TRUNCATED
我不确定它还想从我这里得到什么。我会说响应标头没有被截断,但我不是 chrome。我可以在调试时读取 chrome 的 GET 请求,但 chrome 显然不能或不会读取我的响应。
我已成功使用完全相同的代码重定向边缘(http 和 https),所以这似乎是特定于 chrome 的
在服务器发送响应之前,快速的wireshark 调查显示没有任何异常。举例说明:标准 tcp syn/ack 握手,tls 握手,然后是客户端应用程序。数据(GET)服务器应用程序数据(301)。在服务器发送 301 之后,有 3 个 FIN/ACK,一个保持活动状态,一个密码更改,然后是一堆 RST。鉴于这些信息,似乎 chrome 并没有给我们任何东西,但同时也不指望我们抛弃它们,并开始拼命恳求重新连接。奇怪的是,如果我调试,它会重新连接。但随后它抛出异常,因为服务器在读取时超时;我们给了 Chrome 第二次机会,但 Chrome 不愿意为已经破裂的关系恢复任何东西,并留下了伤痕。
差不多了,我在问我在做什么 Chrome 显然没有预料到,我该如何纠正它以便它在 Chrome 上运行?我是在做其他浏览器正在补偿的明显错误,还是 SslStream 有问题?
我的 TLS 代码基本上取自 Microsoft doc for SslStream,http 设计遵循相同的模式:接受、读取、写入、刷新、流关闭、tcp 关闭。如果要复制,则创建的证书与 X509Certificate.CreateFromCertFile(string) 一起使用。 TcpListener 使用了IPAddress.Loopback。为了生成我的证书,我关注了this tutorial,并使用openssl pkcs12 导出了我的localhost.crt 和localhost.key
private string response = "HTTP/1.1 301 Moved Permanently\r\nCache-Control: no-store\r\nLocation: https://google.com/ \r\n";
private void listen() {
while (true) {
TcpClient client = listener.AcceptTcpClient();
NetworkStream stream = client.GetStream();
stream.Read(new Byte[1024], 0, 1024);
stream.Write(Encoding.UTF8.GetBytes(response), 0, response.Length);
stream.Flush();
stream.Close();
client.Close();
}
}
private void listenSSL() {
TcpClient client;
while (true) {
client = listener.AcceptTcpClient();
SslStream sslStream = new SslStream(client.GetStream(), false);
sslStream.AuthenticateAsServer(certificate, clientCertificateRequired: false, SslProtocols.Tls12, checkCertificateRevocation: true);
sslStream.ReadTimeout = timeout;
sslStream.WriteTimeout = timeout;
string message = readMessage(sslStream);
sslStream.Write(Encoding.UTF8.GetBytes(response), 0, response.Length);
sslStream.Flush();
sslStream.Close();
client.Close();
}
}
【问题讨论】:
标签: c# google-chrome https wireshark tls1.2