【问题标题】:setting up an openssl client with a specific cipher in c++在 C++ 中使用特定密码设置 openssl 客户端
【发布时间】:2020-03-18 10:07:10
【问题描述】:

运行 openssl 命令时:

echo | openssl s_client -cipher 'ECDHE-ECDSA-AES128-GCM-SHA256' -connect www.googleapis.com:443 -tls1_2

CONNECTED(00000005)
depth=2 OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
verify return:1
depth=1 C = US, O = Google Trust Services, CN = GTS CA 1O1
verify return:1
depth=0 C = US, ST = California, L = Mountain View, O = Google LLC, CN = *.googleapis.com
verify return:1
---
Certificate chain
 0 s:C = US, ST = California, L = Mountain View, O = Google LLC, CN = *.googleapis.com
   i:C = US, O = Google Trust Services, CN = GTS CA 1O1
 1 s:C = US, O = Google Trust Services, CN = GTS CA 1O1
   i:OU = GlobalSign Root CA - R2, O = GlobalSign, CN = GlobalSign
---
No client certificate CA names sent
Peer signing digest: SHA256
Peer signature type: ECDSA
Server Temp Key: X25519, 253 bits
---
SSL handshake has read 4111 bytes and written 262 bytes
Verification: OK
---
New, TLSv1.2, Cipher is ECDHE-ECDSA-AES128-GCM-SHA256
Server public key is 256 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-ECDSA-AES128-GCM-SHA256
    Session-ID: ...
    Session-ID-ctx: .... 
    Master-Key: ...
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 100800 (seconds)
    Start Time: 1574424718
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: yes
---
DONE


它显示了一个成功的 ssl 连接。

但是,当我在 c++ 代码中设置等效的 ssl 连接时:

asio::ssl::context cntx{asio::ssl::context::tlsv12_client};
cntx.set_options(boost::asio::ssl::context::default_workarounds);
cntx.set_verify_mode(asio::ssl::verify_peer, ec);

constexpr char kCiphers[] = "ECDHE-ECDSA-AES128-GCM-SHA256";
SSL_CTX_set_cipher_list(ssl_cntx, kCiphers));
SSL_CTX_set_ecdh_auto(ssl_cntx, 1);

握手失败,sslv3 alert handshake failure。 当我使用像ECDHE-RSA-AES128-GCM-SHA256 这样的基于 RSA 的密码时,我的 c++ 客户端成功地执行了成功的握手。 “ECDSA”缺少什么?

【问题讨论】:

    标签: c++ ssl openssl


    【解决方案1】:

    ECDSA 密码需要 ECC 证书。此证书仅在客户端使用 SNI 时由服务器配置,即在 ClientHello 中发送预期的主机名。 openssl 1.1.1(您使用)默认执行 SNI,但您的代码不使用 SNI。

    比较s_client 与(默认)SNI(使用openssl 1.1.1):

    $ openssl s_client -cipher 'ECDHE-ECDSA-AES128-GCM-SHA256' -connect www.googleapis.com:443 -tls1_2
    ...
        Cipher    : ECDHE-ECDSA-AES128-GCM-SHA256
    

    并且没有 SNI:

    $ openssl s_client -noservername -cipher 'ECDHE-ECDSA-AES128-GCM-SHA256' -connect www.googleapis.com:443 -tls1_2
    CONNECTED(00000005)
    140265233306048:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1528:SSL alert number 40
    ...
        Cipher    : 0000
    

    至于在您自己的代码中设置 SNI,请参阅 How to implement Server Name Indication (SNI) 或参阅 this code example with boost::asio,它也使用 SSL_set_tlsext_host_name 实现 SNI。

    【讨论】:

    • 对我来说确实如此。 > openssl 版本 OpenSSL 1.1.1 2018 年 9 月 11 日使用 openssl 输出更新问题
    • @Roman:好的,问题有点不同。查看更新的答案。
    • 非常感谢!没有你的帮助,我永远找不到答案!
    猜你喜欢
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-25
    • 2021-11-05
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多