以编程方式验证 SSL 证书

发布于 2024-11-10 07:24:14 字数 2311 浏览 4 评论 0原文

我知道这将是一篇很大的文章,但我想通过本质上给出它的所有细节来提出我面临的问题。

背景 我有一个应用程序,它触发 Firefox 获取 URL 数据并显示网页中所有组件的单个组件加载时间(如 Firebug)。但是,该应用程序不会自动验证 ssl 证书(即,如果证书错误,它就会卡住,因为没有用户手动接受/拒绝证书,而且这一切都是以编程方式完成的)。我需要通过在 Firefox 进程启动之前尝试验证站点的证书来解决此问题。

我的解决方案

我发现这段 C 代码可以在 C 中以编程方式验证 SSL 证书。我对其进行简要概述。这是 main() 方法:

SSL_library_init();
ERR_load_BIO_strings();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();

/* Set up the SSL context */
ctx = SSL_CTX_new(SSLv23_client_method());

/* Load the trust store - in this case, it's just a single
 * certificate that has been created for testing purposes.
 */

if(! SSL_CTX_load_verify_locations(ctx,"certificate.pem",NULL))
{
    fprintf(stderr, "Error loading trust store\n");
    //ERR_print_errors_fp(stderr);
    SSL_CTX_free(ctx);
    return 0;
}

/* Setup the connection */
bio = BIO_new_ssl_connect(ctx);

/* Set the SSL_MODE_AUTO_RETRY flag */

BIO_get_ssl(bio, & ssl);
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

/* Create and setup the connection */

BIO_set_conn_hostname(bio, "mail.google.com:https");

fprintf(stderr, "Connecting to host ...\n");

if(BIO_do_connect(bio) <= 0)
{
    fprintf(stderr, "Error attempting to connect: %d\n",BIO_do_connect(bio));
    //ERR_print_errors_fp(stderr);
    BIO_free_all(bio);
    SSL_CTX_free(ctx);
    return 0;
}
/* Retrieve the peer certificate */

fprintf(stderr, "Retrieving peer certificate\n");
if(getPeerCert(ssl, & peerCert) != X509_V_OK)
{
    /* Can be changed to better handle a suspect certificate. However,
     * for the purposes of this demonstration, we're aborting.
     */
    fprintf(stderr, "Certificate verification error: %i\n",SSL_get_verify_result(ssl));
    BIO_free_all(bio);
    SSL_CTX_free(ctx);
    return 0;
}

我省略了 getPeerCert() 方法的定义,因为它获取对等证书并使用 openssl 的方法进行验证。

另外,certificate.pem 是通过执行

但是,当我尝试运行此程序时,

Connecting to host ...
Retrieving peer certificate
Certificate verification error: 20

我无法理解为什么会发生这种情况,因为验证应该成功。对于我能得到的任何帮助,我将不胜感激并感到高兴。

更新1

我尝试使用open SSL命令并尝试从代码调用该命令,即

opensssl verify -CAfile ./ca-bundle.crt cert1...

但是我发现它验证内部和外部证书,它似乎也验证实际上应该是坏的证书(内部) (特别是错误的域证书)。我将非常感谢对此的任何见解。

I know this will be a huge post, but I wanted to present a problem that I am facing by essentially giving all the details of it.

Background
I have an application which triggers firefox to fetch URL data and present the individual component load time of all components in a web page (like Firebug). However the application does not validate ssl certs automatically (i.e it gets stuck up if there is a bad certificate as there is no user to manually accept/reject a certificate and it is all done programmatically). I need to solve this issue by trying to validate the site's certificate before the firefox process is started.

My solution

I found this bit of C code that does verification of SSL certs programmatically in C. I am giving a brief overview of it. this is the main() method:

SSL_library_init();
ERR_load_BIO_strings();
SSL_load_error_strings();
OpenSSL_add_all_algorithms();

/* Set up the SSL context */
ctx = SSL_CTX_new(SSLv23_client_method());

