我相信SslStream.AuthenticateAsClient
受到Long Handshake Intolerance
ssllabs 在 GitHub 上记录的问题的影响。
我已经尝试了将近 2 年的时间来找出问题所在,偶然我正在使用 Fiddler 进行调试并阅读了它的日志选项卡并看到它正在列出
Warning: ClientHello record was X bytes long. Some servers have problems with ClientHello's greater than 255 bytes. https://github.com/ssllabs/research/wiki/Long-Handshake-Intolerance
我相信AuthenticateAsClient
(甚至可能是 AuthenticateAsServer)容易出现这个错误/问题,因为这只是我为什么我经常几乎随机地得到异常的唯一可能原因,即使使用相同的 IP、代理、代理类型和目标请求也是如此。
try {
sslStream.AuthenticateAsClient(Host, null, false);
authenticated = sslStream.IsAuthenticated;
} catch (Exception ex) {
if ((Marshal.GetHRForException(ex) & 0xFFFF) == 5664) {
//Authentication failed because the remote party has closed the transport stream.
}
//As well as "The handshake failed due to an unexpected packet format."
}
我收到了 2 个常见错误,一个是 Marshal 5664 和“由于意外的数据包格式导致握手失败”。这是我认为与这个 255 字节问题有关的问题。
我不完全确定调试方法,所以我在这里寻求指导。
更新:
刚刚得到一个确认的可重现实例,当你有一个 SOCKS4 代理但尝试通过发送 SOCKS5 协商发出请求时,它似乎总是或至少大部分时间发生,也许有一种方法来测试代理是 SOCKS4 还是 5?
更新 2:
因此,我通过正确使用 SOCKS4 协商来测试 SOCKS4,我发现它经常返回 0x5A(成功)的状态字节,但可能有 20% 的时间它返回一个只有完整 0x00(空值)的 4 字节数组,首先,第三个和第四个字节基本上会被忽略,但第二个字节(状态字节)返回 0x00 即使根据维基百科甚至没有记录这一事实有点奇怪。
更新 3:
只是为了澄清通过公开可用的免费代理进行的即时测试。巧合的是,似乎有问题的所有 3 个代理大多是端口 4145,经过一些研究,它似乎是 Microtik 路由器上的一个常见代理端口,令人震惊的是,如果我去端口:80 其中一个代理,它会呈现我是带有 Microtik 徽标的路由器默认网关登录名。当通过浏览器向端口 4145 请求时,所有 3 个代理都说没有返回数据,所以我假设所有 3 个都是 Microtik,因为所有证据都指向它。