OpenSSL 自签名证书生成教程 – wiki基地


OpenSSL 自签名证书生成教程:从入门到精通

在现代网络世界中,数据传输安全至关重要。无论是访问网站、发送电子邮件还是进行API通信,我们都希望数据能够加密传输,防止被窃听或篡改。传输层安全(TLS)协议(其前身为安全套接层SSL协议)正是实现这一目标的核心技术。而数字证书则是TLS/SSL协议中用于验证通信方身份和建立加密通道的关键组成部分。

通常,在生产环境中,我们会使用由受信任的第三方证书颁发机构(Certificate Authority, CA)签发的证书。这些CA(如Let’s Encrypt, DigiCert, Sectigo等)在全球范围内被操作系统、浏览器和应用程序广泛信任。然而,在开发、测试、内部网络、个人项目或学习阶段,为了快速搭建一个支持HTTPS/TLS的环境,购买或申请CA签发的证书可能不太方便或没有必要。这时,自签名证书(Self-Signed Certificate)就派上了用场。

什么是自签名证书?

顾名思义,自签名证书就是由证书创建者自己签发的证书,而不是由任何受信任的第三方CA签发。这意味着证书的签名者和被签发者是同一个实体。

为什么使用自签名证书?

自签名证书的主要优点在于:

  1. 成本低廉(免费):无需向CA支付任何费用。
  2. 获取便捷:可以在任何安装了OpenSSL等工具的机器上随时生成。
  3. 灵活性高:可以自定义证书的有效期、主题信息(Common Name, CN)、主题备用名称(Subject Alternative Name, SAN)等所有字段。
  4. 适用于特定场景:非常适合本地开发环境的HTTPS测试、内部网络服务(如Jenkins、GitLab私有部署)、个人实验项目、学习TLS/SSL原理等。

自签名证书的局限性

尽管方便,自签名证书也有其显著的局限性:

  1. 不受信任:由于不是由被广泛信任的CA签发,操作系统、浏览器和大多数客户端应用程序默认会认为它不受信任
  2. 安全警告:使用自签名证书访问网站时,浏览器会显示醒目的安全警告(如“连接不是私密的”、“您的连接不安全”等),用户需要手动选择信任或继续访问。这在生产环境中是不可接受的,会严重影响用户体验。
  3. 中间人攻击风险:在公共网络上,由于证书的身份无法被第三方验证,攻击者可以更容易地实施中间人攻击(Man-in-the-Middle, MITM),用自己的自签名证书冒充目标服务器,而用户难以察觉。
  4. 功能受限:某些高级的TLS功能或新的安全标准可能对证书的信任链有要求,自签名证书可能无法满足。

总结: 自签名证书适用于无需外部信任的封闭或受控环境。绝对不应在面向公众的生产环境中使用自签名证书。

什么是 OpenSSL?

OpenSSL 是一个强大的开源加密工具包,实现了SSL和TLS协议,并提供了丰富的命令行工具,用于生成私钥、公钥、证书签名请求(CSR)、管理证书、进行加密解密操作、测试TLS/SSL连接等。它是生成自签名证书最常用和最强大的工具之一。

准备工作:安装 OpenSSL

大多数 Linux 和 macOS 系统预装了 OpenSSL。你可以在终端中输入以下命令来检查是否已安装及版本:

bash
openssl version

如果命令有效并显示版本信息,说明OpenSSL已安装。

在 Windows 系统上,你需要单独下载并安装 OpenSSL。可以从其官方网站或第三方维护者处获取安装包。安装后,可能需要将 OpenSSL 的 bin 目录添加到系统的 PATH 环境变量中,以便在任何位置调用 openssl 命令。

安装完成后,就可以开始使用 OpenSSL 生成自签名证书了。

核心概念回顾

