当前位置: 首页 > 面试题库 >

使用SSLEngine(JSSE)与旧客户端进行SSL握手

高化
2023-03-14
问题内容

这是“ 使用自签名证书和SSLEngine(JSSE)进行SSL握手 ”的后续问题。

我实现了一个NIO
Web服务器,该服务器可以在同一端口上处理SSL和非SSL消息。为了区分SSL消息和非SSL消息,我检查了入站请求的第一个字节,看看它是否是SSL /
TLS消息。例:

byte a = read(buf);
if (totalBytesRead==1 && (a>19 && a<25)){
    parseTLS(buf);
}

在parseTLS()方法中,我实例化了一个SSLEngine,启动了握手,包装/展开消息等。对于大多数现代Web浏览器(Firefox 10,IE
9,Safari 5等),一切似乎都可以正常工作。

问题在于,较旧的Web浏览器(如IE 6)和库(如Java的URLConnection类)似乎以不同的方式启动SSL / TLS握手。例如,来自IE
6的前几个字节看起来像这样(十六进制值):

80 4F 01 03 00 ...

如果我将消息传递给SSLEngine,它似乎无法识别该消息并引发Exception。

javax.net.ssl.SSLException: Unsupported record version Unknown-0.0

那么IE 6和Java的URLConnection类到底是发送什么呢?这是JSSE SSLEngine可以支持的有效SSL /
TLS消息吗?我是否需要做一些预处理或与客户端协商以发送不同的消息?

提前致谢!

更新

感谢Bruno和EJP以及进一步的调试,我对发生的事情有了更好的了解。正如Bruno正确指出的那样,IE6和Java 6客户端正在通过SSLv2
ClientHello发送。与我之前的评论之一相反,Java
1.6中的SSLEngine实际上可以解包SSLv2消息并生成有效的响应以发送回客户端。我先前报告的SSLException是我自己的错误,与SSLEngine没有任何关系(我错误地认为客户端已完成发送数据,并且当SSLEngine希望解开更多数据时,我最终得到一个空的ByteBuffer)。


问题答案:

看起来像SSLv2客户端Hello(请参阅TLS规范):

支持SSL 2.0版服务器的TLS 1.1客户端必须发送SSL 2.0版客户端问候消息[SSL2]。如果TLS服务器希望在同一连接端口上支持SSL
2.0客户端,则应接受任何一种客户端问候格式。与2.0版规范的唯一不同之处在于可以指定值为3的版本,以及对CipherSpec中更多加密类型的支持。

  • 80 4F是长度,高位必须设置为1(请参见msg_length说明)。
  • 01 是消息类型(客户端问候)
  • 03 00 是受支持的最高版本(此处为SSLv3)

从Java
7开始,默认情况下已禁用此功能。

编辑:

需要说明的是,这实际上不是SSLv2客户端问候,这是SSLv2格式的SSLv3的客户端问候。在这种情况下,服务器将回复一个(正确的)SSLv3服务器Hello(对应于03 00请求的版本号)。TLS 1.0、1.1和1.2同样适用,尽管逐渐不赞成使用此格式。

JSSE 7 SSLServerSocket仍会理解此类客户端Hello,并使用SSLv3 / TLS1.x Server Hello适当地答复。



 类似资料:
  • 问题内容: 我的任务是实现一个定制/独立的Java Web服务器,该服务器可以在同一端口上处理SSL和非SSL消息。 我已经实现了NIO服务器,并且对于非SSL请求,它可以很好地工作。我在SSL方面花了很长时间,可以真正使用一些指导。 到目前为止,这是我所做的。 为了区分SSL消息和非SSL消息,我检查了入站请求的第一个字节,看看它是否是SSL / TLS消息。例: 在parseTLS()方法中,

  • 我有一个客户端-服务器应用程序(Android客户端、Apache Http服务器),通过相互身份验证(TLS 1.2)进行通信。问题是:有时连接(登录)会因SSL错误而失败。 这是有效的: 注册客户端证书 登录 这是行不通的: 注册客户证书 注意:在步骤4之后杀死应用程序,然后启动它并执行步骤5工作。 我能想到的可能解释是: 正在重用一些旧资源(如旧客户端证书)。看起来所有相关的东西(OkHtt

  • 问题内容: 我正在编写将SSLEngine与NIO结合使用的应用程序,同时编写了客户端和服务器。客户端能够连接到服务器,并且在他连接之后,我希望他能够执行会话恢复/重新协商,但是目前没有运气。 由于使用SSLEngine的代码相当大(SSLEngine的使用是如此复杂!),我将编写一个简单的伪代码来演示这种情况: **我更愿意发布可以提供帮助的代码的任何部分(即使是完整的代码,尽管正如我所说的那样

  • 我正在编写一个使用SSLEngine和NIO的应用程序,我同时编写客户机和服务器。客户端能够连接到服务器,并且在他连接之后,我希望他能够执行会话恢复/重新协商,但目前没有运气… 因为使用SSLEngine的代码相当大(SSLEngine的使用非常复杂!)我将编写一个简单的伪代码来演示这种情况: 当我执行我的程序时,第一个连接是成功的,但是第二个导致异常: 我是否遗漏了ssl会话恢复所需的某些成分?

  • 我已经能够通过HTTP使用Eureka+ZUUL+Ribbon+Config Server设置并成功验证Spring cloud设置。 然而,当我尝试转移到HTTPS时,单个服务在HTTPS上运行良好,但Eureka客户端发现却失败了。

  • 如有任何帮助,我们将不胜感激。 PS:我使用的是java7