搞定 Windows OpenSSL:安装、配置与证书生成 – wiki基地


搞定 Windows OpenSSL:从安装、配置到证书生成的终极指南

引言:为什么我们需要在 Windows 上使用 OpenSSL?

在当今数字化的世界中,安全是网络通信的基石。无论是浏览网页(HTTPS)、发送邮件(SMTPS/IMAPS)、连接 VPN 还是保护 API,加密和身份验证都扮演着至关重要的角色。OpenSSL 项目提供了一个强大、商业级且功能齐全的工具包,实现了 SSL(安全套接字层)和 TLS(传输层安全)协议以及一个通用的密码学库。它包含了用于生成私钥、创建证书签名请求(CSR)、安装 SSL/TLS 证书、生成自签名证书、管理证书颁发机构(CA)以及执行各种加密任务的核心工具。

虽然 OpenSSL 起源于类 Unix 系统(如 Linux、macOS),并且在这些平台上是标准配置,但 Windows 用户,特别是开发者、系统管理员和安全专业人士,也经常需要利用 OpenSSL 的强大功能。原因包括:

  1. 跨平台开发与测试:许多应用程序和服务需要跨平台运行,在 Windows 上模拟或管理与 Linux/macOS 服务器相同的证书和密钥环境至关重要。
  2. 本地开发环境:为本地 Web 服务器(如 IIS, Apache, Nginx on Windows)配置 HTTPS,需要生成或处理证书。
  3. 证书管理:需要生成 CSR 发送给商业 CA,或者需要创建内部使用的自签名证书或私有 CA。
  4. 脚本自动化:在 Windows 批处理或 PowerShell 脚本中集成 OpenSSL 命令,实现证书管理和加密任务的自动化。
  5. 学习与实验:理解 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 安装程序。

  1. 访问下载页面:在浏览器中访问 Shining Light Productions 的 Win32/Win64 OpenSSL 下载页面(可以通过搜索引擎搜索 “OpenSSL Windows SLP” 找到官方或可信赖的镜像源)。
  2. 选择版本
    • 架构:根据您的 Windows 系统是 32 位 (Win32) 还是 64 位 (Win64) 选择对应的版本。现代系统通常是 64 位。
    • 版本号:通常建议选择最新的稳定版(LTS – 长期支持版通常更稳定)。避免使用 “Light” 版本,因为它可能缺少开发所需的头文件和库。选择完整版(通常文件名不含 “Light”)。
    • 安装程序类型:通常提供 .exe 安装程序和 .zip 压缩包。
      • EXE 安装程序:更方便,通常会提供添加到系统 PATH 的选项。
      • ZIP 压缩包:绿色版,解压即可使用,但需要手动配置环境变量。
  3. 下载与安装(以 EXE 为例)
    • 下载所选的 .exe 文件。
    • 运行安装程序。仔细阅读许可协议。
    • 选择安装路径:建议选择一个不包含空格或特殊字符的路径,例如 C:\Program Files\OpenSSLC:\Tools\OpenSSL
    • 关键步骤:选择组件:确保选中了 OpenSSL 可执行文件 (openssl.exe) 和相关的库文件。
    • 重要选项:复制 OpenSSL DLLs 到:安装程序可能会询问将 OpenSSL DLL(如 libcrypto-*.dll, libssl-*.dll)复制到哪里。推荐选择 “The OpenSSL binaries (/bin) directory”。不建议选择复制到 Windows 系统目录(System32),这可能导致版本冲突。
    • 完成安装
  4. 安装(以 ZIP 为例)
    • 下载所选的 .zip 文件。
    • 将其解压到一个合适的目录,例如 C:\Tools\OpenSSL。解压后,openssl.exe 通常位于 bin 子目录下。

方法二:通过 Windows Subsystem for Linux (WSL)

如果您是开发者,并且已经在 Windows 10/11 上使用了 WSL 或 WSL 2,那么这可能是最无缝的方式。WSL 允许您运行一个 Linux 环境,其中 OpenSSL 通常是预装或可以通过包管理器轻松安装。

  1. 安装 WSL:如果尚未安装,请打开 PowerShell (管理员权限) 并运行 wsl --install。根据提示可能需要重启。这将安装默认的 Ubuntu 发行版。您也可以从 Microsoft Store 安装其他 Linux 发行版。
  2. 启动 WSL:在开始菜单搜索您安装的 Linux 发行版(如 Ubuntu)并启动它。
  3. 检查/安装 OpenSSL:在 WSL 终端中,运行 openssl version 检查是否已安装。如果未安装或版本过旧,使用发行版的包管理器进行安装/更新:
    • Debian/Ubuntu: sudo apt update && sudo apt install openssl
    • CentOS/Fedora: sudo dnf update && sudo dnf install opensslsudo yum update && sudo yum install openssl
  4. 使用:在 WSL 终端内,您可以直接使用 openssl 命令,就像在原生 Linux 环境中一样。文件系统是互通的,您可以通过 /mnt/c/ 访问 Windows 的 C 盘。

