0

我有一台在Ubuntu 1804上运行的服务器,带有OpenSSL 1.1.1 11 Sep 2018客户端使用以PSK-AES256-CBC-SHA作为密码的 PSK 身份验证与服务器通信。

当我使用在 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 框连接。

4

1 回答 1

3

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

那么这是否意味着只有 TLS_AES_128_GCM_SHA256 可以与 TLS1.3 一起使用?

不可以。TLSv1.3 PSK 可以与任何 TLSv1.3 兼容的密码套件一起使用。但是,OpenSSL 提供了 2 组回调来设置 PSK。“旧式”回调是在 TLSv1.3 出现之前设计的,而“新式”回调是在考虑 TLSv1.3 的情况下设计的。如果您的应用程序使用“旧样式”回调(如果它是为 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,则该错误是由 OpenSSL 生成的。问题是 - 为什么您的代码在 Windows 上返回 0 的 psklen?

于 2019-08-12T15:38:43.257 回答