Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ SSL证书,不通过thrift进行身份验证,但通过浏览器确认_C++_Ssl_Openssl_Thrift - Fatal编程技术网

C++ SSL证书,不通过thrift进行身份验证,但通过浏览器确认

C++ SSL证书,不通过thrift进行身份验证,但通过浏览器确认,c++,ssl,openssl,thrift,C++,Ssl,Openssl,Thrift,这是我生成SSL证书、密钥等的方式: openssl genrsa -out server.key 1024 openssl rsa -in server.key -out new_key.pem openssl req -new -key server.key -out server.csr openssl x509 -req -days 10000 -in server.csr -signkey new_key.pem -out server.crt 这是可行的,我可以在chrome中看到

这是我生成SSL证书、密钥等的方式:

openssl genrsa -out server.key 1024
openssl rsa -in server.key -out new_key.pem
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 10000 -in server.csr -signkey new_key.pem -out server.crt
这是可行的,我可以在chrome中看到输出,尽管我得到一个警告,我将首先感染病毒

openssl s_server -cert server.crt -www -key new_key.pem
这是来自服务器的一个片段。老实说,虽然我有个好主意,但我不确定每一行都在做什么:

socketFactory->server(true); // this is the server
socketFactory->authenticate(false); // no auth?
socketFactory->loadCertificate("server.crt"); 
socketFactory->loadPrivateKey("new_key.pem");
客户:

socketFactory->loadTrustedCertificates("server.crt");
socketFactory->authenticate(true); //auth? wierd, right? This guy does this:[1]
shared_ptr <TSSLSocketFactory> socketFactory = shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
socketFactory->loadTrustedCertificates("server.crt");
socketFactory->authenticate(false);
shared_ptr <TSSLSocket>socket = socketFactory->createSocket(configuration.ip, configuration.port);
shared_ptr<TBufferedTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
SkullduggeryClient client(protocol);
transport->open();
[1]

如果我在客户机中注释掉
loadTrustedCertificates
,则会得到一个SSL未验证证书异常。 保留该行后,我得到一个身份验证失败异常

这里有两个更长的代码片段,可以更好地理解上述代码片段。
服务器:

shared_ptr handler(新的SkullduggeryHandler());
共享ptr传输工厂=
共享(新的TBufferedTransportFactory());
共享的ptr协议工厂(新的TBinaryProtocolFactory());
共享ptr处理器(新的SkullduggeryProcessor(handler));
共享\u ptr socketFactory=
共享ptr(新TSSLSocketFactory());
socketFactory->server(true);
socketFactory->验证(假);
socketFactory->loadCertificate(“server.crt”);
socketFactory->loadPrivateKey(“new_key.pem”);
共享ptr套接字(新的TSSLServerSocket(端口,socketFactory));
TThreadedServer服务器(处理器,
插座
运输厂,
原型工厂);
server.service();
客户:

socketFactory->loadTrustedCertificates("server.crt");
socketFactory->authenticate(true); //auth? wierd, right? This guy does this:[1]
shared_ptr <TSSLSocketFactory> socketFactory = shared_ptr<TSSLSocketFactory>(new TSSLSocketFactory());
socketFactory->loadTrustedCertificates("server.crt");
socketFactory->authenticate(false);
shared_ptr <TSSLSocket>socket = socketFactory->createSocket(configuration.ip, configuration.port);
shared_ptr<TBufferedTransport> transport(new TBufferedTransport(socket));
shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
SkullduggeryClient client(protocol);
transport->open();
shared_ptr socketFactory=shared_ptr(新的TSSLSocketFactory());
socketFactory->loadTrustedCertificates(“server.crt”);
socketFactory->验证(假);
shared_ptr socket=socketFactory->createSocket(configuration.ip,configuration.port);
共享ptr传输(新的缓冲传输(套接字));
共享ptr协议(新的TBinaryProtocol(传输));
Skulldugger客户端(协议);
传输->打开();

感谢您抽出时间阅读此文章。如果有明显的错误,我很高兴听到。这已经是我存在的祸根太久了。太长。