在生成证书之前,快速回顾几个核心概念对理解命令参数很有帮助:

  • 私钥 (Private Key):一段保密的加密数据,用于对数据进行签名或解密只有与该私钥配对的公钥加密的数据。私钥必须严格保密。
  • 公钥 (Public Key):由私钥派生而来,用于验证私钥签名的数据,或加密只有与该公钥配对的私钥才能解密的数据。公钥是公开的。
  • 证书 (Certificate / X.509 Certificate):一个数字文档,包含了持有者的公钥、身份信息(如域名、组织、位置等)、证书的有效期以及由签发机构(CA 或自身)的私钥对该证书内容的签名。证书的作用是将一个公钥绑定到一个特定的身份。
  • 证书签名请求 (Certificate Signing Request, CSR):一个包含申请者公钥和身份信息的文件,用于提交给CA以申请签发证书。对于自签名证书,我们有时会先生成CSR再自己签发,有时则一步到位直接生成证书。

生成自签名证书的方法

OpenSSL 提供了多种生成自签名证书的方法。我们将介绍从最简单到更高级的几种,包括如何添加 Subject Alternative Name (SAN),因为 SAN 对于现代浏览器信任证书(即使是自签名的)至关重要。

重要提示: 在执行命令时,你需要在一个你拥有写权限的目录下,以便生成的文件能够保存。

方法一:最简单的一步到位生成 (不推荐用于现代应用,因为它主要依赖于 Common Name)

这个方法使用一个命令生成私钥和证书。它会提示你输入一些信息来填充证书的字段。

bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.crt

让我们分解这个命令的各个部分:

  • openssl req: 这是一个多用途命令,用于处理证书签名请求(CSR)和证书。
  • -x509: 这个选项告诉 req 命令输出一个自签名证书,而不是一个CSR。当你使用 -x509 选项时,-new-newkey 选项会自动创建一个自签名证书,使用 -days 选项指定的有效期。
  • -nodes: 这个选项表示不使用 DES 加密来保护生成的私钥。这意味着私钥文件(server.key)在磁盘上将是未加密的纯文本。这样做是为了方便,特别是在自动化脚本或服务器启动时,无需手动输入密码。但是,未加密的私钥风险更高,一旦文件泄露,任何人都可以使用它。在更安全的环境中,你应该省略 -nodes 并为私钥设置一个密码,然后在需要时(例如,Web服务器启动)提供该密码。
  • -days 365: 设置证书的有效期,单位是天。这里设置为 365 天,即一年。你可以根据需要调整这个数字。
  • -newkey rsa:2048: 这个选项表示生成一个新的私钥。
    • rsa: 指定密钥类型为 RSA。RSA 是一种常用的非对称加密算法。
    • 2048: 指定 RSA 密钥的长度为 2048 位。2048 位 RSA 密钥目前被认为是安全的,是常用的标准。更长的密钥(如 4096 位)更安全但也更耗费计算资源。
  • -keyout server.key: 指定生成的私钥的输出文件名。这里是 server.key
  • -out server.crt: 指定生成的自签名证书的输出文件名。这里是 server.crt.crt.cer 都是常见的证书文件扩展名。

执行上述命令后,系统会提示你输入一些信息来填充证书的主体(Subject)字段。这些信息构成了证书所有者的身份:

“`
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, this field will be left blank.


Country Name (2 letter code) [AU]:CN # 国家代码 (例如 CN, US)
State or Province Name (full name) [Some-State]:Beijing # 省/州
Locality Name (eg, city) []:Beijing # 城市
Organization Name (eg, company) [Internet Widgits Pty Ltd]:My Local Dev # 组织/公司名称
Organizational Unit Name (eg, section) []:IT Dept # 组织单位名称 (可选)
Common Name (e.g. server FQDN or YOUR name) []:localhost # 通用名称 (Common Name, CN)非常重要! 对于服务器证书,这里通常是服务器的完全限定域名 (FQDN) 或 IP 地址。
Email Address []:[email protected] # 邮箱地址 (可选)
“`

在提示符处逐一输入相应信息(或者直接按回车接受默认值,除了 Common Name 强烈建议输入)。

Common Name (CN) 是历史上用于标识服务器域名的主要字段。然而,现代浏览器已经不推荐甚至逐步废弃依赖 CN 字段进行域名匹配,而是优先或强制使用 Subject Alternative Name (SAN) 字段。

