【密码学实战】openHiTLS X509命令行工具: 数字证书生成与转换
前言
在当今的信息时代,网络通信的安全性是基石。无论是网上购物、在线 banking,还是远程办公,我们都依赖于一个安全、可信的环境来传输敏感信息。这一切的背后,离不开公钥基础设施(Public Key Infrastructure, PKI)的支撑。X.509 正是 PKI 的核心标准之一。它定义了数字证书的格式,该证书如同网络世界中的 “身份证” 或 “护照”。
openHiTLS 是业界首个面向全场景的开源密码库,由华为、西安电子科技大学、山东大学、上海交通大学等13家国内产学研单位共同发起,提供了完整的密码学和安全通信功能。作为其工具集的一部分,openHiTLS 提供了 hitls
命令行工具,其hitls x509
集中用于处理 X.509 证书的核心组件。它允许用户通过命令行界面,方便地执行与 X.509 证书相关的各种操作,如生成、查看、分析和转换等,是管理和维护 PKI 的强大助手。
本文将详细介绍 hitls x509
命令行工具的功能、使用方法和最佳实践。
一、核心功能与设计理念
hitls x509
的设计目标是提供一个全面且高效的 X.509 证书处理解决方案。其核心功能涵盖了证书生命周期的关键环节:
- 证书生成(签名):作为 CA(证书颁发机构),对一个证书签名请求(CSR)进行签名,生成一个新的、受信任的 X.509 证书。这包括自签名(生成根 CA 证书)和由已有 CA 签名(生成中间或终端实体证书)两种模式。
- 证书查看与分析:加载并解析一个已有的 X.509 证书,以人类可读的方式展示其内部结构和所有字段信息,如版本、序列号、颁发者(Issuer)、主题(Subject)、有效期(Validity Period)、公钥信息以及各种扩展(Extensions)。
- 信息提取:从证书中提取特定信息,如公钥、主题密钥标识符(SKI)、指纹(Fingerprint)等,用于密钥管理或验证。
- 格式转换:在 PEM 和 DER 两种最常见的证书编码格式之间进行转换。
设计理念:
- 模块化:代码结构清晰,将命令行解析、证书操作、输出打印等功能拆分为独立模块,便于维护和扩展。
- 灵活性:通过丰富的命令行选项,允许用户精细控制证书生成和查看的每一个环节。
- 兼容性:选项设计和行为与 OpenSSL
x509
高度一致,降低了用户的学习成本和迁移难度。 - 安全性:在处理私钥时,支持密码保护,并在内存中安全地清除敏感信息,防止泄露。
二、工作模式与内部流程
hitls x509
的行为由命令行选项驱动,主要分为两种工作模式,其内部处理流程也有所不同。
1. 生成模式(-req
模式)
当指定 -req
选项时,工具进入证书生成流程。其内部工作流大致如下:
- 初始化与解析:解析命令行参数,初始化上下文(
X509OptCtx
),并进行选项合法性检查(例如,-CA
和-CAkey
必须成对出现,-signkey
与-CA
不能同时使用等)。 - 资源加载:
- 加载 CSR 文件并验证其签名的合法性。
- 加载签名所需的私钥(
-signkey
或-CAkey
),并使用-passin
提供的密码进行解密。 - 如果是 CA 签名,加载 CA 证书并验证 CA 公钥与私钥是否匹配。
- 如果指定了扩展,加载并解析配置文件(
-extfile
)。
- 证书构建:
- 创建一个新的空证书对象。
- 从 CSR 中提取公钥和主题(Subject)信息,设置到新证书中。
- 设置颁发者(Issuer)信息:自签名时与 Subject 相同;CA 签名时从 CA 证书中获取。
- 设置有效期(
-days
),起始时间为当前系统时间。 - 设置序列号(
-set_serial
或随机生成)。 - 处理扩展:复制 CSR 中的扩展,并根据配置文件(
-extfile
和-extensions
)添加或覆盖 X.509 v3 扩展。这是生成功能最强大的部分,用于配置如subjectAltName
(SAN)、keyUsage
、extendedKeyUsage
等关键属性。
- 签名与编码:
- 使用指定的私钥和消息摘要算法(
-md
)对证书的 TBS(To-Be-Signed)部分进行签名。 - 将完整的、已签名的证书编码为指定格式(PEM 或 DER),准备输出。
- 使用指定的私钥和消息摘要算法(
- 输出:将生成的证书写入到文件或标准输出。
2. 查看模式(默认模式)
当不指定 -req
选项时,工具默认进入证书查看流程。其内部工作流相对简单:
- 初始化与解析:解析命令行参数,初始化上下文。
- 证书加载:从指定文件(
-in
)加载证书,并根据-inform
识别其格式。 - 信息提取与打印:
- 根据指定的打印选项(如
-text
,-issuer
,-fingerprint
等),从加载的证书对象中提取相应信息。 - 调用内部的打印函数,将提取的信息格式化并输出到文件或标准输出。
- 根据指定的打印选项(如
- 公钥输出:如果指定了
-pubkey
,则从证书中提取公钥,编码为 PEM 格式并输出。
三、命令行选项详解(增强版)
以下是 hitls x509
支持的所有命令行选项,根据功能进行了分类,并补充了更详细的说明和使用建议。
1. 通用输入 / 输出选项
选项 | 参数 | 描述 | 使用建议 |
---|---|---|---|
-in | filename | (必需) 指定输入文件。在生成模式下为 CSR,在查看模式下为证书。 | 始终明确指定输入文件,避免使用默认值带来的不确定性。 |
-inform | PEM | DER | 指定输入文件的格式,默认为 PEM 。 | 当处理非 PEM 格式的文件(如 .cer , .crt 的 DER 版本)时,必须使用此选项。 |
-out | filename | 指定输出文件。用于写入生成的证书或打印的文本。 | 如果未指定,输出将发送到标准输出(stdout),这对于管道操作很有用。 |
-outform | PEM | DER | 指定输出证书的格式,默认为 PEM 。 | 用于在 PEM 和 DER 格式之间进行转换。例如,将 PEM 证书转换为 DER 格式。 |
-noout | 无 | (重要) 不输出证书本身。 | 当你只想查看证书信息(如指纹、公钥)而不希望创建一个新的证书文件时,此选项至关重要。 |
2. 证书生成选项 (用于 -req
模式)
选项 | 参数 | 描述 | 使用建议 |
---|---|---|---|
-req | 无 | (核心) 声明输入为 CSR,触发证书生成流程。 | 生成新证书时必须使用此选项。 |
-days | number | 指定有效期(天数),默认为 30 天。 | 生产环境中的证书通常设置为 365 天或更久。测试证书可以使用较短的有效期。 |
-set_serial | hex_string | 手动指定序列号(十六进制)。不指定则随机生成。 | 序列号在 CA 域内必须唯一。手动指定有助于在调试或特定策略下进行追踪。 |
-signkey | filename | 指定用于自签名的私钥文件(PEM 格式)。 | 用于生成根 CA 证书或自签名服务器证书。私钥必须与 CSR 中的公钥配对。 |
-CA | filename | 指定用于签名的 CA 证书。 | 用于由上级 CA 签发下级证书(如中间 CA 或终端用户证书)。 |
-CAkey | filename | 指定用于签名的 CA 私钥。 | 必须与 -CA 选项配合使用,且私钥必须与 -CA 证书中的公钥配对。 |
-extfile | filename | 指定包含 X.509 v3 扩展的配置文件。 | 当需要为证书添加高级属性(如 SAN、密钥用法)时,此选项是必需的。 |
-extensions | section | 指定 -extfile 中要使用的配置段名称。 | 配置文件中可以包含多个段,此选项用于选择激活哪一个。 |
-md | algorithm | 指定签名的摘要算法,如 sha256 , sha384 。默认为 sha256 。 | sha1 已不被推荐用于新证书。建议使用 sha256 或更强的算法。 |
-passin | source | 指定私钥的密码来源。 | 为了安全,避免在命令行中直接明文输入密码,可以使用文件或环境变量。 |
-userId | string | 为 SM2 算法指定用户 ID。 | 仅在使用国密 SM2 算法时需要。 |
3. 证书信息打印选项
选项 | 参数 | 描述 | 使用建议 |
---|---|---|---|
-text | 无 | 以详细文本格式打印证书的全部内容。 | 最常用的查看选项,用于全面诊断证书问题,如有效期、扩展是否正确等。通常与 -noout 一起使用。 |
-issuer | 无 | 打印证书的颁发者 DN。 | 快速验证证书是由哪个 CA 签发的。 |
-subject | 无 | 打印证书的主题 DN。 | 快速查看证书的所有者信息。 |
-nameopt | oneline | multiline | rfc2253 | 指定 DN 的打印格式。 | oneline 最适合快速查看;rfc2253 是标准格式,适合程序解析。 |
-hash | 无 | 打印 Subject DN 的哈希值。 | 在某些系统(如旧版 OpenSSL)中,此哈希值用于命名证书文件(例如 8f8...d4f.0 )。 |
-fingerprint | 无 | 打印证书的指纹。 | 非常重要的验证工具。用于在不依赖 CA 的情况下,手动验证证书文件的完整性和真实性。 |
-pubkey | 无 | 提取并打印证书中的公钥(PEM 格式)。 | 用于获取对方的公钥,以便进行加密或验证签名。通常与 -noout 一起使用。 |
4. 其他选项
选项 | 参数 | 描述 |
---|---|---|
-help | 无 | 显示帮助信息,列出所有选项及其说明。 |
四、使用示例
示例 1:生成一个自签名的根 CA 证书
这是创建一个独立 PKI 的第一步。
前提:你已经通过 hitls req
命令生成了 ca.key
(私钥) 和 ca.csr
(CSR)。
# 使用 ca.key 对 ca.csr 进行自签名,生成有效期为 3650 天(约 10 年)的根证书 ca.crt
hitls x509 -req -in ca.csr -signkey ca.key -days 3650 -out ca.crt
命令解析:
- 这个命令创建了一个可以用来为其他证书签名的根证书。
-days 3650
设置了一个较长的有效期,因为根证书通常很少更换。
示例 2:使用 CA 证书为服务器证书签名
前提:
- CA 证书
ca.crt
和 CA 私钥ca.key
。 - 服务器私钥
server.key
和服务器 CSRserver.csr
。 - 一个扩展配置文件
server_ext.conf
,内容如下,用于配置 SAN( Subject Alternative Name):ini
[server] subjectAltName = DNS:www.example.com, DNS:example.com, IP:192.168.1.50 keyUsage = digitalSignature, keyEncipherment extendedKeyUsage = serverAuth
# 使用 CA 证书和私钥,为 server.csr 签名,并应用 server_ext.conf 中的扩展
hitls x509 -req -in server.csr -CA ca.crt -CAkey ca.key -days 365 \-extfile server_ext.conf -extensions server -out server.crt
命令解析:
-CA
和-CAkey
指定了签发者。-extfile
和-extensions
为生成的server.crt
添加了至关重要的 SAN 扩展和用途限制。现代浏览器强制要求证书包含 SAN 字段。
示例 3:全面查看证书详细信息
这是排查证书问题的首选命令。
# 以详细文本格式查看 server.crt 的所有信息,并抑制证书本身的输出
hitls x509 -in server.crt -text -noout
输出内容示例(节选):
Certificate:Data:Version: 3 (0x2)Serial Number:0a:1b:2c:3d:4e:5f:6a:7b:8c:9dSignature Algorithm: sha256WithRSAEncryptionIssuer: C = CN, ST = Beijing, L = Beijing, O = MyOrg, OU = MyDept, CN = My Root CAValidityNot Before: Sep 28 08:30:00 2023 GMTNot After : Sep 28 08:30:00 2024 GMTSubject: C = CN, ST = Beijing, L = Beijing, O = MyOrg, OU = MyDept, CN = www.example.comSubject Public Key Info:Public Key Algorithm: rsaEncryptionRSA Public-Key: (2048 bit)...X509v3 extensions:X509v3 Subject Alternative Name:DNS:www.example.com, DNS:example.com, IP Address:192.168.1.50X509v3 Key Usage:Digital Signature, Key EnciphermentX509v3 Extended Key Usage:TLS Web Server Authentication...
示例 4:获取证书指纹并验证文件完整性
假设你从一个网站下载了证书 remote.crt
,你想确认它在传输过程中没有被篡改。
# 获取 remote.crt 的 SHA-256 指纹
hitls x509 -in remote.crt -fingerprint -md sha256 -noout
输出示例:
SHA256 Fingerprint=AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90:AB:CD:EF:12:34:56:78:90
你可以将这个指纹与网站管理员提供的官方指纹进行比对。如果两者一致,说明文件是完整且未被篡改的。
示例 5:提取公钥并保存
# 从 server.crt 中提取公钥,并保存到 server_pub.pem 文件
hitls x509 -in server.crt -pubkey -noout -out server_pub.pem
输出文件 server_pub.pem
内容示例:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv6...
...
QIDAQAB
-----END PUBLIC KEY-----
示例 6:格式转换
# 将 PEM 格式的 server.crt 转换为 DER 格式,并保存为 server.der
hitls x509 -in server.crt -inform PEM -out server.der -outform DER
示例 7:使用管道(Pipeline)
结合 hitls s_client
从一个 HTTPS 服务器获取证书并直接查看其信息,无需创建临时文件。
# 连接到 example.com,获取其服务器证书,并通过管道直接用 hitls x509 查看其 issuer 和 subject
echo -n | hitls s_client -connect example.com:443 2>/dev/null | hitls x509 -issuer -subject -noout
五、高级技巧与最佳实践
- 自动化脚本:
hitls x509
是编写自动化部署和证书管理脚本的理想工具。通过组合使用各种选项,可以实现证书的批量生成、 renewal(续期)和监控。 - 安全性:
- 保护私钥:私钥文件(如
ca.key
,server.key
)应设置严格的文件权限(例如chmod 600
),仅限所有者读取。 - 密码管理:避免在命令行中使用
-passin pass:your_password
的形式。推荐使用文件(-passin file:password.txt
)或环境变量(-passin env:MY_KEY_PASSWORD
)来管理密码。 - 算法选择:始终使用强密码学算法。对于 RSA,密钥长度至少为 2048 位;对于签名算法,优先使用
sha256
或更强的哈希算法。
- 保护私钥:私钥文件(如
- 扩展配置:X.509 v3 扩展是现代证书的灵魂。务必使用
-extfile
来配置subjectAltName
(SAN)、keyUsage
、extendedKeyUsage
等扩展,以确保证书能够被正确识别和使用。 - 错误排查:当证书在应用中(如浏览器、Web 服务器)无法正常工作时,首先使用
hitls x509 -in cert.crt -text -noout
检查以下几点:- 证书是否在有效期内?
subjectAltName
扩展是否包含了正确的域名?keyUsage
和extendedKeyUsage
是否与你的应用场景匹配(例如,服务器证书需要serverAuth
)?- 证书链是否完整?(需要结合
hitls verify
工具)
六、错误处理与常见问题
Can't load ... private key
:通常意味着私钥文件路径错误、文件损坏,或者密码不正确。unable to load certificate
:输入文件不是有效的证书,或格式与-inform
指定的不符。CA certificate and CA private key do not match
:-CA
指定的证书和-CAkey
指定的私钥不配对。No such file or directory
:检查所有文件路径是否正确。- 浏览器提示
NET::ERR_CERT_COMMON_NAME_INVALID
:这几乎总是因为证书的subjectAltName
扩展中没有包含你正在访问的域名。
七、总结
hitls x509
是一个功能极其强大且稳定可靠的 X.509 证书工具箱。无论是在开发、测试还是生产环境中,它都是处理 TLS/SSL 证书不可或缺的利器。通过熟练掌握其命令行选项和工作流程,用户可以轻松地完成从简单的证书查看,到复杂的 CA 签名和扩展配置等一系列任务,从而构建和维护安全、健壮的网络通信环境。
免费下载openHiTLS
1、下载相关代码
- openHiTLS下载地址:https://gitcode.com/openhitls
- libboundscheck下载地址:https://gitee.com/openeuler/libboundscheck.git 说明:需要将libboundscheck下载至openHiTLS/platform/Secure_C目录
2、构建安装,在openHiTLS根路径下执行以下命令:
mkdir build cd build cmake .. make && make install