在上一篇文章《实践:如何通过OpenSSL来创建自签名的CA证书》中我们介绍了如何使用OpenSSL创建的CA私钥和CA证书。在本文中,我们将使用并使用上一篇文章中生成的CA根证书进行签署客户端证书以及服务器证书。
1. 主要流程
本文实践的前提是先完成CA私钥和CA根证书的生成,具体步骤可以参阅《实践:如何通过OpenSSL来创建自签名的CA证书》。
使用OpenSSL签署客户端与服务器证书所需遵循的步骤如下图所示:
2. 创建客户端证书
2.1. 创建客户端私钥
要创建客户端证书,我们要先用openssl命令创建客户端私钥。在这个例子中,我们创建了2048位大小的客户端密钥 client.key。
openssl genrsa -out client.key
2.2. 使用客户端密钥生成证书签名请求(CSR)
使用如下openssl req
命令生成证书签名请求(CSR)
openssl req -new -key client.key -out client.csr
执行以上命令时会提示让你输入证书相关的主题信息,全部填写完成后会生成文件client.csr。
可以用下列命令来查看 CSR 信息,确保它已经有了对应的公钥和主体信息。
openssl req -in client.csr -noout -text
2.3. 为客户端证书配置X509扩展
数字证书遵循X.509标准,该标准定义了证书的基本结构和一些可选的扩展字段。通过使用这些扩展字段,证书可以包含更详细的信息,以支持更多的功能和应用需求。所以明确定义好用于创建客户端证书的x509扩展非常重要。
接下来我们为客户端证书配置的x509扩展字段如下:
# cat /home/fss/cert/conf/client_cert_ext.cnf
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
扩展项说明:
- basicConstraints:这个扩展字段用于指示一个实体是否是一个证书颁发机构(CA),以及它是否能够签发下级证书。这对于构建证书链非常重要。最终用户证书必须将CA设置为FALSE或完全排除扩展。
- nsCertType:这个字段表示Netscape证书类型,由要包含的标志列表组成。比如我们上面的client,email,当然还可以是server。生成服务器证书时我们就会用到server标志。
- nsComment:Netscape Comment(nsComment)是一个字符串扩展名,其中包含将显示的注释在某些浏览器中查看证书时。
- subjectKeyIdentifier:主体密钥标识符,为证书中的公钥提供唯一标识符,有助于在证书链中快速定位和验证证书。一般为公钥的Hash值。
- authorityKeyIdentifier:授权密钥标识符,用于识别证书颁发机构的公钥,通常是在证书链中用来匹配上一级证书的公钥。该字段只允许两个选项。keyid和issuer。
- keyUsage:指明证书中公钥的预期用途,例如签名、加密、密钥编码等。这有助于防止证书被滥用。。
- extendedKeyUsage:指示证书公钥可用于的目的,比如服务器认证、客户端认证等。
若想了解更多关于x.509证书的细节,可以参阅博主前期文章《轻松掌握X.509数字证书全解析,附赠权威详解资料!一读通透,安全之旅从此启程!》。
2.4. 创建客户端证书
接下来,使用openssl x509
命令颁发我们的客户端证书,并使用我们在上一篇文章中创建的CA密钥(ca_private.key)和CA根证书(ca_certificate.crt)对其进行签名。
# openssl x509 -req -in client.csr -CA ca_certificate.crt -CAkey ca_private.key -out client.cert -CAcreateserial -days 365 -sha256 -extfile /home/fss/cert/conf/client_cert_ext.conf
Note:此客户端证书的有效期为365天,通过参数
-sha256
指定生成证书签名时使用的哈希算法为SHA256。
以上命令执行成功后将会创建客户端证书client.cert。
至此,我们完成了客户端证书的创建。此阶段总共产生了3个文件:
- client.key:客户端私钥,可以通过命令
openssl rsa -noout -text -in client.key
查看其详情; - client.csr:客户端csr,可以通过命令
openssl req -noout -text -in client.csr
查看其详情; - client.cert:客户证书,可以通过命令
openssl x509 -noout -text -in client.cert
查看其详情;
3. OpenSSL创建服务器证书
接下来,我们将使用openssl创建服务器证书。步骤与创建客户端证书步骤类似。
3.1. 创建服务器私钥
openssl genrsa -out server.key 2048
3.2. 使用服务器密钥创建证书签名请求(CSR)
基于服务器密钥server.key,使用如下命令生成证书签名请求server.csr。
openssl req -new -key server.key -out server.csr
注意,使用Common Name指定的服务器节点的主机名或IP地址值非常重要,如果主机名与服务器证书的CN不匹配,服务器与客户端在TLS握手时将失败。在本文,我们的服务器主机名是kali。
3.3. 为服务器证书配置x509扩展
定义用于创建服务器证书的openssl x509
扩展同样重要。这些扩展值将用来区分服务器和客户端证书。
# cat /home/fss/cert/conf/server_cert_ext.conf
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
注意:此处nsCertType取值为server,extendedKeyUsage为serverAuth。
3.4. 创建服务器证书
与创建客户端证书命令类似,具体如下:
# openssl x509 -req -in server.csr -CA ca_certificate.crt -CAkey ca_private.key -out server.cert -CAcreateserial -days 365 -sha256 -extfile /home/fss/cert/conf/server_cert_ext.conf
命令执行成功后,将创建出服务器证书server.cert。此阶段,同样生成3个文件:
- server.key:服务器私钥,可以通过命令
openssl rsa -noout -text -in server.key
查看其详情; - server.csr:服务器csr,可以通过命令
openssl req -noout -text -in server.csr
查看其详情; - server.cert:服务器证书,可以通过命令
openssl x509 -noout -text -in server.cert
查看其详情;
至此,我们完成了客户端证书、服务器证书的生成,累计生成6个文件。
4. 写在最后
下一篇文章中,我们会搭建Apache服务器并配置SSL来实现客户端与服务端的加密通信,并通过客户端与服务端的TLS握手过程来详细介绍证书链校验的工作原理。