我是一个学生,对于openssl使用熟练程度很低,在使用ssl协议建立连接时出现了这种报错:SSL connection failed:sslv3 alert handshake failure,上百度查了很多东西,思考了一天,也还是不能解决这个问题,下面是c语言初始化ssl的过程:
//初始化SSL接口
int init_SSL(int tcp_fd, SSL **ssl, SSL_CTX **ctx)
{
int n, ret;
/* 初始化https的SSL加密协议 */
//加载错误字符串资源
SSL_load_error_strings();
//初始化SSL库
SSL_library_init();
//新建SSL会话
*ctx = SSL_CTX_new(SSLv23_client_method());
if (*ctx == NULL)
{
fprintf(stderr, "init SSL CTX failed:%s\n",
ERR_reason_error_string(ERR_get_error()));
return -1;
}
//根据会话新建SSL加密
*ssl = SSL_new(*ctx);
if (*ssl == NULL)
{
fprintf(stderr, "new SSL with created CTX failed:%s\n",
ERR_reason_error_string(ERR_get_error()));
return -1;
}
//绑定文件描述符,tcp_fd是连接完服务器的文件描述符
ret = SSL_set_fd(*ssl, tcp_fd);
if (ret == 0)
{
fprintf(stderr, "add SSL to tcp socket failed:%s\n",
ERR_reason_error_string(ERR_get_error()));
return -1;
}
//错误出现在这里的,和目标服务器已经建立tcp连接了,但是ssl不行
/* 利用SSL加密连接服务器 */
ret = SSL_connect(*ssl);
if (ret != 1)
{
fprintf(stderr, "SSL connection failed:%s\n",
ERR_reason_error_string(ERR_get_error()));
return -1;
}
return 0;
}
注:linux上命令行get请求访问该api没有什么问题(有返回的json代码),这部分代码访问其他的api建立ssl也没有问题。
系统:ubuntu16.04
openssl version : OpenSSL 1.1.1s 1 Nov 2022
希望你们可以帮我解决问题,我将不胜感激!
这个错误表示SSL连接失败,因为客户端和服务器之间的协商失败了。通常可能是由于客户端和服务器之间的TLS版本不一致,或者服务器上的SSL证书不可信,或者服务器上的SSL证书已过期导致的。
要解决这个问题,可以尝试以下操作:
1.确保客户端和服务器之间使用的TLS版本是一致的。
2.检查服务器上的SSL证书是否有效,并确保其未过期。
3.尝试使用不同的SSL协议,比如TLS 1.1或1.2。
4.如果以上这些都无济于事,可以尝试重新安装服务器上的SSL证书。
参考GPT和自己的思路,这个错误通常意味着SSL/TLS握手过程失败,其中SSLv3握手失败的原因可能是与SSLv3版本相关的安全性问题,因此通常不建议使用SSLv3。在这种情况下,建议尝试使用更安全的TLS协议版本,如TLSv1.0,TLSv1.1或TLSv1.2。
以下是建议的解决方法:
1 尝试使用TLSv1.0,TLSv1.1或TLSv1.2协议版本,这些协议版本比SSLv3更安全。您可以使用SSL_CTX_set_options函数指定支持的TLS版本。
2 确保目标服务器支持您正在使用的SSL/TLS协议版本。可以使用openssl s_client命令测试目标服务器的支持协议版本。例如,要测试TLSv1.2支持,请使用以下命令:
openssl s_client -connect servername:port -tls1_2
3 如果目标服务器仅支持SSLv3,则可能需要与服务器管理员联系以升级SSL/TLS支持。
4 检查证书是否正确。如果证书无效或与服务器不匹配,则SSL握手可能会失败。
如果您想尝试使用更安全的TLS协议版本(如TLSv1.0,TLSv1.1或TLSv1.2),则可以使用以下代码:
int init_SSL(int tcp_fd, SSL **ssl, SSL_CTX **ctx)
{
int n, ret;
/* 初始化https的SSL加密协议 */
//加载错误字符串资源
SSL_load_error_strings();
//初始化SSL库
SSL_library_init();
//新建SSL会话
*ctx = SSL_CTX_new(TLSv1_2_client_method()); // 使用TLSv1.2协议
if (*ctx == NULL)
{
fprintf(stderr, "init SSL CTX failed:%s\n",
ERR_reason_error_string(ERR_get_error()));
return -1;
}
//根据会话新建SSL加密
*ssl = SSL_new(*ctx);
if (*ssl == NULL)
{
fprintf(stderr, "new SSL with created CTX failed:%s\n",
ERR_reason_error_string(ERR_get_error()));
return -1;
}
//绑定文件描述符,tcp_fd是连接完服务器的文件描述符
ret = SSL_set_fd(*ssl, tcp_fd);
if (ret == 0)
{
fprintf(stderr, "add SSL to tcp socket failed:%s\n",
ERR_reason_error_string(ERR_get_error()));
return -1;
}
/* 利用SSL加密连接服务器 */
ret = SSL_connect(*ssl);
if (ret != 1)
{
fprintf(stderr, "SSL connection failed:%s\n",
ERR_reason_error_string(ERR_get_error()));
return -1;
}
return 0;
}
在此修改后,程序将使用TLSv1.2协议版本建立与服务器的SSL连接。请注意,您可以使用SSL_CTX_set_options函数指定支持的TLS版本。例如,要同时支持TLSv1.0,TLSv1.1和TLSv1.2,请使用以下代码:
SSL_CTX_set_options(*ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
如果对您有帮助,请给与采纳,谢谢。
该回答引用ChatGPT
您遇到的错误信息 "SSL connection failed:sslv3 alert handshake failure" 表示 SSL 握手失败,可能是由于 SSL/TLS 版本不兼容或证书问题引起的。为了解决这个问题,您可以尝试以下几个步骤:
1、检查 SSL/TLS 版本
根据错误信息,您正在尝试使用 SSLv3 进行握手,但 SSLv3 已经被废弃,现代浏览器和服务器不再支持。您应该尝试使用更现代和更安全的协议,例如 TLSv1.2 或 TLSv1.3。可以通过在 SSL_CTX_new() 中使用相应的方法来选择 SSL/TLS 版本,例如 SSL_CTX_new(TLS_client_method())。
2、检查证书
SSL 握手需要服务器证书来验证服务器的身份,并使用客户端证书验证客户端身份(如果服务器需要)。如果证书无效或不匹配,握手将失败。请确保您的服务器证书有效,并且您的客户端代码已正确配置以使用它。您可以尝试使用 openssl s_client 命令来测试服务器证书和 SSL/TLS 连接,以验证它们是否正确。
3、检查其他配置
还有一些其他可能导致 SSL 握手失败的配置问题,例如启用了 SSL 协议中的某些选项或关闭了某些选项。您可以尝试根据您的需求调整 SSL/TLS 配置选项,以查看是否可以解决问题。
这个错误通常表示 SSL 链接失败,可能是因为客户端和服务器之间存在协议或密码套件不匹配的问题。SSL/TLS 协议的版本和密码套件必须在客户端和服务器之间协商一致,否则链接将会失败。
在这段代码中,SSLv23_client_method() 表示使用 SSLv2、SSLv3、TLSv1 等协议中的一个最高版本进行加密,这可能导致链接失败。因为 SSLv3 和 TLSv1 已经被广泛认为是不安全的协议,因此许多服务器已经禁用了它们。建议使用更安全的协议,例如 TLSv1.2 或 TLSv1.3。
您可以尝试使用 TLSv1.2_client_method() 或 TLSv1.3_client_method() 代替 SSLv23_client_method(),看看是否能够解决此问题。如果仍然存在问题,您可以尝试检查客户端和服务器之间的 SSL/TLS 版本和密码套件配置是否一致,也可以尝试打开调试日志以获得更多信息。
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
该报错通常是由于SSL握手期间协议版本不匹配导致的。根据openssl版本更新,1.1.1s应该默认是支持TLSv1.3协议的。因此,建议升级SSL协议版本为TLSv1.2或TLSv1.3。
修改方法:
示例代码:
*ctx = SSL_CTX_new(TLSv1_2_client_method());
if (*ctx == NULL)
{
fprintf(stderr, "init SSL CTX failed:%s\n",
ERR_reason_error_string(ERR_get_error()));
return -1;
}
示例代码:
*ctx = SSL_CTX_new(SSLv3_client_method());
if (*ctx == NULL)
{
fprintf(stderr, "init SSL CTX failed:%s\n",
ERR_reason_error_string(ERR_get_error()));
return -1;
}
需要注意的是,启用SSLv3协议存在安全隐患,因为该协议已被认为是不安全的。所以,建议仅在必须使用SSLv3协议的情况下才启用该协议。
另外,检查服务器证书是否正确也是一个解决问题的重要步骤。可以通过SSL_get_verify_result()函数检查证书的有效性。如果证书无效,则可能会导致SSL连接失败。
示例代码:
SSL_CTX_set_verify(*ctx, SSL_VERIFY_PEER, NULL);
ret = SSL_get_verify_result(*ssl);
if (ret != X509_V_OK)
{
fprintf(stderr, "certificate verify failed:%s\n",
X509_verify_cert_error_string(ret));
return -1;
}
希望以上方法可以帮助你解决问题。
如果我的回答解决了您的问题,请采纳!
SSL/TLS 版本
这个错误提示是SSL协议握手失败了。可能的原因包括:
SSL版本不兼容:客户端和服务器端使用的SSL协议版本不一致。你可以尝试修改代码中 SSLv23_client_method() 为 TLSv1_2_client_method(),或者更高版本,看看是否能够解决问题。
证书验证失败:你需要检查目标服务器的 SSL 证书是否正确并且可信,或者考虑禁用证书验证来排除此项问题。
密码套件不匹配:客户端和服务器端支持的密码套件不一致,你可以尝试强制使用某个密码套件,或者通过升级 OpenSSL 库来支持更多的密码套件。
你可以尝试对比目标服务器的 SSL 配置和你的代码实现来找出问题的原因。另外,建议使用调试工具或者日志来帮助排查问题。