2

我有使用 opensl 1.0.2j 并使用 RSA:4096 密钥和证书的客户端服务器,并且希望强制服务器仅使用以下密码。

ECDHE-RSA-AES256-GCM-SHA384
ECDHE-RSA-AES256-SHA384
ECDH-RSA-AES128-GCM-SHA256
ECDH-RSA-AES128-SHA256
DHE-RSA-AES256-GCM-SHA384
DHE-RSA-AES256-SHA256
DHE-RSA-AES128-GCM-SHA256
DHE-RSA-AES128-SHA256

我的服务器端代码如下所示。

method = SSLv23_server_method();
ctx = SSL_CTX_new(method);
SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDH-RSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256");
SSL_CTX_set_ecdh_auto(ctx, 1);
SSL_CTX_set_tmp_dh(ctx, dh);
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
SSL_CTX_use_certificate_file(ctx, certFilePath, SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, privKeyPath, SSL_FILETYPE_PEM)
SSL_accept()

我的客户端代码如下所示

method = SSLv23_server_method();
ctx = SSL_CTX_new(method);
SSL_CTX_set_cipher_list(ctx, "ECDH-RSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-SHA256");
SSL_CTX_set_ecdh_auto(ctx, 1);
SSL_CTX_set_tmp_dh(ctx, dh);
SSL_CTX_set_tmp_ecdh(ctx, ecdh);
SSL_CTX_use_certificate_file(ctx, certFilePath, SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, privKeyPath, SSL_FILETYPE_PEM)
SSL_connect()

服务器上的最后一步 ssl_accept() 失败

err: 336027900 'error:140760FC:SSL routines:SSL23_GET_CLIENT_HELLO:unknown protocol'

如果我在客户端使用ECDHE*RSA*DHE*RSA*密码,它工作正常。

你能告诉我我错过了什么吗?

编辑:服务器的证书(certFilePath)包含一个 RSA 公钥而不是 ECDH 公钥。

4

1 回答 1

2

Meta:只回答到 TLS1.2;1.3 不再有密码套件中的密钥交换和身份验证。

首先,调用两者是没有意义的set_ecdh_auto-set_tmp_ecdh它们是相互排斥的。此外,您的服务器不请求客户端身份验证,因此在客户端上配置自我证书和密钥是无用的。OTOH 您的服务器正在使用可能不在客户端默认信任库中的自签名证书,因此您可能需要配置客户端信任库(有几种方法可以做到这一点)。

其次,“静态”ECDH 密码套件与 ECDHE 套件完全不同,就像“静态”DH 套件与 DHE 套件不同一样。这两种静态形式都没有得到广泛实施,也很少使用,因为它们通常没有任何好处;特别是 OpenSSL 1.1.0 及更高版本不再实现它们,因此如果我没记错时间表,您的代码将在大约一年内过时。

确切地说,DH-RSA 套件需要包含 DH 密钥(允许 keyAgreement)的证书,对于 TLS<=1.1,证书必须由CA使用 RSA 密钥颁发;对于 1.2,后一个限制被删除。没有公共 CA 会为 DH 密钥颁发证书,即使自己做也不容易;请参阅https://security.stackexchange.com/questions/44251/openssl-generate-different-type-of-self-signed-certificate和(我的)https://crypto.stackexchange.com/questions/19452/static- dh-static-ecdh-certificate-using-openssl/

ECDH-RSA 套件同样需要包含允许 keyAgreement 的 ECC 密钥的证书,如果 <=1.1 则由 RSA 颁发;这有点容易,因为 ECDH 的密钥(和 CSR)与 ECDSA 相同,只有 KeyUsage 需要不同。对于您自己创建和自签名的案例,这很容易,只需生成一个 ECC 密钥和证书(使用 ECDSA 自动签名)。

但最后,这不应该导致“未知协议”;这将导致“无共享密码”和握手失败。您显示的代码不应导致“未知协议”,因此您可能需要先调查并修复它。您可以尝试使用命令行s_client,尤其是使用它的-debug-msg钩子,或者-trace如果您已经编译了它。

于 2018-10-24T21:39:03.093 回答