因此,虽然这个方法简单,但生成的证书在现代浏览器中访问时,如果 CN 不是 localhost 或准确匹配你访问的域名/IP,仍然可能会因为缺少 SAN 而产生更严重的警告或直接拒绝连接。

方法二:分开生成私钥和证书 (提供了更灵活的密钥管理)

你可以先独立生成私钥,然后再用该私钥生成自签名证书。

步骤 1:生成私钥

bash
openssl genrsa -out server.key 2048

  • openssl genrsa: 生成 RSA 私钥的命令。
  • -out server.key: 指定输出文件名为 server.key
  • 2048: 指定 RSA 密钥长度为 2048 位。

默认情况下,genrsa 生成的私钥是未加密的。如果你想为私钥设置密码以增加安全性(省略 -nodes 的效果),可以使用 -des3, -aes128, -aes256 等选项。例如:

bash
openssl genrsa -aes256 -out server.key 2048

执行此命令后,系统会提示你输入并验证一个密码。将来使用这个私钥时(例如,启动 Web 服务器),你需要提供这个密码。

步骤 2:使用已生成的私钥生成自签名证书

bash
openssl req -x509 -new -nodes -days 365 -key server.key -out server.crt

  • -new: 创建一个新的证书请求。当与 -x509-key 一起使用时,它会使用指定的私钥创建一个新的自签名证书。
  • -key server.key: 指定用于签发证书的私钥文件。这里使用了上一步生成的 server.key
  • 其他参数 (-x509, -nodes, -days 365, -out server.crt) 的含义与方法一相同。注意这里也使用了 -nodes 来避免在生成证书时再次为私钥输入密码(如果私钥本身是加密的,这个 -nodes 只影响证书生成过程是否需要密码,不会解密私钥文件本身)。如果你在上一步生成了加密的私钥,这里去掉 -nodes 将会提示你输入私钥密码。

执行此命令后,同样会提示你输入证书的主体信息(Country, State, Locality, Organization, Common Name 等)。

这种方法的好处是你可以独立管理和备份你的私钥。例如,你可以先生成一个加密的私钥,然后只在需要生成/更新证书时使用它。

方法三:生成带有 Subject Alternative Name (SAN) 的证书 (推荐用于现代应用)

正如前面提到的,SAN 字段是现代浏览器验证服务器身份的首选方式。它允许你在证书中列出多个域名和/或IP地址,这样证书就可以用于所有这些名称。例如,一个证书可以同时对 localhost, mydev.local, 192.168.1.100 等多个地址有效。

生成带有 SAN 的自签名证书需要使用 OpenSSL 的配置文件。

步骤 1:创建或修改 OpenSSL 配置文件

你需要一个 OpenSSL 配置文件来指定 SAN 扩展。OpenSSL 的默认配置文件通常位于 /etc/ssl/openssl.cnf (Linux/macOS) 或 OpenSSL 安装目录下的 openssl.cnf (Windows)。不建议直接修改系统默认的配置文件。更好的做法是创建一个新的配置文件,或者复制默认文件并修改。

创建一个名为 san.cnf 的文件(或其他你喜欢的名字),内容如下:

