【问题标题】:How to add PFS to socket server written in c and openssl如何将 PFS 添加到用 c 和 openssl 编写的套接字服务器
【发布时间】:2014-05-20 16:17:32
【问题描述】:

我尝试将 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 支持。我想我必须选择一条曲线,并且我可能需要为每个连接创建和交换密钥。

我还需要私钥文件吗?如果是的话——它是用来做什么的?

【问题讨论】:

    标签: c sockets openssl


    【解决方案1】:

    其实我错过的是 Diffie-Hellman 参数和椭圆曲线 Diffie-Hellman 的配置。如果你不配置它们...

    PFS 密码套件将被静默忽略

    有关如何在 C 套接字服务器中配置和包含 Diffie-Hellman 参数和椭圆曲线 Diffie-Hellman 的更多信息和示例可在此处找到:http://wiki.openssl.org/index.php/Diffie-Hellman_parameters

    【讨论】:

    • 该声明指或意味着您必须致电SSL_CTX_set_tmp_dh。该声明与密码套件无关。
    【解决方案2】:
    ... then I get an no shared cipher error.
    
    How do I have to modify the ctx to add ECDHE support?
    

    密码套件是客户端和服务器功能的产物。我发现我需要将 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)

    【讨论】:

    • 好吧,即使我在客户端和服务器上使用相同版本的 OpenSSL?我假设出现在可用密码中的一个密码就足够了?
    • @jww - 如何将代码示例中的字符串转换为密码列表?我想偷它:)
    • @Amit - 将const char CIPHERS[] = { 之类的内容添加到列表中,将}; 作为后缀添加到列表中,然后调用SSL_CTX_set_cipher_listSSL_set_cipher_list
    • @jww 谢谢,这是一个很好的观点,但是在这样做之后SSL_set_ciper_list 现在无法选择任何密码......我当前的密码列表使用不同的语法......这里是:@987654333 @
    猜你喜欢
    • 2011-12-01
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-24
    • 1970-01-01
    • 2011-01-18
    相关资源
    最近更新 更多