简体   繁体   English

openssl 1.0.2j,如何强制服务器选择 ECDH* 密码

[英]openssl 1.0.2j, how to force server to choose ECDH* ciphers

I have client server which uses opensl 1.0.2j, and using RSA:4096 key and certificate and want to force the server to use only the following ciphers.我有使用 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

My server side code will look like below.我的服务器端代码如下所示。

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()

My client side code will look like as below我的客户端代码如下所示

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()

The last step ssl_accept() on the server fails with服务器上的最后一步 ssl_accept() 失败

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

If i use ECDHE*RSA* or DHE*RSA* ciphers on the client side, it is working fine.如果我在客户端使用ECDHE*RSA*DHE*RSA*密码,它工作正常。

Could you please let me know what I am missing?你能告诉我我缺少什么吗?

Edit: server's certificate(certFilePath) contains an RSA public key not the ECDH public key.编辑:服务器的证书(certFilePath)包含一个 RSA 公钥而不是 ECDH 公钥。

Meta: answer only up to TLS1.2; Meta:最多只能回答 TLS1.2; 1.3 no longer has keyexchange and authentication in ciphersuite. 1.3 在密码套件中不再有密钥交换和认证。

First, it makes no sense to call both set_ecdh_auto and set_tmp_ecdh -- those are mutually exclusive.首先,调用set_ecdh_autoset_tmp_ecdh是没有意义的——它们是互斥的。 Also your server doesn't request client authentication, so configuring a self-cert&key on the client is useless.此外,您的服务器不请求客户端身份验证,因此在客户端上配置 self-cert&key 是无用的。 OTOH your server is using a selfsigned cert which probably isn't in the client's default truststore, so you may need to configure the client truststore (there are several approaches to doing that). OTOH 您的服务器正在使用自签名证书,该证书可能不在客户端的默认信任库中,因此您可能需要配置客户端信任库(有几种方法可以做到这一点)。

Second, 'static' ECDH ciphersuites are quite different from ECDHE suites, just as 'static' DH suites are different from DHE suites.其次,“静态”ECDH 密码套件与 ECDHE 套件完全不同,正如“静态”DH 套件与 DHE 套件不同。 Both static forms are not widely implemented and very little used because they generally offer no benefit;这两种静态形式都没有广泛实现,也很少使用,因为它们通常没有任何好处; in particular OpenSSL 1.1.0 and up no longer implement them, so your code becomes obsolete in about a year if I remember the schedule correctly.特别是 OpenSSL 1.1.0 及更高版本不再实现它们,所以如果我没有记错时间表,你的代码在大约一年后就会过时。

To be exact, DH-RSA suites require a cert containing a DH key (which permits keyAgreement), and for TLS<=1.1 the cert must be issued by a CA using an RSA key;确切地说,DH-RSA 套件需要一个包含 DH 密钥的证书(允许 keyAgreement),对于 TLS<=1.1,证书必须由CA使用 RSA 密钥颁发; for 1.2 this latter restriction is removed.对于 1.2 后一个限制被删除。 No public CA will issue a cert for a DH key, and even doing it yourself isn't easy;没有公共 CA 会为 DH 密钥颁发证书,甚至自己做也不容易; see https://security.stackexchange.com/questions/44251/openssl-generate-different-type-of-self-signed-certificate and (my) https://crypto.stackexchange.com/questions/19452/static-dh-static-ecdh-certificate-using-openssl/ .请参阅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 suites similarly require a cert containing an ECC key which permits keyAgreement, and issued by RSA if <=1.1; ECDH-RSA 套件同样需要一个包含允许 keyAgreement 的 ECC 密钥的证书,如果 <=1.1,则由 RSA 颁发; this is somewhat easier because the key (and CSR) for ECDH is the same as for ECDSA and only KeyUsage needs to differ.这稍微容易一些,因为 ECDH 的密钥(和 CSR)与 ECDSA 的密钥(和 CSR)相同,只有 KeyUsage 需要不同。 For your self-created and self-signed case, it's easy, just generate an ECC key and cert (automatically signed with ECDSA).对于您自己创建和自签名的案例,这很简单,只需生成一个 ECC 密钥和证书(使用 ECDSA 自动签名)。

But last, this shouldn't cause 'unknown protocol';但最后,这不应该导致“未知协议”; it would cause 'no shared cipher' and handshake_failure.它会导致“无共享密码”和握手失败。 The code you've shown shouldn't cause 'unknown protocol', so you probably need to investigate and fix that first.您显示的代码不应导致“未知协议”,因此您可能需要先调查并修复该问题。 You might try using commandline s_client instead especially with its -debug or -msg hooks, or -trace if you have compiled that in.您可以尝试使用命令行s_client代替,尤其是使用它的-debug-msg钩子,或者-trace如果您已经编译了它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM