OpenSSL 精粹:SSL 证书、私钥和 CSR

2020-06-07
9分钟阅读时长

介绍

OpenSSL 是一个多功能的命令行工具,可以用于与 公钥基础设施 Public Key Infrastructure (PKI)和 HTTPS(HTTP over TLS)相关的大量任务。这本小抄风格的指南提供了 OpenSSL 命令的快速参考,这些命令在常见的日常场景中非常有用。这包括生成私钥、 证书签署请求 certificate signing request (CSR)和证书格式转换的 OpenSSL 示例,但它并没有涵盖 OpenSSL 的所有用途。

如何使用本指南

  • 如果你不熟悉证书签署请求(CSR),请阅读第一部分。
  • 除了第一部分,本指南采用了简单的小抄格式:自带了命令行代码片段。
  • 跳到与你准备完成的任务相关的任何部分。
  • 大多数命令都是单行的,为了清晰起见,已经扩展到多行(使用 \ 符号)。

关于证书签署请求(CSR)

如果你想从 证书颁发机构 certificate authority (CA)那里获得 SSL 证书,你必须生成一个 证书签署请求 certificate signing request (CSR)。一个 CSR 主要是由一个密钥对的公钥和一些附加信息组成。当证书被签署时,这两部分都会被插入到证书中。

每当你生成一个 CSR 时,你会被提示提供有关证书的信息。这些信息被称为 区分名称 Distinguised Name (DN)。DN 中的一个重要字段是 通用名称 Common Name (CN),它应该是你打算使用证书的主机的 完全合格域名 Fully Qualified Domain Name (FQDN)。当创建 CSR 时,也可以通过命令行或文件传递信息来跳过交互式提示。

DN 中的其他项目提供了有关你的业务或组织的附加信息。如果你是从证书机构购买 SSL 证书,通常要求这些附加字段(如“ 组织 Organization ”)准确地反映你的组织的详细信息。

下面是一个 CSR 信息提示的例子:

---
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:New York
Locality Name (eg, city) []:Brooklyn
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Example Brooklyn Company
Organizational Unit Name (eg, section) []:Technology Division
Common Name (e.g. server FQDN or YOUR name) []:examplebrooklyn.com
Email Address []:

如果你想非交互式地回答 CSR 信息提示,你可以通过在任何请求 CSR 信息的 OpenSSL 命令中添加 -subj 选项来实现。这里是该选项的一个例子,使用上面代码块中显示的相同信息:

-subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=examplebrooklyn.com"

现在你已经了解了 CSR,可以自由跳转到本指南中涵盖你的 OpenSSL 需求的任何一节。

生成 CSR

本节介绍了与生成 CSR(以及私钥,如果它们还不存在的话)有关的 OpenSSL 命令。CSR 可以用来向证书颁发机构请求 SSL 证书。

请记住,你可以通过上一节中提到的 -subj 选项非交互式地添加 CSR 信息。

生成一个私钥和一个 CSR

如果你想使用 HTTPS(HTTP over TLS)来保护你的 Apache HTTP 或 Nginx Web 服务器的安全,并且你想使用一个证书颁发机构(CA)来颁发 SSL 证书,那么就使用这个方法。生成的 CSR 可以发送给 CA,请求签发由 CA 签名的 SSL 证书。如果你的 CA 支持 SHA-2,请添加 -sha256 选项,用 SHA-2 签署 CSR。

这条命令从头开始创建一个 2048 位的私钥(domain.key)和一个 CSR(domain.csr):

openssl req \
       -newkey rsa:2048 -nodes -keyout domain.key \
       -out domain.csr

回答 CSR 信息提问,完成该过程。

选项 -newkey rsa:2048 指定密钥应该是 2048 位,使用 RSA 算法生成。选项 -nodes 指定私钥没有用密码加密。这里没有包含 -new 选项,而是隐含在其中,表示正在生成一个 CSR。

从现有的私钥中生成一个 CSR

如果你已经有了私钥,并想用它向 CA 申请证书,请使用这个方法。

该命令基于现有的私钥(domain.key)创建一个新的 CSR(domain.csr):

openssl req \
       -key domain.key \
       -new -out domain.csr

回答 CSR 信息提问,完成该过程。

选项 -key 指定一个现有的私钥(domain.key),它将被用来生成一个新的 CSR。选项 -new 表示正在生成一个 CSR。

从现有的证书和私钥生成 CSR

如果你想更新现有的证书,但由于某些原因,你或你的 CA 没有原始的 CSR,请使用这个方法。基本上可以省去重新输入 CSR 信息的麻烦,因为它是从现有证书中提取信息的。

该命令基于现有的证书(domain.crt)和私钥(domain.key)创建一个新的 CSR(domain.csr):

openssl x509 \
       -in domain.crt \
       -signkey domain.key \
       -x509toreq -out domain.csr

选项 -x509toreq 指定你使用一个 X509 证书来制作 CSR。

生成 SSL 证书

如果你想使用 SSL 证书来确保服务的安全,但你不需要 CA 签名的证书,一个有效的(和免费的)解决方案是签署你自己的证书。

你可以自己签发的一种常见证书是 自签证书 self-signed certificate 。自签证书是用自己的私钥签署的证书。自签证书和 CA 签名证书一样可以用来加密数据,但是你的用户会显示一个警告,说这个证书不被他们的计算机或浏览器信任。因此,只有当你不需要向用户证明你的服务身份时,才可以使用自签名证书(例如非生产或非公开服务器)。

本节介绍与生成自签名证书相关的 OpenSSL 命令。

生成自签证书

如果你想使用 HTTPS(HTTP over TLS)来保护你的 Apache HTTP 或 Nginx Web 服务器,并且你不需要你的证书由 CA 签名,那么就使用这个方法。

这个命令可以从头开始创建一个 2048 位的私钥(domain.key)和一个自签证书(domain.crt):

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

回答 CSR 信息提问,完成该过程。

选项 -x509 告诉 req 子命令创建一个自签名的证书。-days 365 选项指定证书的有效期为 365 天。它会生成一个临时的 CSR,以收集与证书相关的信息。

从现有私钥生成自签名证书

如果你已经有了一个私钥,并且你想用它来生成一个自签证书,请使用这个方法。

这条命令可以从现有的私钥(domain.key)中创建一个自签证书(domain.crt):

openssl req \
       -key domain.key \
       -new \
       -x509 -days 365 -out domain.crt

回答 CSR 信息提问,完成该过程。

选项 -x509 告诉 req 子命令创建一个自签证书。-days 365 选项指定证书的有效期为 365 天。选项 -new 启用 CSR 信息提问。

从现有的私钥和 CSR 生成自签证书

如果你已经有了私钥和 CSR,并且你想用它们生成一个自签证书,请使用这个方法。

这条命令将从现有的私钥(domain.key)和(domain.csr)中创建一个自签证书(domain.crt)。

openssl x509 \
       -signkey domain.key \
       -in domain.csr \
       -req -days 365 -out domain.crt

选项 -days 365 指定证书的有效期为 365 天。

查看证书

证书和 CSR 文件是以 PEM 格式编码的,不适合被人读取。

本节介绍的 OpenSSL 命令将输出 PEM 编码文件的实际条目。

查看 CSR 条目

该命令允许你查看和验证纯文本的 CSR(domain.csr)的内容:

openssl req \  
       -text -noout -verify \  
       -in domain.csr

查看证书条目

该命令允许你查看纯文本证书(domain.crt)的内容:

openssl x509 \  
       -text -noout \  
       -in domain.crt

验证证书由 CA 签署

使用此命令验证证书(domain.crt)是否由特定的 CA 证书(ca.crt)签署:

openssl verify \  
       -verbose -CAFile ca.crt \  
       domain.crt

私钥

本节介绍了用于创建和验证私钥的 OpenSSL 命令。

创建私钥

使用该命令创建一个受密码保护的 2048 位私钥(domain.key):

openssl genrsa \  
       -des3 -out domain.key 2048

在提示时输入密码以完成该过程。

验证私钥

使用此命令检查私钥(domain.key)是否为有效密钥:

openssl rsa \  
       -check -in domain.key

如果你的私钥已经加密,系统会提示你输入它的密码,成功后,未加密的密钥会在终端上输出。

验证私钥是否与证书和 CSR 匹配

使用这些命令来验证私钥(domain.key)是否匹配证书(domain.crt)和 CSR(domain.csr):

openssl rsa  -noout -modulus -in domain.key | openssl md5
openssl x509 -noout -modulus -in domain.crt | openssl md5
openssl req  -noout -modulus -in domain.csr | openssl md5

如果每条命令的输出都是相同的,那么私钥、证书和 CSR 就极有可能是相关的。

加密私钥

这需要一个未加密的私钥(unencrypted.key),并输出它的加密版本(encrypted.key):

openssl rsa -des3 \
       -in unencrypted.key \
       -out encrypted.key

输入你所需的密码,以加密私钥。

解密私钥

