只有 TLS_AES_128_GCM_SHA256 密码适用于 TLS 1.3 的 psk 连接吗?

Does only TLS_AES_128_GCM_SHA256 cipher work for psk connections for TLS 1.3?

我在 Ubuntu 1804 上有一个服务器 运行 OpenSSL 1.1.1 2018 年 9 月 11 日 。 客户端使用 PSK 身份验证与服务器通信,密码为 PSK-AES256-CBC-SHA

当我使用基于 Windows 和 openssl-1.1.1c 构建的客户端(使用 Microsoft Visual Studio 2019 构建)时,我无法做到工作。

在服务器端,我得到以下信息:

139845863200512:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1528:SSL alert number 40

在客户端,

11720:error:141970DF:SSL routines:tls_construct_cke_psk_preamble:psk identity not found:ssl\statem\statem_clnt.c:2917

我在openssl-1.1.1c\ssl\statem\extensions_clnt.c.

中看到了以下内容
            /*
             * We found a PSK using an old style callback. We don't know
             * the digest so we default to SHA256 as per the TLSv1.3 spec
             */
            cipher = SSL_CIPHER_find(s, tls13_aes128gcmsha256_id);

那么这是否意味着只有 TLS_AES_128_GCM_SHA256 适用于 TLS1.3? 任何指向我可能缺少的东西的指针?任何有关如何使用来自 Windows 平台的客户端 PSK 身份验证的教程都会有所帮助。

我可以使用相同的 PSK id 和密钥从 linux 盒子连接到服务器。但是无法从 windows 框连接。

TLSv1.3 使用与 TLSv1.2 及更低版本完全不同的密码套件。 TLSv1.3 的密码套件不适用于之前的协议版本,反之亦然。

So does this mean that only TLS_AES_128_GCM_SHA256 works with TLS1.3?

没有。 TLSv1.3 PSK 可以与任何 TLSv1.3 兼容的密码套件一起使用。但是,OpenSSL 提供了两组用于设置 PSK 的回调。 "old style" 回调是在 TLSv1.3 出现之前设计的,而 "new style" 回调是为 TLSv1.3 设计的。如果您的应用程序使用 "old style" 回调(这很可能是为 OpenSSL 1.1.0 或更早版本编写的),那么在 TLSv1.3 中,PSK 将仅适用于基于 SHA256 的 TLSv1.3 密码套件。其中包括 OpenSSL 支持的所有 TLSv1.3 密码套件,TLS_AES_256_GCM_SHA384 除外。不要对代码中专门使用 TLS_AES_128_GCM_SHA256 感到困惑。在这种情况下,只有 SHA256 位很重要。

然而,以上所有内容都与您的特定问题无关:

11720:error:141970DF:SSL routines:tls_construct_cke_psk_preamble:psk identity not found:ssl\statem\statem_clnt.c:2917

从错误中我可以看出客户端正在尝试构建 CKE 消息 (ClientKeyExchange)。此消息未在 TLSv1.3 中发送,因此我们可以确信服务器选择了 TLSv1.2(或更低版本)。该错误实际上是由 OpenSSL 中的这段代码产生的:

psklen = s->psk_client_callback(s, s->session->psk_identity_hint,
                                identity, sizeof(identity) - 1,
                                psk, sizeof(psk));

if (psklen > PSK_MAX_PSK_LEN) {
    SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
             SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE, ERR_R_INTERNAL_ERROR);
    goto err;
} else if (psklen == 0) {
    SSLfatal(s, SSL_AD_HANDSHAKE_FAILURE,
             SSL_F_TLS_CONSTRUCT_CKE_PSK_PREAMBLE,
             SSL_R_PSK_IDENTITY_NOT_FOUND);
    goto err;
}

从上面可以看出,如果 OpenSSL 调用您的应用程序回调并返回 psklen 为 0,则会生成错误。问题是 - 为什么您的代码在 Windows?

上返回 0 的 psklen