c++ - 如果我无法提供私钥,如何进行“客户端身份验证”
问题描述
我想设置我的本地服务器以与我的客户进行通信。他们使用 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 以便我能够使用我自己的签名功能。
非常感谢!
解决方案
推荐阅读
- php - 会话变量在php中为空
- c# - 如何遍历 Assets 文件夹中的子文件夹?
- android - 我们如何将三星银河皮肤添加到安卓模拟器中?
- javascript - 由nodeJS中的值总和产生的NaN
- android - Put & Delete 方法在 Retrofit 和 rxjava Android 中不起作用
- c# - 我需要从这个 JSON 中过滤所有的用户组
- java - 将 ObservableLists 用于 GUI 和后台任务的最佳方法是什么?
- shake-build-system - 如何使用shake-build为不同的环境构建?
- c - 有符号整数提升为无符号长整数
- javascript - 小部件的 ApostropheCMS 部署问题