Boost Asio客户端连接自签名证书服务器报dh key too small如何解决
问题原因
dh key too small错误和你是否关闭证书验证没有关联,它是OpenSSL的密钥交换安全校验触发的:你本地OpenSSL默认配置要求DH密钥交换的参数长度不低于2048位,但目标服务器使用的是1024位及以下的弱DH参数,握手阶段校验失败抛出错误。
解决方案
你可以通过以下两种方式修改代码解决问题,二选一即可,也可以同时配置增强兼容性:
- 方案1:降低SSL上下文的安全校验等级,允许短DH密钥
OpenSSL 1.1.0及以上版本支持通过安全等级参数控制校验强度,等级0不限制DH密钥长度,兼容旧服务端。
在初始化sslContext后添加如下代码:SSL_CTX_set_security_level(sslContext.native_handle(), 0); - 方案2:禁用DH类密钥交换套件,从根源规避校验
直接配置加密套件列表,排除所有使用DH密钥交换的算法,改用ECDHE、RSA等不需要DH参数的密钥交换方式:
在初始化sslContext后添加如下代码:sslContext.set_cipher_list("DEFAULT:!DH");
另外你原有代码存在逻辑错误:ioService.run()调用位置错误,你使用的是同步IO接口,不需要提前调用run(),该行代码可以直接删除,否则run()会因为没有待执行的异步任务直接退出,影响后续IO操作。
修改后完整代码
#include <iostream> #include <boost/asio.hpp> #include <boost/asio/ssl.hpp> using namespace std; using namespace boost; int main(){ try{ asio::io_service ioService; asio::ssl::context sslContext(asio::ssl::context::sslv23); // 解决dh key too small问题,两个配置二选一即可,也可以同时添加 SSL_CTX_set_security_level(sslContext.native_handle(), 0); sslContext.set_cipher_list("DEFAULT:!DH"); asio::ip::tcp::resolver resolver(ioService); asio::ip::tcp::resolver::query query("201.175.33.14", "9005"); asio::ip::tcp::resolver::iterator endpointIterator = resolver.resolve(query); boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket(ioService, sslContext); socket.set_verify_mode(asio::ssl::verify_none); SSL_set_tlsext_host_name(socket.native_handle(), "201.175.33.14"); asio::connect(socket.lowest_layer(), endpointIterator); socket.handshake(asio::ssl::stream_base::client); boost::asio::streambuf request; std::ostream requestStream(&request); requestStream << "GET / HTTP/1.0\r\n"; requestStream << "Host: 201.175.33.14\r\n"; requestStream << "Accept: */*\r\n"; requestStream << "Connection: close\r\n\r\n"; asio::write(socket, request); }catch (std::exception& e) { std::cout << e.what(); } return 0; }
内容的提问来源于stack exchange,提问作者Salinas Rodriguez
相关产品推荐
相关产品推荐

