我正在使用OpenSSL库编写一个小程序,旨在与一个SSLv3服务器建立连接。该服务器分发自签名证书,这导致握手失败并出现以下消息:“在证书链中存在自签名证书的sslv3警报握手失败。”
有没有办法强制进行连接?我尝试通过调用SSL_CTX_set_verify来解决:
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
但是它似乎没有改变任何东西。
有什么建议吗?
我正在使用OpenSSL库编写一个小程序,旨在与一个SSLv3服务器建立连接。该服务器分发自签名证书,这导致握手失败并出现以下消息:“在证书链中存在自签名证书的sslv3警报握手失败。”
有没有办法强制进行连接?我尝试通过调用SSL_CTX_set_verify来解决:
SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
但是它似乎没有改变任何东西。
有什么建议吗?
SSL_set_verify()
不会改变这个过程,请参考相关文档。引用文档中的一段话:static int always_true_callback(X509_STORE_CTX *ctx, void *arg)
{
return 1;
}
SSL_CTX_set_cert_verify_callback(CTX, always_true_callback);
1
将完全禁用证书验证。这与设置 SSL_VERIFY_NONE
相同。(即 @Spidey 是正确的。) 你可能不想这样做,因为这会使你容易受到中间人攻击。正确的做法是将自签名证书添加到受信任证书列表中。(请参阅 SSL_CTX_load_verify_locations()。) - Erwan Legrand您是否尝试将服务器的CA证书提供给您的应用程序,以便您的应用程序可以验证证书链?
X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
,这意味着提到的自签名证书不是服务器的证书,而是根CA的证书。 - Erwan Legrand请查看这些OpenSSL示例:http://www.rtfm.com/openssl-examples/
wclient.c连接到任何https页面,例如:
wclient -h www.yahoo.com -p 443
X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN
,这意味着提到的自签名证书不是服务器的证书,而是根CA的证书。 - Erwan LegrandSSL_set_verify(s, SSL_VERIFY_NONE, NULL);
SSL_set_verify()
,然后进行自己的验证。这并不是理想的解决方法,因为我认为您需要完成所有验证,然后允许忽略自签名错误,但是您应该能够从OpenSSL源代码中了解标准验证代码的运行方式,然后将其简单地放入您自己的验证回调中,并允许特定的错误代码...我的示例客户端代码(链接)可以与自签名的服务器证书正常工作。在SSL_connect之后,我有以下代码,并且完全控制客户端接受自签名证书的可接受性。
SSL_CTX* ctx = SSL_CTX_new(SSLv3_method());
// TCP connection and SSL handshake ...
/* Check the certificate */
rc = SSL_get_verify_result(ssl);
if(rc != X509_V_OK) {
if (rc == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || rc == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) {
fprintf(stderr, "self signed certificate\n");
}
else {
fprintf(stderr, "Certificate verification error: %ld\n", SSL_get_verify_result(ssl));
SSL_CTX_free(ctx);
return 0;
}
}
SSL_VERIFY_NONE
禁用了证书验证。你可能不想这样做,因为这会让你容易受到中间人攻击。正确的做法是将自签名证书添加到可信证书列表中。(请参见SSL_CTX_load_verify_locations()
。) - Erwan Legrand