您似乎正在生成自签名证书(这很好),但使用
openssl
实用程序进行的操作令人困惑

第1行正常,它生成一个私钥。
第2行无用:输出键与输入键相同!(尝试区分要查看的两个键)。
第3行生成CSR,第4行实际对其进行自签名,因此它们可以合并到一行中,我们将看到

现在,让我们后退一步,让我们试着了解我们在做什么:-(<)/P> 您正在使用SSL对Thrift服务器和Thrift客户端之间的通信进行身份验证和加密。我想你想两者兼而有之:

  • 保护客户端不受恶意服务器的攻击(您的代码正试图执行的操作)
  • 保护服务器免受恶意客户端的攻击(这对我来说似乎更为重要)
  • 做一个HTTPS类比,(1)是经典的服务器证书,(2)通常是用户的用户名/密码。但是使用Thrift SSL,我们还可以通过向客户端颁发证书来获得相互身份验证

    我将给出的示例将使用自签名证书。它们可以很容易地适应由openssl管理的迷你CA,我将此作为练习留给读者

    生成服务器私钥:
    openssl genrsa-out server-key.pem 2048

    生成关联的公钥并对其进行自签名:
    openssl-req-new-x509-key server-key.pem-out server-cert.pem-10000天

    生成客户端私钥:
    openssl genrsa-out client-key.pem 2048

    生成关联的公钥并对其进行自签名:
    openssl-req-new-x509-key client-key.pem-out client-cert.pem-10000天

    注意:当
    openssl-req
    请求
    公共名称(例如服务器FQDN或您的姓名)
    时,请输入运行Thrift程序的主机的FQDN。这将允许不自定义Thrift的
    AccessManager
    类。另一方面,如果无法预先知道FQDN,则需要继承
    AccessManager
    并相应地重写
    verify()
    方法。请参见
    TSSLSocket.cpp

    很好,现在开始代码

    在服务器端:

    socketFactory->server(true)是多余的,请将其删除

    socketFactory->authenticate(false)
    有点误导。更好的名称应该是
    authenticatePeer
    。如果您说
    false
    ,它将不会对客户端进行身份验证,但我们在需要相互身份验证之前已经决定

    因此,服务器的SSL前导码是:

    try {
        signal(SIGPIPE, SIG_IGN); // See README.SSL
        shared_ptr<TSSLSocketFactory> sslSocketFactory(new TSSLSocketFactory());
        sslSocketFactory->loadPrivateKey(myKey);
        sslSocketFactory->loadCertificate(myCert);
        sslSocketFactory->authenticate(true);
        sslSocketFactory->loadTrustedCertificates(trustedCerts);
        sslSocketFactory->ciphers("HIGH:!DSS:!aNULL@STRENGTH");
        ...
        } catch (TException& tx) {
            ....
        }
    
    试试看{
    信号(SIGPIPE,SIG_IGN);//参见README.SSL
    共享ptrsslsocketfactory(新的TSSLSocketFactory());
    sslSocketFactory->loadPrivateKey(myKey);
    sslSocketFactory->装载证书(myCert);
    sslSocketFactory->验证(true);
    sslSocketFactory->loadTrustedCertificates(trustedCerts);
    sslSocketFactory->密码(“高:!DSS:!aNULL@STRENGTH");
    ...
    }捕获(TException和tx){
    ....
    }
    
    其中
    myKey
    server key.pem
    myCert
    server-cert.pem
    trustedCerts
    是。。。受信任CA的证书,如果是自签名证书,则为客户端的证书。您可以
    cat
    在同一文件中一个接一个地创建多个证书。在我们的示例中,我们将放置以前创建的
    client-cert.pem

    客户端的SSL前导码完全相同,具有正确的客户端私钥、客户端证书,对于
    trustedCerts
    ,还有我们之前创建的对等方的证书:
    server-cert.pem

    仅此而已:-)在开始编写代码之前,请尝试理解,如果您不清楚SSL(相互)身份验证是如何工作的,则很难理解错误消息。我展示的代码经过测试可以正常工作

    不幸的是,在文档方面,节俭是不可取的