这需要一个加密的私钥(encrypted.key),并输出一个解密的版本(decrypted.key):

openssl rsa \
       -in encrypted.key \
       -out decrypted.key

在提示时,输入加密密钥的密码。

转换证书格式

我们一直在使用的所有证书都是 ASCII 码 PEM 编码的 X.509 证书。还有很多其他的证书编码和容器类型;一些应用程序喜欢某些格式而不是其他格式。此外,这些格式中的许多格式可以在一个文件中包含多个项目,如私钥、证书和 CA 证书。

OpenSSL 可以用来将证书在则西格式间转换。本节将介绍一些可能的转换。

将 PEM 转换为 DER

如果要将 PEM 编码的证书(domain.crt)转换为 DER 编码的证书(domain.der),即二进制格式,请使用此命令:

openssl x509 \
       -in domain.crt \
       -outform der -out domain.der

DER 格式通常与 Java 一起使用。

将 DER 转换为 PEM

如果要将 DER 编码的证书(domain.der)转换为 PEM 编码的证书(domain.crt),请使用此命令:

openssl x509 \
       -inform der -in domain.der \
       -out domain.crt

将 PEM 转换为 PKCS7

如果你想把 PEM 证书(domain.crtca-chain.crt)添加到 PKCS7 文件(domain.p7b)中,请使用该命令:

openssl crl2pkcs7 -nocrl \
       -certfile domain.crt \
       -certfile ca-chain.crt \
       -out domain.p7b

请注意,你可以使用一个或多个 -certfile 选项来指定要添加到 PKCS7 文件中的证书。

PKCS7 文件,也被称为 P7B,通常用于 Java Keystores 和 Microsoft IIS(Windows)。它们是 ASCII 文件,可以包含证书和 CA 证书。

将 PKCS7 转换为 PEM

如果你想将 PKCS7 文件(domain.p7b)转换为 PEM 文件,请使用该命令:

openssl pkcs7 \
       -in domain.p7b \
       -print_certs -out domain.crt

请注意,如果你的 PKCS7 文件中有多个项目(如证书和 CA 中间证书),创建的 PEM 文件将包含其中的所有项目。

将 PEM 转换为 PKCS12

如果你想使用私钥(domain.key)和证书(domain.crt),并将它们组合成一个 PKCS12 文件(domain.pfx),请使用这个命令:

openssl pkcs12 \
       -inkey domain.key \
       -in domain.crt \
       -export -out domain.pfx

系统会提示你输入导出密码,你可以留空。请注意,在这种情况下,你可以通过将多个证书连接到一个 PEM 文件(domain.crt)中来添加一个证书链到 PKCS12 文件中。

PKCS12 文件,也被称为 PFX 文件,通常用于在 Micrsoft IIS(Windows)中导入和导出证书链。

将 PKCS12 转换为 PEM

如果你想转换 PKCS12 文件(domain.pfx)并将其转换为 PEM 格式(domain.combined.crt),请使用此命令:

openssl pkcs12 \
       -in domain.pfx \
       -nodes -out domain.combined.crt

请注意,如果你的 PKCS12 文件中有多个项目(如证书和私钥),创建的 PEM 文件将包含其中的所有项目。

OpenSSL 版本

openssl version 命令可以用来检查你正在运行的版本。你正在运行的 OpenSSL 版本,以及编译时使用的选项会影响到你可以使用的功能(有时也会影响到命令行选项)。

下面的命令显示了你正在运行的 OpenSSL 版本,以及它被编译时的所有选项:

openssl version -a

本指南是使用具有如下细节的 OpenSSL 二进制文件编写的(参见前面命令的输出):

OpenSSL 1.0.1f 6 Jan 2014
built on: Mon Apr  7 21:22:23 UTC 2014
platform: debian-amd64
options:  bn(64,64) rc4(16x,int) des(idx,cisc,16,int) blowfish(idx)
compiler: cc -fPIC -DOPENSSL_PIC -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -m64 -DL_ENDIAN -DTERMIO -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2 -Wl,-Bsymbolic-functions -Wl,-z,relro -Wa,--noexecstack -Wall -DMD32_REG_T=int -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/usr/lib/ssl"

总结

这应该涵盖了大多数人如何使用 OpenSSL 来处理 SSL 证书的情况!它还有很多其他的用途,在这里没有介绍,所以请在评论中随时询问或建议其他用途。

如果你在使用这些命令时遇到了问题,请一定要评论(并附上你的 OpenSSL 版本输出)。


via: https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs

作者:Mitchell Anicas 选题:wxy 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出