如果私钥在 HSM 中,如何生成证书?

How to generate certificate if private key is in HSM?

我经常使用openssl来生成RSA密钥和证书。但是现在我遇到了一个问题。 openssl x509 -req 需要私钥作为输入。但现在我们使用 HSM 来保护私钥,我永远无法触及私钥。这样我应该如何生成x509证书?

使用 HSM 支持的函数(通常是 HSM 提供者支持并提供所需的库)如 encrypt()decrypt()sign() 来获取所需的数据。您无法从 HSM 获取私钥对象,也无法将 openssl 用于 HSM。

我见过 一些 HSM 带有自己的支持程序,可用于各种用途,包括密钥生成和证书或 CSR 创建,或使它们可用(用于供应商网站上的示例);你检查了吗? 假设这不是一个(好的)选择:

您没有识别您的 HSM;有成千上万的模型至少有数百个接口,尽管很大一部分(不是几乎所有)使用 "standard"(大部分)PKCS#11 接口。

OpenSSL 有一个相当开放的ENGINE API,它将密码函数的一些子集——例如私钥生成、签名和解密——重定向到一个不同于 OpenSSL 的正常实现的实现——比如 HSM . OpenSSL 带有一些内置的引擎——至少在默认情况下是这样;特定构建(例如 Linux 发行版的包)可能会省略内置引擎,在这种情况下,您可能需要自己构建。其他人也可以编写引擎模块,包括但不限于特定 HSM 型号或生产线的制造商或供应商,包括您。

  1. 如果您的 HSM 是具有内置引擎的 HSM 之一,请根据其文档根据需要配置该引擎,并为您的 openssl 使用适当的 -engine id-*engine id 选项(子)命令。

注意req -new生成证书只需要-x509,通常加上一些相关的参数,这样生成的证书是自签名的;否则 req -new 会生成证书签名请求 (CSR),然后您将 CA "convert" 转换为 CA 签名的 "real" 证书(PKCS#10 CSR 本身是 总是 自签名)。 req 也可以生成一个新的私钥而不是使用现有的私钥,这一代可以是 "in" HSM 上的引擎。

  1. 如果您的 HSM 没有内置引擎但有来自其他方的引擎,请将其安装到您的系统中。 PKCS#11 就是这种情况。这可能需要将您的 OpenSSL 版本更改为引擎支持的版本。然后按照1进行:配置引擎并使用它。

  2. 如果您的 HSM 没有任何引擎,但其 API 提供了 OpenSSL 在引擎中所需的操作,您可以为其编写(并调试!)一个引擎模块。然后使用您的引擎按照 1 中的步骤进行。还要考虑向全世界提供您的引擎模块,社区使用这种类型的 HSM,and/or OpenSSL 项目。

  3. 如果您的 HSM 功能不适合引擎 API,或者不存在引擎模块并且您不想创建一个,您可以改为编写自己的程序,使用 openssl/apps/req.c 中的一些(可能很多)代码生成私钥 and/or 在您的 HSM 上使用现有私钥 ,构建证书的数据结构(或 CSR)以或多或少的现有方式在 OpenSSL 中,然后给 X509_[REQ_]sign_ctx 一个 EVP_PKEY(OpenSSL 中用于各种类型的非对称密钥的多态 C 数据结构)设置自定义方法,使用您的 HSM API(以及 HSM 上密钥的一些标识)进行签名。 确保您程序上的任何许可都与 OpenSSL 许可兼容(本质上是 BSD 广告风格)。

大多数 HSM 都有 PKCS#11 驱动程序。您可以使用 OpenSC 的 engine_pkcs11 to enable OpenSSL to leverage an HSM (or a smartcard). There's a document 了解如何使用它创建请求。

您需要安装和配置 PKCS#11 中间件(驱动程序),编译 engine_pkcs11 模块,并且可能需要对上述说明进行一些改编。