OpenSSL 的相互身份验证始终成功

Posted

技术标签:

【中文标题】OpenSSL 的相互身份验证始终成功【英文标题】:Mutual authentication always succeeds with OpenSSL 【发布时间】:2015-02-08 09:02:10 【问题描述】:

我正在使用 openssl 和 zmq 来编写服务器和客户端。 我的客户端和服务器需要相互身份验证。 但是在我在服务器上设置SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_FAIL_IF_NO_PEER_CERT,NULL) 之后,无论客户端是否发送证书,握手总是成功的。 另外SSL_get_peer_certificate(tls->get_ssl_())返回null,SSL_get_verify_result(tls->get_ssl_())返回0,表示X509_V_OK

我现在真的很困惑和绝望。有什么建议或更正吗?

这是我的代码的一部分:

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

const SSL_METHOD *meth;
SSL_CTX *ssl_ctx;

     //**************************part of client************************
  
    meth = SSLv23_client_method();
    ssl_ctx = SSL_CTX_new(meth);   


    SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_PEER,NULL);

    int rc1 = SSL_CTX_load_verify_locations(ssl_ctx, ".\\demoCA\\private\\server_chain.pem",".\\demoCA\\private\\");///   
     SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx,"pw");

     std::string cert_chain(".\\demoCA\\private\\client_chain.pem");
     std::string cert(".\\demoCA\\private\\client_crt.pem");
     std::string key(".\\demoCA\\private\\client_key.pem");

     int code = SSL_CTX_use_certificate_chain_file(ssl_ctx,cert_chain.c_str());

     if (code != 1)
    
         std::cout<<"error1\n";
        //throw TLSException("failed to read credentials.");
     
    code = SSL_CTX_use_PrivateKey_file(ssl_ctx,key.c_str(),SSL_FILETYPE_PEM);   
    i f (code != 1)
    
        std::cout<<"error2\n";
        //throw TLSException("failed to read credentials.");
    
    if(!SSL_CTX_check_private_key(ssl_ctx))
    
        std::cout<<"key wrong";
        system("pause");
        exit(0);
    
   

//*****************part of server****************************

    meth = SSLv23_server_method();
    ssl_ctx = SSL_CTX_new(meth);

    SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_FAIL_IF_NO_PEER_CERT,NULL)   
    SSL_CTX_set_client_CA_list(ssl_ctx,SSL_load_client_CA_file(".\\demoCA\\private\\client_chain.pem"));//

    SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx,"pw");

    std::string cert_chain(".\\demoCA\\private\\server_chain.pem");
    std::string cert(".\\demoCA\\private\\server_crt.pem");
    std::string key(".\\demoCA\\private\\server_key.pem");

    int rc = SSL_CTX_use_certificate_file(ssl_ctx,cert.c_str(),SSL_FILETYPE_PEM);

    if (rc!=1)
    
        //throw TLSException("failed to read credentials.");
        std::cout<<"error1\n";
    

    rc = SSL_CTX_use_PrivateKey_file(ssl_ctx,key.c_str(),SSL_FILETYPE_PEM);

    if (rc!=1)
    
        //throw TLSException("failed to read credentials.");   
        std::cout<<"error2\n";
    

    int rcode = SSL_CTX_check_private_key(ssl_ctx);
    if(rcode!=1)
    
        std::cout<<"key wrong";
        system("pause");
        //exit(0);
    

【问题讨论】:

另请参阅 OpenSSL wiki 上的 Library Initialization。您无需拨打四个启动电话。 你的意思是这个? OpenSSL_add_all_algorithms(); SSL_library_init(); SSL_load_error_strings(); ERR_load_BIO_strings(); 【参考方案1】:

来自documentation of SSL_CTX_set_verify:

SSL_VERIFY_FAIL_IF_NO_PEER_CERT

服务器模式:如果客户端没有返回证书,则 TLS/SSL 握手会立即终止,并发出“握手失败”警报。 此标志必须与 SSL_VERIFY_PEER 一起使用。

您没有按照文档中的说明将它与SSL_VERIFY_PEER 一起使用,因此它没有效果。

【讨论】:

天哪!非常感谢 !!!我注意到了那个注释,但是我用错了,我认为这意味着在客户端上使用 SSL_VERIFY_PEER! 非常感谢,阻止我在这个愚蠢的错误上浪费更多时间。 嘿... ..我这里还有一个问题,***.com/questions/29211061/…。请你看一下好吗?什么叫这种问题,有什么想法吗?

以上是关于OpenSSL 的相互身份验证始终成功的主要内容,如果未能解决你的问题,请参考以下文章

Laravel Passport身份验证问题:始终返回未经身份验证的身份

OpenSSL 客户端基于证书的身份验证失败

Django REST 框架:令牌身份验证不适用于生产

WCF与相互身份验证

护照身份验证 req.isAuthenticated 始终为 false

登录身份验证始终返回 true