“`ini
[ req ]

req_extensions = v3_req # 如果使用 req -new 命令生成 CSR 时需要 SAN,则取消注释此行,并确保 req_extensions 指向包含 SAN 的 section

These are removed when -subj is used.

distinguished_name = req_distinguished_name # 如果使用交互式输入主题信息,则取消注释此行

prompt = no # 如果设置为 no,则不提示输入主题信息,必须使用 -subj 选项或 distinguished_name section

[ req_distinguished_name ]
C = CN # Country Name (2 letter code)
ST = Beijing # State or Province Name
L = Beijing # Locality Name (eg, city)
O = My Local Dev # Organization Name (eg, company)
OU = IT Dept # Organizational Unit Name (optional)
CN = localhost # Common Name (e.g. server FQDN or YOUR name) – 仍然需要,但SAN更重要

[ v3_req ]

Extensions to add to a certificate request

For client certificates: basicConstraints = CA:FALSE

For server certificates: basicConstraints = CA:FALSE

使用 subjectAltName 扩展指定 SANs

subjectAltName = @alt_names

[ v3_ext ]

Extensions to add to a certificate (when signing)

basicConstraints = CA:FALSE # 如果这个自签名证书不会用于签发其他证书,设置为 CA:FALSE 是最佳实践

keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names # 引用 SAN 定义的 section

[ alt_names ]

定义 Subject Alternative Name (SAN)

DNS. 用于域名, IP. 用于 IP 地址

DNS.1 = localhost
DNS.2 = mydev.local
DNS.3 = *.mydev.local # 示例:支持通配符子域名 (通配符证书)
IP.1 = 127.0.0.1
IP.2 = 192.168.1.100
IP.3 = 10.0.0.50

更多 DNS 或 IP 地址…

“`

配置文件的解释:

  • [ req ]: 配置 openssl req 命令的行为。
    • prompt = no: 设置为 no 可以避免交互式输入主题信息,此时必须通过 -subj 命令行参数或在 [ req_distinguished_name ] section 中指定。
    • req_extensions = v3_req: 如果你先生成一个 CSR (openssl req -new) 并希望 CSR 中包含 SAN 信息以便后续使用它生成证书,则需要启用此项。对于一步到位生成自签名证书 (openssl req -x509), 重要的扩展部分是 [ v3_ext ],它通过 -extensions-extfile 参数引用。
  • [ req_distinguished_name ]: 定义证书主体信息(如果 prompt = no 并且不使用 -subj)。
  • [ v3_req ]: 定义用于证书请求 (CSR) 的 X.509v3 扩展。这里的 subjectAltName 如果在 req_extensions 中引用,会包含在 CSR 里。
  • [ v3_ext ]: 定义用于证书的 X.509v3 扩展。对于自签名证书 (-x509),这是最关键的 SAN 定义位置,需要通过 -extensions-extfile 参数引用。
  • [ alt_names ]: 定义具体的 SAN 条目。
    • DNS.<number> = <hostname>: 指定域名。
    • IP.<number> = <ip_address>: 指定 IP 地址。
    • 根据需要添加任意数量的 DNS 或 IP 条目。

步骤 2A:一步到位生成带有 SAN 的自签名证书 (推荐)

这是最常用的方法,结合了生成私钥、证书以及 SAN 扩展。

bash
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout server.key -out server.crt \
-config san.cnf \
-extensions v3_ext \
-subj "/C=CN/ST=Beijing/L=Beijing/O=My Local Dev/OU=IT Dept/CN=localhost"

分解这个命令:

  • 前面大部分参数 (-x509, -nodes, -days 365, -newkey rsa:2048, -keyout server.key, -out server.crt) 与方法一和方法二类似。
  • -config san.cnf: 指定使用我们创建的配置文件 san.cnf
  • -extensions v3_ext: 告诉 OpenSSL 在生成证书时使用配置文件中 [ v3_ext ] section 定义的扩展。这是将 SAN 添加到最终证书的关键。
  • -subj "/C=.../ST=.../L=.../O=.../OU=.../CN=...": 通过命令行直接指定证书的主体信息,避免交互式输入。/C=CN/ST=Beijing/... 是一种标准的 Distinguished Name 格式。确保 /CN= 字段与你在 [ alt_names ] 中列出的某个 DNS 名称(通常是第一个)一致,尽管 SAN 是主要的匹配项,但某些旧系统或工具可能仍然依赖 CN。

执行此命令后,会在当前目录下生成 server.keyserver.crt 文件,其中 server.crt 就包含了你在 san.cnf 文件 [ alt_names ] section 中定义的所有域名和 IP 地址作为 SAN。

步骤 2B:先生成 CSR (包含 SAN),再自签名该 CSR (更贴近标准流程)

