如何在没有记录层的情况下获得TLS握手?

Paŭ*_*ann 11 java ssl tls1.3

我正在查看最近的QUIC传输协议(传输TLS)的Internet草案,并想知道如何在Java(或其他JVM语言)中实现,假设我不想同时重新实现TLS 1.3.

TLS通常基于TCP(或其他具有类似服务的协议),TLS本身有两层:

   +--------------+--------------+--------------+
   |  Handshake   |    Alerts    |  Application |
   |    Layer     |              |     Data     |
   |              |              |              |
   +--------------+--------------+--------------+
   |                                            |
   |               Record Layer                 |
   |                                            |
   +--------------------------------------------+
   |                                            |
   |                   TCP                      |
   |                                            |
   +--------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

2.1改编自互联网草案

在Java中,我们可以使用javax.net.ssl中的类来实现这一点,或者使用SSLEngine仅用于没有I/O的TLS(应用程序或框架需要插入网络,例如使用NIO),或者使用SSLSocket(通过常用的InputStream/OutputStream阻塞I/O实现TCP上的TLS或SSLServerSocket.

QUIC仅使用TLS 1.3的握手部分来协商会话密钥,同时使用自己的数据包格式和加密("数据包保护")而不是TLS'记录层(整个过程基于UDP,而不是TCP):

   +--------------+--------------+ +-------------+
   |     TLS      |     TLS      | |    QUIC     |
   |  Handshake   |    Alerts    | | Applications|
   |              |              | | (h2q, etc.) |
   +--------------+--------------+-+-------------+
   |                                             |
   |                QUIC Transport               |
   |   (streams, reliability, congestion, etc.)  |
   |                                             |
   +---------------------------------------------+
   |                                             |
   |            QUIC Packet Protection           |
   |                                             |
   +---------------------------------------------+
   |                                             |
   |                   UDP                       |
   |                                             |
   +---------------------------------------------+
Run Code Online (Sandbox Code Playgroud)

图3改编自网络草案,第3节

所以现在我的问题是:给定的TLS实现(来自Java 11,我们包含TLS 1.3)在一个框中只有TLS,即记录+握手+警报在一起,而不是仅握手版本.SSLEngine的似乎最接近来了,但它仍然有只有两个wrapunwrap它的创建/读取密文和读/生产的纯文本(虽然我可能能够做到这握手而不传输任何实际数据)的方法.

是否有一种简单的方法来剥离记录层?或者我可以使用不同的实现?

我还需要从中获取实际密钥(或者更确切地说,主密钥).

Ska*_*out 0

有一个简单的方法。您编写了一个 SSLEngine,它是真实 SSLEngine 的包装器。您可以移除包裹中的框架和展开部分中的框架。您只需委托所有其他方法即可。