如何将PFS添加到用c和openssl编写的套接字服务器中

我尝试将PFS(完美前向保密)添加到我的客户端 – 服务器应用程序中。

当我使用以下命令运行服务器时:

openssl s_server -key ./key.pem -cert ./cert.pem -accept 443 -cipher ECDHE-RSA-AES128-SHA -tls1_2 

鉴于以下ctx,我能够与我的客户连接:

 SSL_CTX* initCTX() { SSL_METHOD *method; SSL_CTX *ctx; SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); method = TLSv1_2_client_method(); ctx = SSL_CTX_new(method); if(ctx == NULL) { ERR_print_errors_fp(stderr); return NULL; } SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES128-SHA"); return ctx; } 

当我使用以下ctx运行我的服务器应用程序时:

 SSL_CTX* init_ssl_ctx() { SSL_METHOD const *method; SSL_CTX *ctx; SSL_library_init(); OpenSSL_add_all_algorithms(); SSL_load_error_strings(); method = TLSv1_2_server_method(); ctx = SSL_CTX_new(method); if(ctx == NULL) { ERR_print_errors_fp(stderr); abort(); } SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES128-SHA"); // ADDITIONAL CTX MODIFICATIONS TO ENABLE ECDHE SSL_CTX_use_certificate_file(ctx, "./cert.pem", SSL_FILETYPE_PEM); SSL_CTX_use_PrivateKey_file(ctx, "./key.pem", SSL_FILETYPE_PEM); return ctx; } 

并尝试与客户端连接,然后我得到一个no shared cipher错误。 私钥已使用openssl genrsa创建。

我的问题是:我如何修改ctx以添加ECDHE支持。 我想我必须选择一条曲线,我可能需要为每个连接创建和交换密钥。

我还需要私钥文件吗? 什么时候是 – 它用于什么?

那么我实际上错过的是Diffie-Hellman参数和Elliptic曲线Diffie-Hellman的配置。 如果你不配置它们……

PFS密码套件将被默默忽略

有关如何在C套接字服务器中配置和包含Diffie-Hellman参数和Elliptic曲线Diffie-Hellman的更多信息和示例,请访问: http : //wiki.openssl.org/index.php/Diffie-Hellman_parameters

 ... then I get an no shared cipher error. How do I have to modify the ctx to add ECDHE support? 

密码套件是客户端和服务器function的产物。 我发现我需要添加12到16,以确保可以容纳大多数客户。

这是我使用的密码列表。 它包括即将推出的ChaCha和Poly密码套件,并包括下层客户端套件。 如果您想要ECDHE,那么甚至可以进一步提升列表。

 // *_CHACHA20_POLY1305 are 3x to 4x faster than existing cipher suites. // http://googleonlinesecurity.blogspot.com/2014/04/speeding-up-and-strengthening-https.html // Use them if available. Normative names can be found at (TLS spec depends on IPSec spec): // http://tools.ietf.org/html/draft-nir-ipsecme-chacha20-poly1305-01 // http://tools.ietf.org/html/draft-mavrogiannopoulos-chacha-tls-02 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:" "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:" "TLS_ECDHE_ECDSA_WITH_CHACHA20_SHA:" "TLS_ECDHE_RSA_WITH_CHACHA20_SHA:" "TLS_DHE_RSA_WITH_CHACHA20_POLY1305:" "TLS_RSA_WITH_CHACHA20_POLY1305:" "TLS_DHE_RSA_WITH_CHACHA20_SHA:" "TLS_RSA_WITH_CHACHA20_SHA:" // Done with bleeding edge, back to TLS v1.2 and below "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:" "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:" "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:" "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:" "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:" "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:" "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:" "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:" // TLS v1.0 (with some SSLv3 interop) "TLS_DHE_RSA_WITH_AES_256_CBC_SHA384:" "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:" "TLS_DHE_RSA_WITH_AES_128_CBC_SHA:" "TLS_DHE_DSS_WITH_AES_128_CBC_SHA:" "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:" "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:" "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:" "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:" // RSA key transport sucks, but they are needed as a fallback. // For example, microsoft.com fails under all versions of TLS // if they are not included. If only TLS 1.0 is available at // the client, then google.com will fail too. TLS v1.3 is // trying to deprecate them, so it will be interesteng to see // what happens. "TLS_RSA_WITH_AES_256_CBC_SHA256:" "TLS_RSA_WITH_AES_256_CBC_SHA:" "TLS_RSA_WITH_AES_128_CBC_SHA256:" "TLS_RSA_WITH_AES_128_CBC_SHA:" 

ChaCha / Poly密码套件在OpenSSL 1.0.2中提供。 因此,如果感兴趣,您可以测试Google的实施情况。


RFC 没有指定谁选择密码。 按照惯例,服务器通常会尊重客户的偏好。 要确保服务器选择密码套件,您应该将SSL_OP_CIPHER_SERVER_PREFERENCE添加到服务器的上下文选项中。 请参阅SSL_CTX_set_options(3)