使用OpenSSL Dynamic Engine调用CloudHSM加密机内的密钥完成签名和证书签发
本文介绍如何在 Ubuntu 22.04 上使用 AWS CloudHSM OpenSSL Dynamic Engine 完成密钥管理和证书操作。内容涵盖 Dynamic Engine 与OpenSSL Provider 的对比选型、引擎安装配置、RSA 和 ECC(P-256)密钥对的创建与导出、使用 SHA256withRSA 和 SHA256withECDSA进行签名与验签,以及基于 CloudHSM 私钥生成自签名证书和签发下级证书的完整流程。所有签名操作均在 HSM内完成,私钥始终不离开硬件安全模块。
本文介绍如何使用OpenSSL的Dynamic Engine,实现在OpenSSL命令行下调用CloudHSM加密机内的密钥完成签名和证书签发操作。
一、OpenSSL Dynamic Engine 与 OpenSSL Provider 的区别
AWS CloudHSM 提供了两种与 OpenSSL 集成的方式:Dynamic Engine 和 Provider 。在开始操作之前,需要先了解二者的区别和各自的限制。
1、功能对比
| 对比项 | Dynamic Engine | Provider |
|---|---|---|
| OpenSSL 版本要求 | OpenSSL 1.0.2+ | OpenSSL 3.2+ |
| OpenSSL CLI 命令行支持 | ✅ 支持(-engine cloudhsm) |
❌ 明确不支持 |
| 支持的 Web 服务器 | NGINX / Apache | NGINX / HAProxy |
| RSA 签名 | ✅ PKCS#1 v1.5 | ✅ PKCS#1 v1.5 + PSS 填充 |
| ECDSA 签名 | ✅ P-256, P-384, secp256k1 | ✅ P-256, P-384, P-521 |
| 验签 | 本地 OpenSSL 软件完成 | 本地 OpenSSL 软件完成 |
关于 OpenSSL Provider 的重要警告: 官方文档明确声明 “Integration with OpenSSL CLI is not currently supported by AWS CloudHSM OpenSSL Provider”,即 Provider 完全不支持 OpenSSL 命令行集成,Provider这种集成方式只能用于在NGINX上的Offload场景。
2、各自适用场景
OpenSSL Dynamic Engine 适用于:
- 需要通过 OpenSSL 命令行进行签名操作(如
openssl dgst -engine cloudhsm) - 需要通过 OpenSSL 命令行生成 CSR 和自签名证书
- 使用 NGINX 或 Apache 做 SSL/TLS 卸载
- 运行在 OpenSSL 3.2 以下版本的系统上
OpenSSL Provider 适用于:
- 使用 OpenSSL 3.2+ 的新部署环境
- 使用 NGINX 或 HAProxy 做 SSL/TLS 卸载
- 需要 RSA-PSS 签名填充或 P-521 曲线支持
- 仅通过 Web 服务器编程方式调用,不需要命令行操作
3、总结
- 如果你需要 OpenSSL 命令行 操作 CloudHSM → 只能用 Dynamic Engine
- 如果你只需要 Web 服务器 TLS 卸载 且系统是 OpenSSL 3.2+ → 推荐用 Provider
- 如果你需要通用的 加密/解密 能力 → 两个方案都不行,请使用 JCE Provider 或 PKCS#11
4、参考文档
二、Ubuntu 22.04 系统上 OpenSSL Dynamic Engine 库安装
1、概述
本章节介绍如何使用 OpenSSL Dynamic Engine 通过命令行完成 RSA 和 ECC 密钥创建、签名和验签操作:
| 操作 | 是否在 CloudHSM 内执行 |
|---|---|
| RSA / ECC 密钥创建 | ✅ 是 |
| RSA / ECDSA 签名 | ✅ 是 |
| RSA / ECDSA 验签 | ❌ 否(在本地 OpenSSL 软件完成) |
2、前提条件
- 已激活的 CloudHSM 集群,至少2个节点
- 已安装 CloudHSM Client SDK 5
- 已创建非 Admin 权限的普通加密用户 Crypto User (CU)
3、安装 OpenSSL 动态引擎安装包(区分操作系统)
以Ubuntu 22.04 (x86_64) 系统为例,从官网链接下载对应的操作系统安装包:
wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsmClient/Jammy/cloudhsm-dyn_latest_u22.04_amd64.deb
sudo apt install ./cloudhsm-dyn_latest_u22.04_amd64.deb
安装完成后,动态引擎库位于 /opt/cloudhsm/lib/libcloudhsm_openssl_engine.so。
4、配置 CloudHSM IP 地址
安装完成后,需要将配置文件中的占位符替换为实际的 CloudHSM ENI IP 地址,否则引擎初始化会报错:
Failed to initialize OpenSSL engine, Internal Error: Config key hostname has invalid value %%HSM_IP_ADDRESS%%
1)获取 CloudHSM 的 ENI IP 地址:
aws cloudhsmv2 describe-clusters --query 'Clusters[].Hsms[].EniIp' --output text
2)编辑配置文件,将 %%HSM_IP_ADDRESS%% 替换为实际 IP:
sudo vi /opt/cloudhsm/etc/cloudhsm-dyn.cfg
替换前:
"hostname": "%%HSM_IP_ADDRESS%%"
替换后(示例):
"hostname": "172.31.36.75"
注意: 如果集群中有多个 CloudHSM 节点,可以在
servers数组中添加多个条目,每个条目对应一个 CloudHSM 的 ENI IP。
5、验证安装
openssl engine -t cloudhsm
预期输出如下表示正常:
(cloudhsm) CloudHSM OpenSSL Engine
[ available ]
6、设置 OpenSSL Dynamic Engine访问 CloudHSM 的凭证
在执行任何 OpenSSL 引擎操作前,必须设置环境变量:
export CLOUDHSM_PIN=<CU用户名>:<CU密码>
示例:
export CLOUDHSM_PIN=myuser:mypassword
注意: 如果密码中包含 shell 特殊字符(如
!、$、&等),需要进行转义。
三、使用 RSA 签名
注意:请确认您的CloudHSM集群内有两个节点,否则OpenSSL CLI调用Dynamic Engine功能可能不正常。
使用 CloudHSM CLI 在 CloudHSM 内生成 RSA 密钥对,支持的算法包括:
- SHA1withRSA
- SHA224withRSA
- SHA256withRSA
- SHA384withRSA
- SHA512withRSA
1、使用 CloudHSM CLI 在 CloudHSM 内生成 RSA 2048 密钥对
/opt/cloudhsm/bin/cloudhsm-cli interactive
执行login --username user01 --role crypto-user命令以普通用户身份登陆,输入user01用户的密钥即可完成登陆。
key generate-asymmetric-pair rsa \
--modulus-size-bits 2048 \
--public-exponent 65537 \
--public-label my_rsa_pub \
--private-label my_rsa_private \
--private-attributes sign=true
生成成功后会返回 key-reference 等信息。
2、导出 Fake PEM 私钥文件和公钥 PEM 文件
Fake PEM 文件不包含真实私钥数据,仅包含对 CloudHSM 上私钥的引用,供 OpenSSL 引擎识别使用。
key generate-file \
--encoding reference-pem \
--path /tmp/my_rsa_private.key \
--filter attr.label="my_rsa_private"
导出公钥PEM文件。
key generate-file \
--encoding pem \
--path /tmp/my_rsa_pub.pem \
--filter attr.label="my_rsa_pub"
执行quit命令,退出CloudHSM CLI。
3、使用 OpenSSL 引擎进行签名(CloudHSM内执行)
签名操作通过 -engine cloudhsm 参数将签名运算卸载到 CloudHSM,私钥始终保留在 CloudHSM 内部。
首先准备待签名文件:
echo "Hello CloudHSM OpenSSL Engine" > /tmp/message.txt
然后使用 SHA256withRSA 签名。
openssl dgst -engine cloudhsm -sha256 \
-sign /tmp/my_rsa_private.key \
-out /tmp/message.sig \
/tmp/message.txt
返回Engine "cloudhsm" set.表示成功
参数说明:
-engine cloudhsm:指定使用 CloudHSM 动态引擎-sha256:使用 SHA-256 哈希算法(数据哈希在本地完成,签名在 CloudHSM 内完成)-sign /tmp/my_rsa_private.key:使用 Fake PEM 私钥文件(引用 CloudHSM 上的真实私钥)-out /tmp/message.sig:输出签名文件/tmp/message.txt:待签名的原始文件
支持的哈希算法:-sha1、-sha224、-sha256、-sha384、-sha512
4、使用 OpenSSL 进行验签(本地执行)
验签操作在本地 OpenSSL 软件中完成,不经过 CloudHSM。因此可以不指定 -engine cloudhsm,直接使用公钥验签。
使用公钥验签:
openssl dgst -sha256 \
-verify /tmp/my_rsa_pub.pem \
-signature /tmp/message.sig \
/tmp/message.txt
验签成功输出:
Verified OK
验签失败输出:
Verification Failure
5、生成自签名证书
基于 CloudHSM 上的私钥生成证书:
生成 CSR:
openssl req -engine cloudhsm -new \
-key /tmp/my_rsa_private.key \
-out /tmp/my_server.csr
按提示填写证书信息(国家、组织、域名等)。在遇到A challenge password时候可以直接回车不设置。在An optional company name参数也可以直接回车不设置。
使用 CloudHSM 内的私钥签名
openssl x509 -engine cloudhsm -req -days 365 \
-in /tmp/my_server.csr \
-signkey /tmp/my_rsa_private.key \
-out /tmp/my_server.crt
签名成功返回:
Certificate request self-signature ok
subject=C = CN, ST = BEIJING, L = BJ, O = BITIPCMAN, OU = rsa_ops, CN = rsa-ops.bitipcman.com, emailAddress = rsa_ops@bitipcman.com
由此获得/tmp/my_server.crt。
四、使用 ECC 密钥进行签名和证书签发
注意:请确认您的CloudHSM集群内有两个节点,否则OpenSSL CLI调用Dynamic Engine功能可能不正常。
除 RSA 外,Dynamic Engine 也支持 ECC(ECDSA)签名。以下演示使用 P-256 曲线完成密钥创建、签名、验签和证书签发的完整流程。OpenSSL 会根据你传入的密钥类型自动选择:
- ECC 密钥 → ECDSA 签名
- RSA 密钥 → RSASSA-PKCS1-v1_5 签名
Dynamic Engine 支持的 ECC 曲线: P-256(secp256r1/prime256v1)、P-384(secp384r1)、secp256k1。如需 P-521 支持,请使用 OpenSSL Provider。
1、在 CloudHSM 上创建 ECC 密钥对
/opt/cloudhsm/bin/cloudhsm-cli interactive
执行如下命令以user01身份登陆:
login --username <CU用户名> --role crypto-user
执行如下命令创建证书。
key generate-asymmetric-pair ec \
--curve secp256r1 \
--public-label my_ec_pub \
--private-label my_ec_private \
--public-attributes verify=true \
--private-attributes sign=true
由此获得公钥和私钥,都保存在CloudHSM内,并未下载到本地。
2、导出 Fake PEM 私钥和公钥
Fake PEM 文件不包含真实私钥数据,仅包含对 CloudHSM 上私钥的引用,供 OpenSSL 引擎识别使用。
key generate-file \
--encoding reference-pem \
--path /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_private.key \
--filter attr.label="my_ec_private"
导出公钥PEM文件。
key generate-file \
--encoding pem \
--path /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_pub.pem \
--filter attr.label="my_ec_pub"
操作成功的话返回如下:
{
"error_code": 0,
"data": {
"message": "Successfully generated key file"
}
}
由此在指定目录下获得my_ec_private.key和my_ec_pub.pem两个文件。
执行quit命令,退出CloudHSM CLI。
3、使用 ECDSA 签名(CloudHSM 内执行)
签名操作通过 -engine cloudhsm 参数将签名运算卸载到 CloudHSM,私钥始终保留在 CloudHSM 内部。
首先准备待签名文件:
echo "Hello CloudHSM OpenSSL Engine" > message.txt
针对低于SHA256的算法,需要额外打开例外选项。(以下命令是SHA256,因此不用执行此命令)
sudo /opt/cloudhsm/bin/configure-dyn --enable-ecdsa-with-weak-hash-function
openssl dgst -engine cloudhsm -sha256 \
-sign /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_private.key \
-out /home/ubuntu/environment/cloudhsm/test-key-2/ecc_message.sig \
/home/ubuntu/environment/cloudhsm/test-key-2/ecc_message.txt
返回Engine "cloudhsm" set.表示成功。
OpenSSL 会自动识别密钥类型为 EC,使用 ECDSA 算法进行签名。参数 sha256 指定的是哈希算法部分,组合起来就是:
- SHA256 + ECDSA = SHA256withECDSA
- SHA384 + ECDSA = SHA384withECDSA
Dynamic Engine 支持的 ECDSA 曲线是 P-256、P-384 和 secp256k1。
4、使用公钥验签(本地执行)
openssl dgst -sha256 \
-verify /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_pub.pem \
-signature /home/ubuntu/environment/cloudhsm/test-key-2/ecc_message.sig \
/home/ubuntu/environment/cloudhsm/test-key-2/ecc_message.txt
验签成功输出 Verified OK。
5、使用 ECC 密钥生成自签名证书
openssl req -engine cloudhsm -new \
-key /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_private.key \
-out /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_server.csr
按提示填写证书信息(国家、组织、域名等)。在遇到A challenge password时候可以直接回车不设置。在An optional company name参数也可以直接回车不设置。
由此在对应目录下生成my_ec_server.csr文件。
openssl x509 -engine cloudhsm -req -days 365 \
-in /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_server.csr \
-signkey /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_private.key \
-out /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_server.crt
执行成功返回:
Engine "cloudhsm" set.
Certificate request self-signature ok
subject=C = CN, ST = BEIJING, L = BJ, O = BITIPCMAN, OU = ec-dev, CN = ec-dev.bitipcman.com, emailAddress = ec-dev@bitipcman.com
由此获得my_ec_server.crt文件。
6、使用 ECC CA 密钥签发证书
如果将 ECC 密钥作为 CA 密钥,可以用它签发其他证书:
openssl x509 -engine cloudhsm -req -days 365 \
-in /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_server.csr \
-CA /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_server.crt \
-CAkey /home/ubuntu/environment/cloudhsm/test-key-2/my_ec_private.key \
-CAcreateserial \
-out /home/ubuntu/environment/cloudhsm/test-key-2/client-01.crt
签发成功返回:
Engine "cloudhsm" set.
Certificate request self-signature ok
subject=C = CN, ST = BEIJING, L = BJ, O = BITIPCMAN, OU = ec-dev, CN = ec-dev.bitipcman.com, emailAddress = ec-dev@bitipcman.com
由此获得client-01.crt文件。
五、小结
本文主要流程如下:
┌─────────────────────────────────────────────────────────┐
│ 1. 安装 OpenSSL 动态引擎 │
│ 2. export CLOUDHSM_PIN=user:password │
│ 3. CloudHSM CLI 生成 RSA 或 ECC 密钥对 │
│ 4. 导出 Fake PEM 私钥 + 公钥 PEM │
│ 5. openssl dgst -engine cloudhsm -sign ... (签名) │
│ 6. openssl dgst -verify ... (验签,本地完成) │
│ 7. openssl req/x509 -engine cloudhsm ... (生成证书,可选) │
└─────────────────────────────────────────────────────────┘
备注:Cloudhsm官方文档说法:
Only RSA offload to the HSM is supported by default:
- Impact: To maximize performance, the SDK is not configured to offload additional functions such as random number generation or EC-DH operations.
- Workaround: Please contact us through a support case if you need to offload additional operations.
- Resolution status: We are adding support to the SDK to configure offload options through a configuration file. The update will be announced on the version history page once available.
这条 known issue 说的是 EC-DH(椭圆曲线 Diffie-Hellman 密钥协商),不是 ECDSA(签名)。两者是不同的操作:
- EC-DH — 密钥交换/协商协议,用于 TLS 握手中的密钥协商
- ECDSA — 数字签名算法,用于签名和验签
Dynamic Engine 的 supported mechanisms 页面 (https://docs.aws.amazon.com/cloudhsm/latest/userguide/openssl-mechanisms.html) 明确列出了 SHA256withECDSA 是支持的。这条 known issue 不影响 ECDSA 签名场景。
六、参考链接
- OpenSSL Dynamic Engine 官方文档
- OpenSSL Provider 官方文档
- Dynamic Engine 支持的密钥类型
- Dynamic Engine 支持的签名机制
- Provider 支持的密钥类型
- Provider 支持的签名机制
- Dynamic Engine 已知问题
最后修改于 2026-03-31