这种方法更接近CA签发证书的标准流程:先生成私钥和CSR,然后使用该CSR生成证书。对于自签名,签发机构就是我们自己。

  • 2B.1:生成私钥 (同方法二的步骤 1)
    bash
    openssl genrsa -out server.key 2048

    或者带密码:
    bash
    openssl genrsa -aes256 -out server.key 2048

  • 2B.2:生成包含 SAN 的 CSR
    你需要修改 san.cnf 文件,确保 [ req ] section 中的 req_extensions 行被取消注释,并指向 [ v3_req ] 或其他包含 SAN 定义的 section。例如:
    “`ini
    [ req ]
    req_extensions = v3_req # 使用 v3_req 定义的扩展 (SAN)
    prompt = no
    distinguished_name = req_distinguished_name

    [ req_distinguished_name ]
    C = CN
    ST = Beijing
    L = Beijing
    O = My Local Dev
    OU = IT Dept
    CN = localhost # 这个CN会被包含在CSR中

    [ v3_req ] # 这个 section 定义了 CSR 的扩展
    subjectAltName = @alt_names

    [ alt_names ] # SAN 定义
    DNS.1 = localhost
    DNS.2 = mydev.local
    IP.1 = 127.0.0.1

    … 其他 SAN 条目 …

    注意:这里不需要 [ v3_ext ] section 来定义证书扩展,因为我们在生成 CSR 阶段已经定义了 SAN,

    并在下一步自签名时引用 CSR 中的扩展。

    “`

    然后执行命令生成 CSR:
    bash
    openssl req -new -key server.key -out server.csr -config san.cnf

    * -new: 生成一个新的证书请求。
    * -key server.key: 使用这个私钥生成请求。
    * -out server.csr: 输出 CSR 文件。
    * -config san.cnf: 使用配置文件指定主题信息和 SAN 扩展。
    * 如果你在 san.cnf 中设置了 prompt = yes 或没有 -subj 部分,这里会提示你输入主题信息。

  • 2B.3:自签名 CSR 生成证书
    现在,使用私钥和你刚刚生成的 CSR 来签发证书:
    bash
    openssl x509 -req -in server.csr -signkey server.key -out server.crt -days 365 -extensions v3_req -extfile san.cnf

    分解这个命令:

    • openssl x509: 用于处理 X.509 证书。
    • -req: 指明输入文件是一个 CSR (server.csr)。
    • -in server.csr: 指定输入的 CSR 文件。
    • -signkey server.key: 指定用于签发证书的私钥(自签名时就是证书持有者的私钥)。
    • -out server.crt: 输出生成的证书文件。
    • -days 365: 设置证书有效期。
    • -extensions v3_req: 指定使用配置文件中 [ v3_req ] section 定义的扩展。注意:这里引用的是 CSR 中的扩展定义 section。 如果你的 SAN 定义在 [ v3_ext ] 或其他 section,这里需要相应修改,并确保 -extfile 参数指向正确的配置文件。
    • -extfile san.cnf: 指定包含扩展定义的配置文件。

这种方法分步骤更清晰,有助于理解 CSR 的作用,并且在某些自动化流程中可能更有优势。

总结: 对于大多数现代自签名证书需求,推荐使用方法三,特别是步骤 2A (一步到位),因为它直接生成带有 SAN 的证书,且命令相对简洁。确保你的 san.cnf 文件正确配置了 [ alt_names ][ v3_ext ] section (或 [ v3_req ] 如果走 CSR 流程)。

理解生成的证书文件

生成证书后,你会有两个主要文件:

  • server.key: 你的私钥文件。内容通常以 -----BEGIN RSA PRIVATE KEY----------BEGIN PRIVATE KEY----- 开头,以 -----END RSA PRIVATE KEY----------END PRIVATE KEY----- 结尾。这个文件非常重要,必须保密!
  • server.crt: 你的自签名证书文件。内容通常以 -----BEGIN CERTIFICATE----- 开头,以 -----END CERTIFICATE----- 结尾。这是 PEM 编码的 X.509 证书。你可以公开这个文件。

