搞定 Windows OpenSSL:从安装、配置到证书生成的终极指南
引言:为什么我们需要在 Windows 上使用 OpenSSL?
在当今数字化的世界中,安全是网络通信的基石。无论是浏览网页(HTTPS)、发送邮件(SMTPS/IMAPS)、连接 VPN 还是保护 API,加密和身份验证都扮演着至关重要的角色。OpenSSL 项目提供了一个强大、商业级且功能齐全的工具包,实现了 SSL(安全套接字层)和 TLS(传输层安全)协议以及一个通用的密码学库。它包含了用于生成私钥、创建证书签名请求(CSR)、安装 SSL/TLS 证书、生成自签名证书、管理证书颁发机构(CA)以及执行各种加密任务的核心工具。
虽然 OpenSSL 起源于类 Unix 系统(如 Linux、macOS),并且在这些平台上是标准配置,但 Windows 用户,特别是开发者、系统管理员和安全专业人士,也经常需要利用 OpenSSL 的强大功能。原因包括:
- 跨平台开发与测试:许多应用程序和服务需要跨平台运行,在 Windows 上模拟或管理与 Linux/macOS 服务器相同的证书和密钥环境至关重要。
- 本地开发环境:为本地 Web 服务器(如 IIS, Apache, Nginx on Windows)配置 HTTPS,需要生成或处理证书。
- 证书管理:需要生成 CSR 发送给商业 CA,或者需要创建内部使用的自签名证书或私有 CA。
- 脚本自动化:在 Windows 批处理或 PowerShell 脚本中集成 OpenSSL 命令,实现证书管理和加密任务的自动化。
- 学习与实验:理解 PKI(公钥基础设施)、SSL/TLS 协议和密码学概念的最佳实践工具之一。
然而,Windows 本身并不原生自带 OpenSSL 命令行工具(尽管它有自己的加密 API 和证书管理工具 certlm.msc
/ certmgr.msc
)。因此,我们需要手动安装和配置它。本文将详细指导您如何在 Windows 系统上完成 OpenSSL 的安装、环境配置,并深入探讨如何使用它生成各种类型的证书和密钥,助您彻底搞定 Windows OpenSSL。
第一章:在 Windows 上安装 OpenSSL
在 Windows 上安装 OpenSSL 有多种途径,您可以根据自己的需求和偏好选择最合适的方法。
方法一:使用预编译的第三方二进制包(推荐)
这是最直接、最受推荐的方法,特别是对于不希望处理编译复杂性的用户。一些社区或组织提供了预编译好的 Windows 版 OpenSSL 安装包或压缩包。
推荐来源:Shining Light Productions (SLP)
SLP 长期以来一直提供稳定且更新及时的 Windows OpenSSL 安装程序。
- 访问下载页面:在浏览器中访问 Shining Light Productions 的 Win32/Win64 OpenSSL 下载页面(可以通过搜索引擎搜索 “OpenSSL Windows SLP” 找到官方或可信赖的镜像源)。
- 选择版本:
- 架构:根据您的 Windows 系统是 32 位 (Win32) 还是 64 位 (Win64) 选择对应的版本。现代系统通常是 64 位。
- 版本号:通常建议选择最新的稳定版(LTS – 长期支持版通常更稳定)。避免使用 “Light” 版本,因为它可能缺少开发所需的头文件和库。选择完整版(通常文件名不含 “Light”)。
- 安装程序类型:通常提供
.exe
安装程序和.zip
压缩包。- EXE 安装程序:更方便,通常会提供添加到系统 PATH 的选项。
- ZIP 压缩包:绿色版,解压即可使用,但需要手动配置环境变量。
- 下载与安装(以 EXE 为例):
- 下载所选的
.exe
文件。 - 运行安装程序。仔细阅读许可协议。
- 选择安装路径:建议选择一个不包含空格或特殊字符的路径,例如
C:\Program Files\OpenSSL
或C:\Tools\OpenSSL
。 - 关键步骤:选择组件:确保选中了 OpenSSL 可执行文件 (
openssl.exe
) 和相关的库文件。 - 重要选项:复制 OpenSSL DLLs 到:安装程序可能会询问将 OpenSSL DLL(如
libcrypto-*.dll
,libssl-*.dll
)复制到哪里。推荐选择 “The OpenSSL binaries (/bin) directory”。不建议选择复制到 Windows 系统目录(System32),这可能导致版本冲突。 - 完成安装。
- 下载所选的
- 安装(以 ZIP 为例):
- 下载所选的
.zip
文件。 - 将其解压到一个合适的目录,例如
C:\Tools\OpenSSL
。解压后,openssl.exe
通常位于bin
子目录下。
- 下载所选的
方法二:通过 Windows Subsystem for Linux (WSL)
如果您是开发者,并且已经在 Windows 10/11 上使用了 WSL 或 WSL 2,那么这可能是最无缝的方式。WSL 允许您运行一个 Linux 环境,其中 OpenSSL 通常是预装或可以通过包管理器轻松安装。
- 安装 WSL:如果尚未安装,请打开 PowerShell (管理员权限) 并运行
wsl --install
。根据提示可能需要重启。这将安装默认的 Ubuntu 发行版。您也可以从 Microsoft Store 安装其他 Linux 发行版。 - 启动 WSL:在开始菜单搜索您安装的 Linux 发行版(如 Ubuntu)并启动它。
- 检查/安装 OpenSSL:在 WSL 终端中,运行
openssl version
检查是否已安装。如果未安装或版本过旧,使用发行版的包管理器进行安装/更新:- Debian/Ubuntu:
sudo apt update && sudo apt install openssl
- CentOS/Fedora:
sudo dnf update && sudo dnf install openssl
或sudo yum update && sudo yum install openssl
- Debian/Ubuntu:
- 使用:在 WSL 终端内,您可以直接使用
openssl
命令,就像在原生 Linux 环境中一样。文件系统是互通的,您可以通过/mnt/c/
访问 Windows 的 C 盘。
优点:获得与 Linux 完全一致的体验。
缺点:需要在 WSL 环境下操作,对于只需要 OpenSSL 命令行的用户可能稍显重量级。
方法三:使用 Git for Windows 自带的 OpenSSL
如果您安装了 Git for Windows(一个非常流行的工具),它会捆绑一个 OpenSSL 的版本,主要供 Git 内部使用(例如 HTTPS 连接)。
- 安装 Git for Windows:从官网下载并安装。
- 找到 OpenSSL:安装完成后,
openssl.exe
通常位于 Git 安装目录下的usr\bin
子目录中,例如C:\Program Files\Git\usr\bin\openssl.exe
。 - 使用:
- 可以通过 Git Bash 终端直接使用
openssl
命令,因为它已经配置好了环境。 - 如果想在 Windows 命令提示符 (CMD) 或 PowerShell 中使用,需要将
C:\Program Files\Git\usr\bin
(根据您的实际安装路径调整) 添加到系统环境变量 PATH 中。
- 可以通过 Git Bash 终端直接使用
优点:如果已安装 Git,则无需额外安装。
缺点:捆绑的 OpenSSL 版本可能不是最新的,且主要目的是服务于 Git,可能不是功能最全的版本。
方法四:自行编译(高级)
这是最复杂的方法,需要安装编译器(如 Visual Studio)、Perl (通常推荐 Strawberry Perl) 和 NASM 汇编器。
- 从 OpenSSL 官网下载源代码 (
.tar.gz
)。 - 解压源代码。
- 仔细阅读
NOTES-WINDOWS.md
或INSTALL.md
文件中的 Windows 编译指南。 - 配置编译环境(设置 VS 环境变量等)。
- 运行
perl Configure VC-WIN64A
(64位) 或VC-WIN32
(32位) 以及其他选项。 - 运行
nmake
。 - 运行
nmake test
(可选但推荐)。 - 运行
nmake install
。
优点:可以获得最新版本,完全控制编译选项。
缺点:过程复杂,易出错,耗时,不适合大多数用户。
第二章:配置 Windows 环境
无论您选择哪种安装方式(除了 WSL,它有自己的环境),为了能在任何路径下的命令提示符 (CMD) 或 PowerShell 中直接使用 openssl
命令,您需要配置 Windows 的环境变量 PATH
。
配置环境变量 PATH
- 找到 OpenSSL 的
bin
目录:这取决于您的安装方法和路径。- 如果是通过 SLP 的 EXE 安装程序安装到
C:\Program Files\OpenSSL
,那么路径通常是C:\Program Files\OpenSSL\bin
。 - 如果是解压 ZIP 包到
C:\Tools\OpenSSL
,路径是C:\Tools\OpenSSL\bin
。 - 如果是使用 Git for Windows,路径是
C:\Program Files\Git\usr\bin
。
- 如果是通过 SLP 的 EXE 安装程序安装到
- 编辑系统环境变量:
- 在 Windows 搜索栏中输入 “环境变量”,然后选择 “编辑系统环境变量”。
- 在弹出的 “系统属性” 对话框中,点击 “高级” 选项卡下的 “环境变量(N)…” 按钮。
- 在 “环境变量” 对话框中,找到 “系统变量(S)” 区域下的
Path
变量,选中它,然后点击 “编辑(E)…”。 - 在 “编辑环境变量” 对话框中,点击 “新建(N)”,然后粘贴或输入您找到的 OpenSSL
bin
目录的完整路径。 - 点击 “确定” 关闭所有打开的对话框。
- 验证配置:
- 重要:关闭所有已打开的 CMD 或 PowerShell 窗口,然后重新打开一个新的窗口。环境变量的更改只对新启动的进程生效。
- 在新窗口中输入命令:
openssl version
- 如果配置成功,您应该能看到已安装的 OpenSSL 版本信息,例如
OpenSSL 3.0.5 5 Jul 2022 (Library: OpenSSL 3.0.5 5 Jul 2022)
。 - 如果提示 “‘openssl’ 不是内部或外部命令…”,请检查您的
PATH
变量设置是否正确,路径是否无误,以及是否重启了命令窗口。
理解 OpenSSL 配置文件 (openssl.cnf
或 openssl.cfg
)
OpenSSL 的许多行为,特别是 req
(证书请求)和 ca
(证书颁发机构)命令的行为,都受到配置文件的影响。
- 查找配置文件:OpenSSL 会在几个预定义的位置查找配置文件。对于 SLP 安装的版本,通常位于 OpenSSL 安装目录下的
ssl
或certs
文件夹内,或者与openssl.exe
在同一bin
目录下。您可以通过openssl version -d
查看OPENSSLDIR
,这通常是配置文件的根目录。 - 默认配置文件:通常名为
openssl.cnf
或openssl.cfg
。 - 结构:这是一个文本文件,采用 INI 文件格式,包含多个节(section),用方括号
[]
括起来,例如[ req ]
,[ req_distinguished_name ]
,[ v3_ca ]
。每个节包含键值对。 - 重要性:
[ req ]
节定义了生成 CSR 时的默认值和选项,如默认密钥长度 (default_bits
)、是否加密私钥 (encrypt_key
)、摘要算法 (default_md
)、以及专有名称(DN)字段的提示 (prompt
) 和默认值 (distinguished_name
)。[ req_distinguished_name ]
节定义了构成证书主体(Subject)的字段及其默认值或提示语,如国家 (C
)、省份 (ST
)、城市 (L
)、组织 (O
)、组织单位 (OU
) 和通用名称 (CN
)。[ v3_ca ]
,[ v3_req ]
,[ usr_cert ]
等节用于定义 X.509 v3 扩展,例如basicConstraints
,keyUsage
,extendedKeyUsage
,subjectAltName
(SAN)。SAN 对于现代 HTTPS 证书至关重要。
- 自定义:您可以编辑此文件来自定义默认行为,例如设置默认的组织信息,或者添加/修改扩展配置。在执行命令时,也可以使用
-config path/to/your/custom.cnf
选项指定一个不同的配置文件。
第三章:核心概念:PKI 与证书基础
在深入实践之前,理解一些基本概念有助于更好地使用 OpenSSL。
- 公钥基础设施 (PKI):一套用于创建、管理、分发、使用、存储和撤销数字证书的策略、标准、人员和系统。
- 非对称加密:使用一对密钥:公钥和私钥。公钥可以公开分发,用于加密数据或验证签名;私钥必须严格保密,用于解密公钥加密的数据或生成签名。
- 私钥 (Private Key):用于解密和签名的密钥,必须保密。OpenSSL 可以生成多种格式的私钥文件(通常是 PEM 格式,以
-----BEGIN PRIVATE KEY-----
或-----BEGIN RSA PRIVATE KEY-----
开头)。 - 公钥 (Public Key):从私钥派生而来,用于加密和验证签名。公钥通常嵌入在证书中。
- 证书签名请求 (CSR – Certificate Signing Request):包含公钥和身份信息(如域名、组织名称)的文件,发送给证书颁发机构 (CA) 请求签名。CSR 本身不是证书,也不包含私钥。通常是 PEM 格式(以
-----BEGIN CERTIFICATE REQUEST-----
开头)。 - 证书颁发机构 (CA – Certificate Authority):受信任的第三方,负责验证请求者的身份,并使用其自身的私钥对 CSR 进行签名,从而颁发数字证书。
- 根 CA (Root CA):顶级 CA,其证书是自签名的,并被操作系统和浏览器广泛信任。
- 中间 CA (Intermediate CA):由根 CA 或其他中间 CA 签名,用于签署最终用户证书,形成信任链。
- 数字证书 (Digital Certificate):通常指 X.509 证书。这是一个电子文档,使用 CA 的私钥签名,将公钥与一个身份(个人、服务器、公司等)绑定。它包含公钥、身份信息(Subject)、颁发者信息 (Issuer)、有效期、签名以及可能的扩展信息(如 SAN)。通常是 PEM 格式(以
-----BEGIN CERTIFICATE-----
开头)。 - 自签名证书 (Self-Signed Certificate):证书的颁发者 (Issuer) 和主体 (Subject) 是相同的,并且证书是用其自身的私钥签名的。它没有经过公共 CA 的验证,因此不被浏览器或操作系统默认信任,主要用于测试、内部网络或作为私有 CA 的根证书。
- 通用名称 (CN – Common Name):传统上用于标识证书主体的主要名称,对于 SSL 证书,通常是域名(如
www.example.com
)。 - 主题备用名称 (SAN – Subject Alternative Name):X.509 v3 扩展,允许一个证书包含多个身份标识,如多个 DNS 域名、IP 地址、Email 地址等。现代浏览器(自 Chrome 58 起)强制要求 HTTPS 证书使用 SAN 扩展来包含域名,即使 CN 也设置了域名。生成证书时务必包含 SAN。
第四章:实战演练:使用 OpenSSL 生成密钥和证书
现在,让我们动手实践,使用 OpenSSL 命令行工具执行常见的证书管理任务。
准备工作:打开一个新的 CMD 或 PowerShell 窗口,确保 openssl
命令可用。创建一个工作目录来存放生成的文件,例如 C:\certs
,并 cd
到该目录。
步骤 1:生成私钥
私钥是所有操作的基础,必须首先生成并妥善保管。
生成 RSA 私钥(常用):
“`bash
生成一个 2048 位的 RSA 私钥,不加密(移除 -aes256 参数)
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
或者使用旧的 genrsa 命令
openssl genrsa -out private_key.pem 2048
生成一个 2048 位的 RSA 私钥,并使用 AES-256 加密(会提示输入密码)
openssl genpkey -algorithm RSA -out private_key_encrypted.pem -pkeyopt rsa_keygen_bits:2048 -aes-256-cbc
或者
openssl genrsa -aes256 -out private_key_encrypted.pem 2048
“`
genpkey
: 推荐的现代命令,用于生成各种类型的私钥。genrsa
: 专门用于生成 RSA 私钥的旧命令。-algorithm RSA
: 指定算法为 RSA。-out private_key.pem
: 指定输出的私钥文件名。.pem
是常见的扩展名,表示 PEM 格式。-pkeyopt rsa_keygen_bits:2048
: 指定 RSA 密钥长度为 2048 位(推荐最小值)。也可以使用 3072 或 4096 位以提高安全性。-aes-256-cbc
(或-aes256
): 可选,用指定的密码算法加密输出的私钥文件。每次使用此密钥时都需要输入密码。如果不加此参数,则私钥不加密(注意保管!)。
生成 ECC (Elliptic Curve Cryptography) 私钥(更高效):
“`bash
查看支持的椭圆曲线
openssl ecparam -list_curves
生成使用 prime256v1 (NIST P-256) 曲线的 ECC 私钥
openssl genpkey -algorithm EC -out ecc_private_key.pem -pkeyopt ec_paramgen_curve:prime256v1
或者使用旧的 ecparam 命令
openssl ecparam -name prime256v1 -genkey -noout -out ecc_private_key.pem
“`
- ECC 密钥通常比相同安全级别的 RSA 密钥更短,计算效率更高。
prime256v1
是常用且广泛支持的曲线。
安全提示:生成的未加密私钥文件(如 private_key.pem
)绝对不能泄露。确保文件权限设置正确,只允许授权用户访问。
步骤 2:生成证书签名请求 (CSR)
CSR 文件包含了您的公钥和您希望包含在证书中的身份信息,用于向 CA 申请证书。
“`bash
使用已生成的私钥 private_key.pem 生成 CSR
openssl req -new -key private_key.pem -out server.csr -sha256
“`
req
: 用于处理 CSR 和证书的命令。-new
: 表示生成新的 CSR。-key private_key.pem
: 指定用于生成 CSR 的私钥文件。-out server.csr
: 指定输出的 CSR 文件名。-sha256
: 指定使用 SHA-256 摘要算法进行签名(推荐)。
执行此命令后,OpenSSL 会交互式地提示您输入以下信息(这些信息将构成证书的 Subject DN):
- Country Name (2 letter code) [AU]:
CN
(例如:中国) - State or Province Name (full name) [Some-State]:
Beijing
(例如:北京市) - Locality Name (eg, city) []:
Beijing
(例如:北京市) - Organization Name (eg, company) [Internet Widgits Pty Ltd]:
My Company Ltd
(您的公司或组织名称) - Organizational Unit Name (eg, section) []:
IT Department
(您的部门名称,可选) - Common Name (e.g. server FQDN or YOUR name) []:
www.example.com
(极其重要: 对于 SSL 证书,这通常是您的服务器的完全限定域名 FQDN) - Email Address []:
[email protected]
(可选) - A challenge password []: (可选,通常留空)
- An optional company name []: (可选,通常留空)
重要:
* Common Name (CN) 必须准确填写。
* 对于现代证书,仅仅设置 CN 是不够的,还需要通过 SAN 包含所有需要保护的域名和 IP 地址。直接使用 openssl req
命令生成 CSR 时添加 SAN 比较麻烦,通常有以下两种方式:
1. 在配置文件中预定义 SAN:修改 openssl.cnf
文件,在 [ req ]
节添加 req_extensions = v3_req
(如果还没有的话),并在 [ v3_req ]
节中定义 subjectAltName = @alt_names
,然后在 [ alt_names ]
节列出所有名称,如 DNS.1 = www.example.com
, DNS.2 = example.com
, IP.1 = 192.168.1.100
。然后在生成 CSR 时使用 -config openssl.cnf
。
2. 在生成自签名证书或签署 CSR 时添加 SAN:更常见的方法是在下一步生成自签名证书或 CA 签署时使用 -addext
选项动态添加 SAN。
非交互式生成 CSR (使用 -subj
参数):
如果您想在脚本中自动生成 CSR,可以使用 -subj
参数提供 Subject 信息:
bash
openssl req -new -key private_key.pem -out server.csr -sha256 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=My Company Ltd/OU=IT Department/CN=www.example.com"
注意:使用 -subj
无法直接添加 SAN 扩展。
步骤 3:生成自签名证书
自签名证书适用于测试环境、内部网络或作为私有 CA 的根证书。它使用自己的私钥进行签名。
方法一:一步生成私钥和自签名证书
bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout self_signed_private_key.pem -out self_signed_certificate.pem -sha256 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=My Self-Signed Org/OU=Dev/CN=localhost" \
-addext "subjectAltName=DNS:localhost,IP:127.0.0.1"
-x509
: 表示输出自签名证书而不是 CSR。-nodes
: (No DES) 表示不加密生成的私钥(方便测试,生产环境慎用)。如果需要加密,去掉此参数,会提示设置密码。-days 365
: 设置证书有效期为 365 天。-newkey rsa:2048
: 同时生成一个新的 2048 位 RSA 私钥。-keyout self_signed_private_key.pem
: 指定输出的私钥文件名。-out self_signed_certificate.pem
: 指定输出的自签名证书文件名。-subj ...
: 提供 Subject 信息。-addext "subjectAltName=..."
: 关键! 添加 SAN 扩展。这里包含了localhost
域名和127.0.0.1
IP 地址。您可以根据需要添加更多DNS:
或IP:
条目,用逗号分隔。
方法二:使用已有的私钥和 CSR 生成自签名证书
如果您已经有了私钥 (private_key.pem
) 和 CSR (server.csr
):
bash
openssl x509 -req -in server.csr -signkey private_key.pem -out self_signed_certificate.pem -days 365 -sha256 \
-extfile <(printf "subjectAltName=DNS:www.example.com,DNS:example.com,IP:192.168.1.100")
x509
: 用于处理 X.509 证书的命令。-req
: 表示输入是 CSR。-in server.csr
: 指定输入的 CSR 文件。-signkey private_key.pem
: 指定用于签名的私钥。-out ...
: 输出证书文件。-days ...
: 有效期。-sha256
: 摘要算法。-extfile <(printf "...")
: 在类 Unix shell (如 Git Bash 或 WSL) 中,这是一种动态创建包含扩展信息文件的方式来添加 SAN。- 在 Windows CMD 中,这会比较麻烦。您需要先创建一个文本文件,例如
san.txt
,内容如下:
ini
subjectAltName=DNS:www.example.com,DNS:example.com,IP:192.168.1.100
然后使用-extfile san.txt
选项:
cmd
openssl x509 -req -in server.csr -signkey private_key.pem -out self_signed_certificate.pem -days 365 -sha256 -extfile san.txt - 在 PowerShell 中,可以类似地动态创建:
powershell
"subjectAltName=DNS:www.example.com,DNS:example.com,IP:192.168.1.100" | Out-File -Encoding ASCII san.txt
openssl x509 -req -in server.csr -signkey private_key.pem -out self_signed_certificate.pem -days 365 -sha256 -extfile san.txt
Remove-Item san.txt # 清理临时文件
- 在 Windows CMD 中,这会比较麻烦。您需要先创建一个文本文件,例如
注意:自签名证书在公共互联网上不被信任,浏览器会显示安全警告。
步骤 4(进阶):建立一个简单的本地 CA 并签署证书
如果您需要为内部服务签发多个受信任(在您的组织内部)的证书,可以建立一个简单的私有 CA。
1. 创建 CA 目录结构和基础文件
bash
mkdir myCA
cd myCA
mkdir certs crl newcerts private
chmod 700 private # 设置私钥目录权限(在 WSL 或 Git Bash 中)
touch index.txt
echo 1000 > serial # 初始序列号(十六进制)
2. 创建 CA 配置文件 (openssl_ca.cnf
)
复制一份系统的 openssl.cnf
文件,或者创建一个新的,至少包含以下内容(根据需要调整路径和默认值):
“`ini
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = C:/certs/myCA # CA 根目录 (使用正斜杠)
certs = $dir/certs # 已颁发证书存放目录
crl_dir = $dir/crl # CRL 存放目录
database = $dir/index.txt # 证书数据库索引文件
new_certs_dir = $dir/newcerts # 新证书备份目录
certificate = $dir/cacert.pem # CA 证书文件
serial = $dir/serial # 当前序列号文件
private_key = $dir/private/cakey.pem # CA 私钥文件
RANDFILE = $dir/private/.rand # 随机数文件
default_md = sha256 # 默认摘要算法
policy = policy_match # 证书策略
default_days = 730 # 默认证书有效期 (2年)
策略:定义 CSR 中的哪些字段必须与 CA 证书匹配
[ policy_match ]
countryName = match # 要求国家匹配
stateOrProvinceName = match # 要求省份匹配
organizationName = match # 要求组织匹配
organizationalUnitName = optional # 部门可选
commonName = supplied # CN 必须提供
emailAddress = optional # Email 可选
用于 v3 扩展的配置
[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:true
[ usr_cert ]
basicConstraints = CA:FALSE
nsCertType = server
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
subjectAltName = @alt_names # 引用 SAN
在这里定义服务器证书的 SAN (可以留空,在签名时通过 -extfile 指定)
[ alt_names ]
DNS.1 = www.example.com
DNS.2 = mail.example.com
IP.1 = 192.168.0.1
“`
3. 生成 CA 的私钥和根证书(自签名)
“`bash
生成 CA 私钥 (需要设置强密码并记住)
openssl genpkey -algorithm RSA -out private/cakey.pem -pkeyopt rsa_keygen_bits:4096 -aes-256-cbc
生成 CA 根证书 (自签名)
openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 3650 -sha256 \
-subj “/C=CN/ST=Beijing/L=Beijing/O=My Local CA/CN=My Local Root CA” \
-config openssl_ca.cnf -extensions v3_ca
``
-days 3650
* 会提示输入 CA 私钥的密码。
*: CA 根证书通常有效期很长(例如 10 年)。
-config openssl_ca.cnf
*: 使用我们刚创建的 CA 配置文件。
-extensions v3_ca
*: 应用配置文件中定义的
[ v3_ca ]` 扩展,标记这是一个 CA 证书。
4. 使用 CA 签署服务器证书请求 (CSR)
假设您已经有了一个服务器的 CSR 文件 server.csr
(在步骤 2 中生成)。
首先,创建包含 SAN 信息的扩展文件 server_san.txt
:
“`ini
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.internal.local
DNS.2 = server1.internal.local
IP.1 = 10.0.0.10
“`
然后,使用 openssl ca
命令签署:
bash
openssl ca -config openssl_ca.cnf -in ../server.csr -out certs/server_certificate.pem -days 365 \
-extfile server_san.txt -extensions usr_cert
- 会提示输入 CA 私钥的密码。
-config openssl_ca.cnf
: 指定 CA 配置文件。-in ../server.csr
: 输入要签名的 CSR 文件(假设 CSR 在上一级目录)。-out certs/server_certificate.pem
: 输出签名后的服务器证书。-days 365
: 设置服务器证书有效期。-extfile server_san.txt
: 关键! 指定包含 SAN 和其他扩展的文件。-extensions usr_cert
: 应用配置文件中[ usr_cert ]
节定义的扩展(它会引用server_san.txt
中的[alt_names]
)。
成功签署后,index.txt
会被更新,serial
文件中的序列号会增加,并在 newcerts
目录下生成一个以序列号命名的证书副本。
信任 CA 根证书:为了让客户端(如浏览器或其他服务器)信任由这个本地 CA 签发的证书,需要将 CA 的根证书 (cacert.pem
) 导入到客户端的信任存储中。在 Windows 上,可以通过 certlm.msc
(本地计算机) 或 certmgr.msc
(当前用户) 将其导入到 “受信任的根证书颁发机构” 存储区。
第五章:常用 OpenSSL 操作
除了生成密钥和证书,OpenSSL 还有许多其他有用的功能:
1. 查看证书信息
“`bash
查看 PEM 格式证书的详细信息
openssl x509 -in certificate.pem -text -noout
查看证书的 Subject, Issuer, Validity dates 等关键信息
openssl x509 -in certificate.pem -subject -issuer -dates -noout
查看证书的 SAN (Subject Alternative Name)
openssl x509 -in certificate.pem -text -noout | grep -A 1 “Subject Alternative Name” # (Git Bash/WSL)
或在 PowerShell 中:
(openssl x509 -in certificate.pem -text -noout) -match “Subject Alternative Name” -Context 0,1
“`
2. 查看 CSR 信息
“`bash
openssl req -in server.csr -text -noout -verify
-verify 会检查 CSR 的签名是否与其内部公钥匹配
“`
3. 查看私钥信息
“`bash
查看 RSA 私钥的详细信息 (包括公钥部分)
openssl rsa -in private_key.pem -text -noout
查看 ECC 私钥的详细信息
openssl ec -in ecc_private_key.pem -text -noout
检查私钥是否有效且一致
openssl rsa -in private_key.pem -check # (如果加密了会提示输入密码)
openssl ec -in ecc_private_key.pem -check
“`
4. 验证私钥、证书和 CSR 是否匹配
它们共享同一个公钥模数 (Modulus)。如果模数相同,则它们是匹配的。
“`bash
获取私钥的模数
openssl rsa -in private_key.pem -modulus -noout | openssl md5
(如果加密了会提示输入密码)
获取 CSR 的模数
openssl req -in server.csr -modulus -noout | openssl md5
获取证书的模数
openssl x509 -in certificate.pem -modulus -noout | openssl md5
“`
比较这三个命令输出的 MD5 哈希值,如果它们完全相同,则三者匹配。
5. 证书格式转换
OpenSSL 支持多种证书和密钥格式,常见的有 PEM, DER, PFX/P12。
- PEM (Privacy-Enhanced Mail): Base64 编码的 ASCII 文本格式,由
-----BEGIN ...-----
和-----END ...-----
包裹。可以包含证书、私钥、CSR 等。这是最常见的格式。 - DER (Distinguished Encoding Rules): 二进制格式。通常用于 Java 平台。
- PFX/P12 (PKCS#12): 二进制格式,通常用于在 Windows 环境中导入/导出证书和对应的私钥(打包在一个文件中),可以设置密码保护。
PEM -> DER
bash
openssl x509 -in certificate.pem -outform DER -out certificate.der
openssl rsa -in private_key.pem -outform DER -out private_key.der
DER -> PEM
bash
openssl x509 -in certificate.der -inform DER -outform PEM -out certificate.pem
openssl rsa -in private_key.der -inform DER -outform PEM -out private_key.pem
PEM (证书 + 私钥) -> PFX/P12
“`bash
将证书和未加密的私钥打包成 PFX 文件 (会提示设置 PFX 文件的导出密码)
openssl pkcs12 -export -out certificate.pfx -inkey private_key.pem -in certificate.pem
如果需要包含证书链 (例如:服务器证书 + 中间 CA 证书),先将它们合并到一个 PEM 文件中
cat server_certificate.pem intermediate_ca.pem > certificate_chain.pem (Git Bash/WSL)
copy /b server_certificate.pem + intermediate_ca.pem certificate_chain.pem (CMD)
Get-Content server_certificate.pem, intermediate_ca.pem | Set-Content certificate_chain.pem (PowerShell)
openssl pkcs12 -export -out certificate_bundle.pfx -inkey private_key.pem -in certificate_chain.pem
“`
PFX/P12 -> PEM (提取证书和私钥)
“`bash
提取私钥 (会提示输入 PFX 密码和设置 PEM 私钥密码)
openssl pkcs12 -in certificate.pfx -nocerts -out private_key_from_pfx.pem
提取证书 (会提示输入 PFX 密码)
openssl pkcs12 -in certificate.pfx -clcerts -nokeys -out certificate_from_pfx.pem
提取 CA 证书链 (如果 PFX 文件包含的话)
openssl pkcs12 -in certificate.pfx -cacerts -nokeys -out ca_chain_from_pfx.pem
如果提取的私钥被加密了,移除密码保护
openssl rsa -in private_key_from_pfx.pem -out private_key_unencrypted.pem (会提示输入 PEM 密码)
“`
第六章:故障排除与最佳实践
'openssl' is not recognized...
: 环境变量PATH
未正确设置或未重启命令窗口。检查路径是否包含 OpenSSL 的bin
目录。unable to load config file
: OpenSSL 找不到默认配置文件。可以尝试使用openssl version -d
找到OPENSSLDIR
并检查该目录下是否有openssl.cnf
。或者在命令中使用-config path/to/openssl.cnf
显式指定。- 权限错误: 无法写入文件或读取私钥。确保您对工作目录和私钥文件有读写权限。在 Windows 上,以管理员身份运行 CMD 或 PowerShell 可能解决某些权限问题,但需谨慎。
- 证书链问题: 当客户端验证证书时,需要完整的信任链(服务器证书 -> 中间 CA -> 根 CA)。确保服务器配置了发送完整的证书链(通常不包括根证书)。使用
openssl s_client -connect host:port -showcerts
可以检查服务器发送的链。 - SAN 至关重要: 再次强调,为 Web 服务器生成证书时,务必使用
subjectAltName
扩展包含所有需要保护的域名和 IP 地址。 - 保护私钥: 私钥的安全性是整个 PKI 系统的关键。不要共享私钥,确保存储私钥的文件权限严格,对生产环境的私钥使用强密码加密(
-aes256
等选项)。 - 保持更新: OpenSSL 是一个活跃的项目,会修复安全漏洞。定期检查并更新您安装的 OpenSSL 版本。
- 密钥长度: 对于 RSA,至少使用 2048 位,推荐 3072 或 4096 位。对于 ECC,使用
prime256v1
(NIST P-256) 或更强的曲线。 - 摘要算法: 使用 SHA-256 (
-sha256
) 或更强的摘要算法,避免使用 MD5 或 SHA-1。
结语
OpenSSL 是一个功能极其丰富的密码学工具箱,虽然它在 Windows 上的使用需要一些初始设置,但一旦安装和配置完成,它将成为您处理各种安全相关任务的得力助手。从生成简单的自签名证书用于本地开发,到建立内部 CA 管理组织内的证书,再到准备提交给公共 CA 的 CSR,OpenSSL 都能胜任。
本文详细介绍了在 Windows 上安装 OpenSSL 的多种方法、如何配置环境、PKI 的核心概念,并提供了生成私钥、CSR、自签名证书以及使用本地 CA 签署证书的详细步骤和命令示例。同时,也涵盖了一些常用的 OpenSSL 操作和故障排除技巧。
掌握 OpenSSL 的使用,不仅能解决实际工作中的证书和加密问题,更能加深对网络安全底层原理的理解。希望这篇详尽的指南能够帮助您在 Windows 平台上自信地运用 OpenSSL,从容应对各种挑战。不断实践和探索 OpenSSL 的更多功能(如加密/解密文件、性能测试、SSL/TLS 客户端/服务器测试等),您会发现它是一个值得深入学习的宝库。