OpenSSL之创建根证书

前言

最近想研究一下关于OpenSSL的相关知识,顺便想创建自己的一个根CA方便后续进行个人项目的各种证书签发工作。因此打算编写一份关于OpenSSL的专题,记录一下它的相关使用方法,为后续使用做准备。

所有操作均未考虑权限管理,如需引入权限管理,请移步^重点教程

什么是OpenSSL?

计算机网络上,OpenSSL是一个开放源代码软件函数库包,应用程序可以使用这个包来进行安全通信,避免窃听,同时确认另一端连线者的身份。这个包广泛被应用在互联网的网页服务器上。

OpenSSL

版本说明

  • OpenSSL版本为3.0.13

专题跳转

创建属于自己的根证书(快捷指令版)

这里记录着所有所需要的命令,如果想无脑用,则可以直接CV进行使用,如果想要了解更多有关的知识信息,那么请跳过该章节,跳转到创建属于自己的根证书(一步步操作版)

以下操作默认证书存放为当前地址。

创建root.sh文件,并在里面输入如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/bin/bash
# 创建根证书所需要的全部文件信息
# 创建签发证书位置
if [ ! -d RootCA/crt ]; then
mkdir -p RootCA/crt
fi
# 创建根证书数据文件点
if [ ! -d RootCA/db ]; then
mkdir -p RootCA/db
touch RootCA/db/index
openssl rand -hex 16 > RootCA/db/serial
fi
# 创建密钥存放点
if [ ! -d RootCA/key ]; then
mkdir -p RootCA/key
fi
# 【总】创建过期证书生成点
if [ ! -d ./crl ]; then
mkdir -p ./crl
fi
# 创建根证书新证书记录存放点
if [ ! -d RootCA/newcerts ]; then
mkdir -p RootCA/newcerts
fi
# 【总】创建根证书、中间证书存放密钥点
if [ ! -d ./KEY ]; then
mkdir -p ./KEY
fi
# 【总】创建根证书、中间证书配置点
if [ ! -d ./conf ]; then
mkdir -p ./conf
fi

运行命令:./root.sh

创建根证书配置文件touch ./conf/RootCA.cnf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#
# OpenSSL example configuration file.
# See doc/man5/config.pod for more info.
#
# 整个项目的根目录,默认为当下
HOME = .

####################################################################
[ ca ]
default_ca = CA_default # The default ca section

####################################################################
[ CA_default ]
dir = ./RootCA
database = $dir/db/index.txt # 数据文件存放点(必要)
new_certs_dir = $dir/newcerts # 存放新证书 (必要)
private_key = ./KEY/RootCA.key # 私钥地址 (必要)
serial = $dir/db/serial # 当前序列号(必要)
certificate = $dir/crt/RootCA.crt # 根证书签发文件位置
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
crl_extensions = crl_ext # 添加撤销证书功能


default_days = 365 # 默认天数
default_crl_days= 30 # 默认30天获取撤销证书信息
default_md = sha256 # 公钥默认加密方式
preserve = no # keep passed DN ordering


policy = policy_match

# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

####################################################################
[ req ]
default_bits = 2048
prompt = no
distinguished_name = req_distinguished_name
x509_extensions = v3_ca # The extensions to add to the self signed cert
string_mask = pkix

[ req_distinguished_name ]
C = CN
ST = TianJin
L = TJ
O = ROOT
OU = Root CA
CN = Root CA
emailAddress = ZHYCarge@zhycarge.top


