我想设置我的本地服务器来与我的客户端通信。他们使用Openssl建立TLS连接。我尝试实现双面身份验证,例如服务器将验证客户端,而客户端也需要验证服务器。
当我使用自己生成的证书时,一切正常。代码如下。这是客户端中的C ++代码。我设置了客户端证书,私钥和中间证书。在服务器端,我保存了一个CA证书。
关系是:CA签署中间证书,中间证书签署客户证书。
我们知道,我们需要提供客户端私钥的原因是客户端将签名“挑战”然后发送到服务器。服务器可以通过证书链获取客户端公钥,并使用它来解码加密“挑战”以查看它们是否匹配。您可以查看此链接以了解详细的过程: https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake
但是,在我的情况下,我无权获取私钥。我只有一个要调用的API,它将摘要或我们要编码的任何内容作为输入,并返回由客户端私钥编码的字符串。
因此,我无法将任何“ ClientPrivateKeyFileTest”传递给TLS。
我搜索了openssl源代码,但所有握手均在此函数中完成:SSL_do_handshake(),并且不允许修改此函数。
// load client-side cert and key
SSL_CTX_use_certificate_file(m_ctx, ClientCertificateFileTest, SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(m_ctx, ClientPrivateKeyFileTest, SSL_FILETYPE_PEM);
// load intermediate cert
X509* chaincert = X509_new();
BIO* bio_cert = BIO_new_file(SignerCertificateFileTest, "rb");
PEM_read_bio_X509(bio_cert, &chaincert, NULL, NULL);
SSL_CTX_add1_chain_cert(m_ctx, chaincert)
m_ssl = SSL_new(m_ctx);
// get_seocket is my own API
m_sock = get_socket();
SSL_set_fd(m_ssl, m_sock)
// doing handshake and build connection
auto r = SSL_connect(m_ssl);
我认为在我调用SSL_connect()之后所有握手过程都将完成。所以我想知道还有其他方法可以完成客户端身份验证吗?
例如,我可以跳过添加私钥步骤,但在某个地方设置回调函数,该函数可以处理SSL需要使用私钥来计算某些内容的所有情况。
PS:API是客户端计算机中的黑匣子。
还有一件事情,这些天我发现openssl引擎可能有助于解决此问题。但是,有人知道哪种引擎对这个问题有用吗? EC标志,验证或其他?
最终更新:我实现了OpenSSL引擎来重新加载EC_KEY_METHOD,以便能够使用自己的签名功能。
非常感谢!