/* Load the trust store - in this case, it's just a single
 * certificate that has been created for testing purposes.
 */

if(! SSL_CTX_load_verify_locations(ctx,"certificate.pem",NULL))
{
    fprintf(stderr, "Error loading trust store\n");
    //ERR_print_errors_fp(stderr);
    SSL_CTX_free(ctx);
    return 0;
}

/* Setup the connection */
bio = BIO_new_ssl_connect(ctx);

/* Set the SSL_MODE_AUTO_RETRY flag */

BIO_get_ssl(bio, & ssl);
SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);

/* Create and setup the connection */

BIO_set_conn_hostname(bio, "mail.google.com:https");

fprintf(stderr, "Connecting to host ...\n");

if(BIO_do_connect(bio) <= 0)
{
    fprintf(stderr, "Error attempting to connect: %d\n",BIO_do_connect(bio));
    //ERR_print_errors_fp(stderr);
    BIO_free_all(bio);
    SSL_CTX_free(ctx);
    return 0;
}
/* Retrieve the peer certificate */

fprintf(stderr, "Retrieving peer certificate\n");
if(getPeerCert(ssl, & peerCert) != X509_V_OK)
{
    /* Can be changed to better handle a suspect certificate. However,
     * for the purposes of this demonstration, we're aborting.
     */
    fprintf(stderr, "Certificate verification error: %i\n",SSL_get_verify_result(ssl));
    BIO_free_all(bio);
    SSL_CTX_free(ctx);
    return 0;
}

I am leaving out the getPeerCert() method's defenition as it gets the peer cert and verifies using openssl's methods.

Also the certificate.pem is a pem file obtained by following the steps for the solution to this question.

However When I try to run this i get

Connecting to host ...
Retrieving peer certificate
Certificate verification error: 20

I am unable to see why this should happen as the verification should succeed. I would be grateful and glad to any help that I can get.

Update 1

I tried using the open SSL command and tried calling the command from code i.e. the

opensssl verify -CAfile ./ca-bundle.crt cert1...

However I found that it validates internal and external certs, it also seemed to validate certs (internal) that should actually be bad (specifically bad domain certs). I would greatly appreciate any insight into this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

聚集的泪 2024-11-17 07:24:14
opensssl verify -CAfile ./ca-bundle.crt -untrusted cert1...

看到这篇文章,但我还不知道如何以编程方式执行此操作。

http://www .herongyang.com/crypto/openssl_verify_2.html\

opensssl verify -CAfile ./ca-bundle.crt -untrusted cert1...

see this article, but I don't know yet how to do it programatically..

http://www.herongyang.com/crypto/openssl_verify_2.html\

北笙凉宸 2024-11-17 07:24:14

您遇到的特定错误

20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate

the issuer certificate could not be found: this occurs if the issuer certificate of an untrusted certificate cannot be found.

尝试输入 gmail 颁发者,而不是Gmail 证书,转换为certificate.pem。

另外,请确保您理解布鲁诺对您的问题的第一条评论。

The specific error you are are getting is

20 X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: unable to get local issuer certificate

the issuer certificate could not be found: this occurs if the issuer certificate of an untrusted certificate cannot be found.

Try putting the gmail issuer, and not the gmail certificate, into certificate.pem.

Also, make sure you understand Bruno's first comment on your question.

流年里的时光 2024-11-17 07:24:14

用户CertificateFactory获取X509证书的实例并使用generateCertificate方法进行验证,这是java安全

try{
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
    X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(${certificate});
catch (CertificateException ex){}

cmd中的lib来验证证书

openssl x509 -text -noout

User CertificateFactory to get instance of X509 cert and validate using generateCertificate method this is lib in java security

try{
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X509");
    X509Certificate cert = (X509Certificate) certificateFactory.generateCertificate(${certificate});
catch (CertificateException ex){}

cmd to verify cert

openssl x509 -text -noout
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文