有时你可能还会看到 .pem 扩展名的文件。.pem 是一种容器格式,它可以包含私钥、证书、CSR,或者它们中的任何组合。通常,一个 .pem 文件可以包含证书(以 -----BEGIN CERTIFICATE----- 开头)和其对应的私钥(以 -----BEGIN PRIVATE KEY----------BEGIN RSA PRIVATE KEY----- 开头)串联在一起。许多服务器软件(如 Nginx)可以配置为使用单独的 .key.crt 文件,也有一些(如某些Java应用)可能需要一个包含两者或特定格式的 .pem 文件。你可以简单地将 .key.crt 文件的内容连接起来创建一个 .pem 文件:

bash
cat server.key server.crt > server.pem

查看证书详情

你可以使用 OpenSSL 命令来查看生成的证书或 CSR 的详细信息,验证是否包含了正确的CN、SAN、有效期等。

查看证书详情:

bash
openssl x509 -in server.crt -text -noout

  • openssl x509: 处理 X.509 证书。
  • -in server.crt: 指定输入文件是 server.crt
  • -text: 以人类可读的文本格式输出证书内容。
  • -noout: 不要输出 PEM 编码的证书本身,只输出文本信息。

执行此命令后,你会看到证书的各个字段,包括版本、序列号、签名算法、签发者 (Issuer)、主体 (Subject)、有效期 (Validity)、公钥信息、以及最重要的 Subject Alternative Name (SAN) 扩展。检查 SAN 字段,确认它包含了你期望的所有域名和 IP 地址。

查看 CSR 详情 (如果你生成了 CSR):

bash
openssl req -in server.csr -text -noout

这会显示 CSR 中的主体信息、公钥以及包含的扩展信息(如 SAN)。

在服务器中使用自签名证书

生成 server.keyserver.crt 文件后,你就可以将它们配置到你的 Web 服务器或其他需要 TLS/SSL 的应用程序中。不同服务器的配置方法不同,但通常都需要指定私钥文件和证书文件的路径。

例如:

  • Nginx:
    “`nginx
    server {
    listen 443 ssl;
    server_name localhost mydev.local; # 或你的IP/域名

    ssl_certificate server.crt;
    ssl_certificate_key server.key;
    
    # ... 其他配置
    

    }
    * **Apache:**apache

    ServerName localhost # 或你的域名/IP
    # ServerAlias mydev.local … # 如果有多个SAN域名

    SSLEngine on
    SSLCertificateFile /path/to/your/server.crt
    SSLCertificateKeyFile /path/to/your/server.key
    
    # ... 其他配置
    


    * **Node.js `https` 模块:**javascript
    const https = require(‘https’);
    const fs = require(‘fs’);

    const options = {
    key: fs.readFileSync(‘server.key’),
    cert: fs.readFileSync(‘server.crt’)
    };

    https.createServer(options, (req, res) => {
    res.writeHead(200);
    res.end(‘Hello HTTPS World!\n’);
    }).listen(8443, () => {
    console.log(‘HTTPS server listening on port 8443’);
    });
    “`

配置完成后,重启你的服务器或应用程序。

处理浏览器警告

当你使用浏览器访问配置了自签名证书的网站时,由于证书不受信任,浏览器会显示安全警告。要绕过这个警告,你有几种选择:

  1. 忽略警告并继续访问:大多数浏览器都提供了“继续访问”、“接受风险”或类似的选项。这仅用于临时访问,并且每次都会出现警告。
  2. 将自签名证书导入到操作系统的信任存储中:这是解决警告的最彻底方法(针对特定机器)。将 .crt 文件作为“受信任的根证书颁发机构”导入到你的操作系统(Windows、macOS、Linux)或浏览器(如 Firefox 有自己的证书存储)的证书信任存储中。导入后,该机器上的浏览器和其他应用程序就会信任这个证书,不再显示警告。导入过程因操作系统和浏览器而异,通常可以在操作系统的“证书管理器”或浏览器的“隐私与安全”设置中找到。请谨慎导入不受信任的证书,只导入你自己生成的并确定安全的证书。
  3. 使用工具辅助:有一些开发工具或库(如 mkcert)可以更方便地在本地生成并自动信任自签名证书,简化了手动导入的过程。