优点:获得与 Linux 完全一致的体验。
缺点:需要在 WSL 环境下操作,对于只需要 OpenSSL 命令行的用户可能稍显重量级。

方法三:使用 Git for Windows 自带的 OpenSSL

如果您安装了 Git for Windows(一个非常流行的工具),它会捆绑一个 OpenSSL 的版本,主要供 Git 内部使用(例如 HTTPS 连接)。

  1. 安装 Git for Windows:从官网下载并安装。
  2. 找到 OpenSSL:安装完成后,openssl.exe 通常位于 Git 安装目录下的 usr\bin 子目录中,例如 C:\Program Files\Git\usr\bin\openssl.exe
  3. 使用
    • 可以通过 Git Bash 终端直接使用 openssl 命令,因为它已经配置好了环境。
    • 如果想在 Windows 命令提示符 (CMD) 或 PowerShell 中使用,需要将 C:\Program Files\Git\usr\bin (根据您的实际安装路径调整) 添加到系统环境变量 PATH 中。

优点:如果已安装 Git,则无需额外安装。
缺点:捆绑的 OpenSSL 版本可能不是最新的,且主要目的是服务于 Git,可能不是功能最全的版本。

方法四:自行编译(高级)

这是最复杂的方法,需要安装编译器(如 Visual Studio)、Perl (通常推荐 Strawberry Perl) 和 NASM 汇编器。

  1. 从 OpenSSL 官网下载源代码 (.tar.gz)。
  2. 解压源代码。
  3. 仔细阅读 NOTES-WINDOWS.mdINSTALL.md 文件中的 Windows 编译指南。
  4. 配置编译环境(设置 VS 环境变量等)。
  5. 运行 perl Configure VC-WIN64A (64位) 或 VC-WIN32 (32位) 以及其他选项。
  6. 运行 nmake
  7. 运行 nmake test (可选但推荐)。
  8. 运行 nmake install

优点:可以获得最新版本,完全控制编译选项。
缺点:过程复杂,易出错,耗时,不适合大多数用户。

第二章:配置 Windows 环境

无论您选择哪种安装方式(除了 WSL,它有自己的环境),为了能在任何路径下的命令提示符 (CMD) 或 PowerShell 中直接使用 openssl 命令,您需要配置 Windows 的环境变量 PATH

配置环境变量 PATH

  1. 找到 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
  2. 编辑系统环境变量
    • 在 Windows 搜索栏中输入 “环境变量”,然后选择 “编辑系统环境变量”。
    • 在弹出的 “系统属性” 对话框中,点击 “高级” 选项卡下的 “环境变量(N)…” 按钮。
    • 在 “环境变量” 对话框中,找到 “系统变量(S)” 区域下的 Path 变量,选中它,然后点击 “编辑(E)…”。
    • 在 “编辑环境变量” 对话框中,点击 “新建(N)”,然后粘贴或输入您找到的 OpenSSL bin 目录的完整路径。
    • 点击 “确定” 关闭所有打开的对话框。
  3. 验证配置
    • 重要:关闭所有已打开的 CMD 或 PowerShell 窗口,然后重新打开一个新的窗口。环境变量的更改只对新启动的进程生效。
    • 在新窗口中输入命令:openssl version
    • 如果配置成功,您应该能看到已安装的 OpenSSL 版本信息,例如 OpenSSL 3.0.5 5 Jul 2022 (Library: OpenSSL 3.0.5 5 Jul 2022)
    • 如果提示 “‘openssl’ 不是内部或外部命令…”,请检查您的 PATH 变量设置是否正确,路径是否无误,以及是否重启了命令窗口。

理解 OpenSSL 配置文件 (openssl.cnfopenssl.cfg)

OpenSSL 的许多行为,特别是 req(证书请求)和 ca(证书颁发机构)命令的行为,都受到配置文件的影响。

  • 查找配置文件:OpenSSL 会在几个预定义的位置查找配置文件。对于 SLP 安装的版本,通常位于 OpenSSL 安装目录下的 sslcerts 文件夹内,或者与 openssl.exe 在同一 bin 目录下。您可以通过 openssl version -d 查看 OPENSSLDIR,这通常是配置文件的根目录。
  • 默认配置文件:通常名为 openssl.cnfopenssl.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 # 清理临时文件

注意:自签名证书在公共互联网上不被信任,浏览器会显示安全警告。

步骤 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
``
* 会提示输入 CA 私钥的密码。
*
-days 3650: 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 客户端/服务器测试等),您会发现它是一个值得深入学习的宝库。


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部