【问题标题】:SSL Certificate Verification programmatically以编程方式进行 SSL 证书验证
【发布时间】:2011-05-27 18:56:40
【问题描述】:

我知道这将是一个巨大的帖子,但我想通过提供它的所有细节来展示我面临的一个问题。

背景 我有一个应用程序触发 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是按照this问题解答步骤得到的pem文件。

但是当我尝试运行它时,我得到了

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

我不明白为什么会发生这种情况,因为验证应该会成功。如果能得到任何帮助,我将不胜感激。

更新 1

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

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

但是我发现它验证了内部和外部证书,它似乎也验证了实际上应该是坏的证书(内部)(特别是坏的域证书)。对此我将不胜感激。

【问题讨论】:

  • 您要建立两个连接吗?先用您的应用程序验证证书,然后再用 Firefox 验证证书?在这种情况下,从技术上讲,您并不真正知道 Firefox 是否提供了相同的证书,因此验证第一个证书毫无意义。我不太确定您为什么要使用 Firefox 来获取您的页面。那里有许多 HTTP 客户端库,支持 SSL/TLS,这更适合这样做。
  • 嗨,firefox 部分是为了模拟有/没有主缓存的真实用户会看到什么。我不确定我是否理解您提出的不同 ecrts 的问题。我首先验证这一点,如果失败,我根本不会启动 firefox。
  • 我真正担心的是,即使在获得所需的证书之后。这失败了,我不知道为什么
  • 更新: 虽然我无法为任何使用 SSL 证书(如 gmail/facebook 等)的外部网站这样做,但我能够在内部网站上使用它跨度>

标签: openssl ssl-certificate verification


【解决方案1】:

你得到的specific error

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。

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

【讨论】:

  • 谢谢..这听起来可能很愚蠢。但我不是这方面的专家。即使在放置发行者证书后,我也会收到此错误。我不知道!
【解决方案2】:
opensssl verify -CAfile ./ca-bundle.crt -untrusted cert1...

请参阅这篇文章,但我还不知道如何以编程方式进行操作..

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-29
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 2011-07-02
    • 1970-01-01
    • 2013-04-23
    相关资源
    最近更新 更多