You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

使用OpenSSL建立SSL连接报错:SSL_connect()返回0、SSL_ERROR_SSL

分析SSL_connect返回0且SSL_ERROR_SSL的报错原因

先给你拆解下这个报错的几个核心可能原因,结合你贴的代码来看:

  • 未抓取详细错误栈SSL_ERROR_SSL只是一个笼统的协议层错误标识,没法直接定位问题。你需要在报错后打印OpenSSL的详细错误栈,这才能拿到具体的失败原因(比如证书验证失败、加密套件不兼容、协议版本不匹配等)。可以在SSL_get_error之后添加这段代码:

    ERR_print_errors_fp(stderr);
    // 或者用编程方式逐个获取错误码
    unsigned long err;
    while ((err = ERR_get_error()) != 0) {
        fprintf(stderr, "OpenSSL error: %s\n", ERR_error_string(err, NULL));
    }
    
  • 证书验证未配置:默认情况下,OpenSSL的客户端上下文会强制验证服务器证书的合法性。如果服务器用的是自签名证书,或者你没有加载对应的根CA证书,握手就会失败。你可以先做个测试:临时关闭证书验证(仅用于排查,生产环境绝对不能这么做),看看是否能成功连接:

    // 在创建m_ctx之后添加
    SSL_CTX_set_verify(m_ctx, SSL_VERIFY_NONE, NULL);
    

    如果这样能成功,那就是证书验证的问题,生产环境需要加载正确的CA证书文件:

    if (!SSL_CTX_load_verify_locations(m_ctx, "/path/to/ca-cert.pem", NULL)) {
        // 处理CA证书加载失败的逻辑
    }
    
  • TCP连接未完成SSL_connect的前提是底层的TCP连接已经成功建立(也就是你已经调用了connect函数并且返回成功)。如果你的hSocket还没完成TCP连接就直接调用SSL握手,肯定会触发协议错误。先确认TCP连接是否正常建立。

  • 协议版本兼容性问题:你代码里用的是TLSv1_2_client_method(),如果服务器不支持TLS 1.2(比如只支持TLS 1.3或者更旧的版本),就会导致握手协商失败。建议换成更通用的协议方法,让客户端自动协商支持的最高版本:

    m_ctx = SSL_CTX_new(SSLv23_client_method());
    // 如果需要限制最高版本,可以添加
    SSL_CTX_set_options(m_ctx, SSL_OP_NO_TLSv1_3); // 示例:禁用TLS1.3
    
  • 初始化和资源问题:虽然不是直接导致当前报错的原因,但你的代码有几个可以优化的点:新版本OpenSSL(1.1.0+)已经废弃了SSL_library_init()SSL_load_error_strings(),建议改用OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);另外,代码里没有释放SSLSSL_CTX资源,长期运行会内存泄漏,记得在函数末尾添加:

    SSL_free(m_ssl);
    SSL_CTX_free(m_ctx);
    

内容的提问来源于stack exchange,提问作者Trânf Hà

火山引擎 最新活动