4

我正在尝试建立与服务器计算机的 TLS 连接。我已经使用 openssl CLI 命令创建了根 CA 证书和服务器证书。我创建了通用名称与其 IP 地址相同的服务器证书。根 CA 证书的通用名称是服务器的 FQDN。

我正在使用 openssl 库 API 来建立与服务器的连接。我正在使用 API

int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath)

用于设置 CA 文件查找路径。

当我使用 CAfile 参数指定 CA 文件的路径时,一切正常,将 CApath 参数保留为 NULL。

但是,如果我使用 CApath 参数指定包含 CA 文件的目录的路径,将 CAfile 参数保留为 NULL,则连接会由于证书验证错误而失败。

当我使用wireshark捕获数据包时,我发现我的客户端代码正在从服务器发送“服务器你好”的TLS响应“未知CA”。我使用了与成功连接相同的 CA 证书文件。

根据我在探索 openssl 库源代码时的观察,我推断在我的情况下,CA 文件不被认为是有效的,因此由于某些未知原因而没有被库 API 加载。

有人能告诉我原因吗,如果可能的话,可以告诉我这个问题的解决方案吗?

4

1 回答 1

7

我正在为我自己的问题发布答案,因为我没有从互联网上获得太多关于这个问题的信息,所以我花了很多时间来寻找这个问题的解决方案。我希望这将帮助其他面临类似问题的人。

如果 CApath 不为 null,则 CApath 指向的目录应包含有效的 CA 证书。而且最重要的是CA文件名应该是主题名哈希值。

可以将 CA 文件重命名为其主题名称哈希值,或者可以使用与 CA 文件的 CA 主题名称哈希相同的名称创建指向 CA 文件的软链接。

c_rehash实用程序可用于在 CApath 中创建必要的链接。该命令的语法非常简单。

c_rehash <CApath>

c_rehash 实用程序可能并非在所有 Linux 发行版中都可用。在这种情况下

openssl x509 -in <CA file name> -noout -subject_hash

可用于生成主题名称哈希(例如 e5d93f80)。只需将“.0”附加到此值并使用此名称(e5d93f80.0)创建一个指向 CA 文件的软链接。如果有多个 CA 文件具有相同的主题名称哈希值,则它们的扩展名应该不同(例如 e5d93f80.1)。搜索按分机号码的顺序进行。

opensssl 引入了这种技术来减少 CA 文件查找时间。否则 openssl 可能必须读取 CApath 中的所有文件才能找到匹配的 CA 文件。

于 2015-09-08T07:07:33.517 回答