如何正常检测SSL

我有一个可以绑定到ssl或plain http的Web服务。 配置为知道服务器主机和端口的Java客户端。 当客户端连接时,我构建服务器端点,如http:// host:port / service 。 客户端不知道服务器是否正在使用ssl – 服务器始终绑定到单个端口,以便它是安全的或不安全的。 现在,问题是如何让客户端在不引入其他参数的情况下发现它? 我是否可以挑战普通的http请求,然后在特定的exception情况下回到ssl(或反之)? 或者我必须为客户明确引入新的连接参数?

在服务器端,您可以使用像Grizzly的端口统一实现这样的机制。 这可用于在同一端口上提供HTTP和HTTPS。 这取决于以下事实:在两种情况下,客户端首先进行会话,并发送HTTP请求或SSL / TLS客户端Hello消息。 它在服务器端非常方便(虽然我不确定我是否建议在同一端口上运行两个协议)。

从客户的角度(这是你要问的),其后果是:

  • 客户首先谈话的事实意味着它总是必须首先尝试。 如果您尝试将SSL / TLS与普通HTTP服务进行通信,则会出现某种exception,反之亦然。
  • 如果服务器使用端口统一,那么您将无法可靠地找到它。

除了端口统一(毕竟这是一种罕见的情况),您可以尝试缓存过去尝试的结果。

更重要的是,从安全的角度来看,不知道应该使用哪种协议会引入漏洞:您的系统将开放降级攻击 (以盲目依赖自动重定向的方式)。 如果您的用户代理支持HSTS ,那么值得研究(尽管它需要用户代理记住哪些站点将与HTTPS一起使用)。

无论哪种方式,如果您担心安全性,您必须配置客户端以了解何时使用https://