特别提示: 确保你访问网站时使用的域名或 IP 地址精确匹配你的证书中的 CN(历史原因)或 SAN 条目。如果不匹配,即使导入了证书,浏览器仍然会因为名称不匹配而显示警告(通常是 NET::ERR_CERT_COMMON_NAME_INVALID 或类似的错误)。这就是 SAN 字段的重要性所在。

故障排除与常见问题

  • openssl command not found: OpenSSL 没有安装或其执行路径没有添加到系统的 PATH 环境变量中。
  • Permission denied: 你可能在没有写权限的目录执行命令,或者输出文件已存在但你没有覆盖的权限。尝试在用户主目录下或创建一个新目录进行操作。
  • 生成私钥时总是提示输入密码,即使使用了 -nodes: 检查命令是否正确,-nodes 必须紧跟在 openssl reqopenssl genrsa 后面。
  • 浏览器警告仍然存在,即使导入了证书:
    • 名称不匹配: 这是最常见的问题。检查你访问的 URL (域名或 IP) 是否在证书的 SAN 列表中。使用 openssl x509 -in server.crt -text -noout 检查证书内容。如果你使用的是 IP 地址访问,证书的 SAN 中必须包含该 IP 地址。如果你使用的是域名访问,SAN 中必须包含该域名。
    • 证书导入错误: 确认你将证书导入到了正确的位置(通常是“受信任的根证书颁发机构”)并且导入成功。重启浏览器或计算机有时是必要的。
    • 证书过期: 检查证书的有效期 (openssl x509 -in server.crt -text -noout 中的 Validity 字段)。如果过期,重新生成证书。
    • 系统时间错误: 确保你的计算机系统时间是正确的。
    • 服务器配置错误: 确认你的服务器配置确实指向了新生成的私钥和证书文件,并且服务器已重启。
  • 使用配置文件时提示 Error loading extension section <section_name>: 配置文件中指定的 section 名称不正确,或者文件路径错误。检查 -extensions 参数是否与配置文件中的 section 名称匹配,以及 -extfile 参数是否指向正确的配置文件路径。
  • 生成的私钥有密码,但服务器启动时没有提示输入密码或报错: 服务器配置可能没有正确处理带密码的私钥,或者没有在启动时提供密码。对于自动化部署,通常会选择无密码的私钥 (-nodes),但要注意其安全风险。

安全注意事项

  • 私钥安全:无密码的私钥 (-nodes) 提供了便利,但也带来了安全隐患。如果你的私钥文件落入恶意方手中,他们可以轻松冒充你的服务器。在非开发/测试环境或更关注安全性的场景下,考虑为私钥设置密码,并采取措施在服务器启动时安全地提供密码。
  • 自签名证书的信任范围:记住,自签名证书只在手动将其导入信任存储的机器上被信任。它不具备全球性的信任。
  • 不要在公共生产环境使用:再次强调,永远不要在面向公共用户的生产网站或服务上使用自签名证书,除非你希望用户看到安全警告或无法访问。

结论

通过本教程,你应该已经掌握了使用 OpenSSL 生成自签名证书的各种方法,从最简单的一步到位,到更安全地分开生成私钥和证书,以及最重要的——如何生成包含 Subject Alternative Name (SAN) 的证书以适应现代浏览器和应用程序的需求。

自签名证书是开发和测试阶段的强大工具,能够帮助你在无需依赖外部CA的情况下快速搭建安全的TLS/SSL环境。然而,理解其局限性并仅在合适的场景下使用至关重要。

熟练掌握 OpenSSL 的命令行工具,不仅能让你自由生成和管理自签名证书,也是深入理解 TLS/SSL 工作原理和证书体系结构的良好开端。希望这篇详细教程对你有所帮助!

发表评论

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

滚动至顶部