ssl - OpenSSL 和 CAPI - 证书冲突

标签 ssl openssl certificate collision

我遇到了与 OpenSSL 的 CAPI 引擎的冲突问题:在正常情况下,我可以使用存储在智能卡上的私钥通过 OpenSSL 建立 SSL 连接。简化代码:

    EVP_PKEY pkey = ENGINE_load_private_key(my_engine, subject_name, 0, 0);
    void * pdata = my_certificate_context.pbCertEncoded;
    X509 * cert = d2i_X509(0, &pdata, my_certificate_context.cbCertEncoded);
    SSL_CTX_use_certificate(my_ssl_context, cert);
    SSL_CTX_use_private_key(my_ssl_context, pkey);

但是,有一个问题:如果碰巧我有多个具有给定主题名称的证书,CAPI 引擎将选择其中一个证书,是否选择正确的证书取决于运气。对我来说幸运的是,它选择了错误的一个,这样就提醒了我这个问题。查看源代码,CAPI 引擎似乎支持更复杂的 key 搜索方案,因此我可以指定应该在特定证书存储中找到主题名称。因为我有正确的 PCCERT_CONTEXT,所以我可以很容易地获得证书库的名称,但我不知道如何告诉 CAPI 引擎使用该证书库。这里的文档非常粗略,我找不到一个例子。我希望它可以使用 FENGINE_ctrl_cmd_string 来完成,但我不知道该怎么做。有人可以帮我解决这个问题吗?

最佳答案

经过大量研究和测试,我可以得出结论,可以使用 ENGINE_ctrl_cmd_string 更详细地指定证书的位置:

if (!ENGINE_ctrl_cmd_string(Engine, "store_name", "MY", 0)) printf("Failed!");
if (!ENGINE_ctrl_cmd_string(Engine, "store_flags", "1", 0)) printf("Failed!");

第一行告诉 CAPI 引擎使用不同的证书存储(在本例中为“MY”,但也可以使用任何其他存储,例如“ROOT”)。第二行指示引擎使用本地计算机存储而不是当前用户存储。

但是:

1) 这两个值对于引擎都是全局的。如果需要使用具有不同设置的多个同时连接,每个连接必须有一个单独的引擎。与网络上所写的相反,使用 SSL_CTX_set_client_cert_engine 函数 可能是可能的。在这种情况下,您不需要将引擎设置为默认引擎。 (注意:如果我对两个同时连接使用两个具有不同设置的引擎,我需要对实际发生的情况进行一些测试。到目前为止,它看起来可以工作,但我不确定。)

2) 无法指定当前服务店铺等其他店铺位置。这将需要更新 CAPI 引擎。

3) 无法使用更精确的标识来指定证书,例如通过指定哈希值或序列号。

4) 无论如何指定证书是没有意义的,因为 SSL 引擎将忽略此类指定(实际上任何使用 SSL_CTX_use_certificateSSL_CTX_use_PrivateKey 函数所做的事情)。相反,当执行握手时,它将打开由命令字符串指定的存储并搜索由服务器选择的 CA 签名的证书。我不确定如果找到多个这样的证书会发生什么,我怀疑会向用户显示一个对话框。无论如何,不​​可能通过代码选择特定的证书,除非你想修改引擎的插件。 (注意:如果您打算在服务器端使用证书,情况可能并非如此。)

5) 使用函数 SSL_CTX_use_certificateSSL_CTX_use_PrivateKey 不仅毫无意义,而且实际上是危险的,因为后者将选择第一个匹配的证书(例如与存储中使用相同的主题名称)并使用它,而不管颁发 CA 或其他任何内容。

此信息对 OpenSSL 的 1.0.2 分支有效。我没有对较新或较旧的分支机构进行任何测试。

关于ssl - OpenSSL 和 CAPI - 证书冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51968387/

相关文章:

java - 从工作灯加载 Java 中的特定证书

node.js - 创建客户端证书,将特定 ip 地址添加到证书

c++ - Boost SSL-Server 因 SSLv3 错误而失败

ssl - 共享 SSL 证书作为子域

java - java的cacerts格式应该是什么格式?

OpenSSL:加密/解密例程的输入和输出缓冲区可以相同吗?

ubuntu -/etc/nginx/sites-enabled/default 中 "ssl_certificate_key"指令中的参数数量无效

iOS 证书生成错误 : Disc Quota Exceeded. 这是 Apple 的错误吗?

.net - 是否可以使用 SSL 证书签署我的程序集?

java - 我什么时候得到 javax.net.ssl.SSLHandshakeException : sun. security.validator.ValidatorException: No trusted certificate found