[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:true
keyUsage = critical, keyCertSign, cRLSign, digitalSignature
crlDistributionPoints = URI:http://ca.zhycarge.top/crl/crl-Root.crl

[ v3_Web_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign, keyEncipherment
extendedKeyUsage = serverAuth
authorityInfoAccess=caIssuers;URI:http://ca.zhycarge.top/crt/ZHYCargeRootCA.crt
crlDistributionPoints = URI:http://ca.zhycarge.top/crl/crl-Root.crl

[ crl_ext ]
authorityKeyIdentifier=keyid:always

生成根证书私钥:

openssl genrsa -aes256 -out KEY/RootCA.key 4096

生成根证书签名请求:

openssl req -new -config ./conf/RootCA.cnf -sha256 -key /KEY/RootCA.key -out ./RootCA/csr/RootCA.csr

签发证书:

openssl ca -selfsign -config ./conf/RootCA.cnf -in ./RootCA/csr/RootCA.csr -extensions v3_ca -days 365 -out ./RootCA/crt/RootCA.crt

至此证书无脑化生成完毕。

创建属于自己的根证书(一步步操作版)

此处记录着详细的生成操作,供了解学习。

生成目录文件

参考上文root.sh文件的创建方式以及生成目录文件,这里不再进行赘述 创建属于自己的根证书(快捷指令版)

配置文件详解

conf文件夹中创建RootCA.cnf文件,并依次添加如下代码框中的内容:

CA头

没什么可以讲解的,默认配置

1
2
3
4
5
6
7
8
9
10
#
# OpenSSL example configuration file.
# See doc/man5/config.pod for more info.
#
# 整个项目的根目录,默认为当下
HOME = .
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
####################################################################

证书配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[ CA_default ]
dir = ./RootCA # 与证书配套的配置文件夹
database = $dir/db/index.txt # 证书签发记录数据库
new_certs_dir = $dir/newcerts # 存放生成证书签名信息
private_key = ./KEY/RootCA.key # 当前证书私钥地址
serial = $dir/db/serial # 生成随机数,根据随机数进行索引记录
certificate = $dir/crt/RootCA.crt # 当前证书签发文件位置
name_opt = ca_default # 默认
cert_opt = ca_default # 默认
crl_extensions = crl_ext # 添加撤销证书功能,与后续功能块联动
default_days = 365 # 默认证书天数
default_crl_days= 30 # 默认更新撤销证书实践
default_md = sha256 # 私钥默认加密方式
preserve = no # 不知道,暂存
policy = policy_match # 证书创建规则匹配,与后续功能块联动

证书规则匹配

1
2
3
4
5
6
7
8
9
# For the CA policy
# 前三个match 要求签发证书与当前CA一致,optional为可选项,supplied会在创建时进行输入
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

证书生成参数

1
2
3
4
5
6
[ req ]
default_bits = 2048 # 证书加密位数
prompt = no # 不需要显示提示信息,直接按照参数信息进行键入CN信息等
distinguished_name = req_distinguished_name # 参数信息,后面功能块联动
x509_extensions = v3_ca # The extensions to add to the self signed cert # 签发证书参数,后面功能块联动
string_mask = pkix # 如果是utf8only,则键入英文可能会出现证书规则匹配错误,具体查看后面疑难杂症章节

证书参数信息

1
2
3
4
5
6
7
8
[ req_distinguished_name ]
C = CN # 国家代码,默认2位
ST = TianJin # 所在州省
L = TJ # 所在市
O = ZHYCarge # 组织名称
OU = ZHYCarge Root CA # 组织唯一名称
CN = ZHYCarge Root CA # 通用名称,要求唯一
emailAddress = ZHYCarge@zhycarge.top # 邮箱地址

根证书签发参数

1
2
3
4
5
6
[ v3_ca ]
subjectKeyIdentifier=hash # 加密方式
authorityKeyIdentifier=keyid:always,issuer # 参数存储
basicConstraints = critical,CA:true # 是CA签发机构,能继续签发证书,若FALSE则为终端证书,不允许签发
keyUsage = critical, keyCertSign, cRLSign, digitalSignature # 证书用途,后续章节疑难解答详细说明
crlDistributionPoints = URI:http://ca.zhycarge.top/crl/crl-Root.crl # 证书吊销地址,后续疑难解答有详细说明

中间证书配置文件

1
2
3
4
5
6
7
8
[ v3_Web_ca ] # 名称随意,后续创建中间证书会用上
subjectKeyIdentifier = hash # 与根证书同
authorityKeyIdentifier = keyid:always,issuer # 与根证书同
basicConstraints = critical, CA:true, pathlen:0 # pathlen代表签发证书无限制,默认就是0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign, keyEncipherment # 与根证书同
extendedKeyUsage = serverAuth # 额外证书用途,后续有详细讲解
authorityInfoAccess=caIssuers;URI:http://ca.zhycarge.top/crt/ZHYCargeRootCA.crt # 指向根证书地址,后续详细讲解
crlDistributionPoints = URI:http://ca.zhycarge.top/crl/crl-Root.crl # 与根证书同

证书吊销列表参数

1
2
[ crl_ext ]
authorityKeyIdentifier=keyid:always # 与根证书同

keyUsage讲解

扩展用于指明证书的基本用途。可以包含多个值,常见的选项有:

  • digitalSignature 用于数字签名(如 SSL/TLS 握手、代码签名等)
  • nonRepudiation用于非否认性(证明某个操作已被执行)
  • keyEncipherment用于密钥加密(例如,保护会话密钥)
  • dataEncipherment用于数据加密(加密实际数据)
  • keyAgreement用于密钥协商(如 Diffie-Hellman)
  • keyCertSign用于签署其他证书(CA 证书)
  • cRLSign用于签署证书撤销列表(CRL)
  • encipherOnly用于仅加密操作
  • decipherOnly用于仅解密操作

extendedKeyUsage讲解

扩展用于指明证书的扩展用途,可以包含多个值,常见的选项有:

  • serverAuth用于服务器身份验证
  • clientAuth用于客户端身份验证
  • codeSigning用于代码签名
  • emailProtection用于电子邮件保护(S/MIME)
  • timeStamping用于时间戳服务
  • OCSPSigning用于在线证书状态协议(OCSP)签名
  • ipsecEndSystem用于 IPsec 终端
  • ipsecTunnel用于 IPsec 隧道
  • ipsecUser用于 IPsec 用户
  • anyExtendedKeyUsage表示可以用于任何扩展用途

authorityInfoAccess讲解

authorityInfoAccess(AIA) 是 X.509 证书中的一个扩展,用于提供证书颁发机构(CA)信息的访问方法。这一扩展可以帮助用户或应用程序获取有关证书的更多信息,例如证书的撤销状态或颁发者的证书。

通常配置文件:

1
2
3
authorityInfoAccess = critical
CAIssuers;URI:http://ca.example.com/ca.crt,
OCSP;URI:http://ocsp.example.com
  • critical :表示该扩展是关键的,如果接收方不支持这一扩展,可能会拒绝该证书。
  • CAIssuers:指向 CA 证书的 URL,客户端可以通过该 URL 获取 CA 的证书。
  • OCSP:指向在线证书状态协议(OCSP)的 URL,客户端可以通过该 URL 查询证书的实时状态。

这里由于OCSP需要搭建服务器等进行匹配,由于证书信息都在本地进行生成,因此不考虑,仅提供CAIssuers,通过配置crlDistributionPoints提供CRL文件进行证书的撤销状态提示。

创建根证书私钥

参考文章^openssl-genrsa

通过使用命令创建根证书私钥

openssl genrsa -aes256 -out ./KEY/RootCA.key 4096

其中参数说明:

  • -out:生成根证书私钥的名称及存储位置
  • -aes256:生成证书的加密方式
  • 4096:证书私钥的大小,默认值为2048

生成根证书的签名请求

参考文章^openssl-req,使用命令创建签名请求。

openssl req -new -config ./conf/RootCA.cnf -sha256 -key ./KEY/RootCA.key -out ./RootCA/csr/RootCA.csr

签发CA证书

输入下列命令后通过输入密钥密码还有两个y之后便可生成根证书密钥。

openssl ca -selfsign -config ./conf/RootCA.cnf -in ./RootCA/csr/RootCA.csr -extensions v3_ca -days 365 -out ./RootCA/crt/RootCA.crt

至此,根证书创建完成,可以根据自身需要将根证书导入到指定环境或者进行分发,或者等待中间证书创建好后编写证书链进行分发。

其余操作介绍

查看签发证书情况

通过使用如下命令查看签发证书情况,能够看到大致的证书信息。

openssl req -text -noout -in ./RootCA/csr/RootCA.csr

添加crl信息

以下内容在发稿前实验撤销证书暂无效果,撤销证书效果存疑,后续实验有新进展后会更新博文

使用前提:要确保在证书中已经添加好CRL链接文件

撤销证书

通过命令撤销1.crt证书

openssl ca -revoke 1.crt -config ./conf/RootCA.cnf

更新crl文件

openssl ca -gencrl -out ./crl/ca-Root.crl -config ./conf/RootCA.cnf

尾言

疑难杂症

The mandatory stateOrProvinceName field was missing

报错内容:

1
2
3
Check that the request matches the signature
Signature ok
The mandatory stateOrProvinceName field was missing

根据^报错1可知,配置文件中[policy_match]

1
2
3
4
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match

有三个选项应该一致,但是并未保持一致,所以报错。

修改方式是要么将 match改成 optional,要么参考^报错2string_maskutf8only更改为pkix

无法创建有效的证书链

添加authorityInfoAccess指向上级证书的信息时不能加HTTPS,要用HTTP进行引用,否则无法找到

存在疑问信息

手机端无法签发该证书,不知道哪一步存在问题,证书签发仅在电脑端能够实现

张贴自己的根证书

根证书下载地址:ZHYCargeRootCA

在后续的不定期更新中,可能会存在需要使用数字证书进行相关工作,为保证访问及不会出报错,因此张贴个人的根证书信息,若有需要可以下载安装:安装需要安装在受信任的根证书中。

为保证证书有效性,可通过发送主题包含根证书指纹验证邮件到ZHYCarge@zhycarge.top中,你会得到根证书的sha1sha256指纹信息,与你下载的证书进行匹配,若一致便可确认。

为保障个人证书安全性,该证书仅1年有效,后续证书更换也会在当前博文及关于里进行更新。

更新说明

2024-12-20 13:41:34

重新更换文章、刊错

参考链接