可以直接使用我制作好的工具,支持自签名 HTTPS 证书和双向认证证书,纯 shell 脚本,支持 Docker 使用,一键生成证书:https://github.com/iuxt/my_cert

双向认证用途是什么: 双向认证就是客户端需要携带证书来请求服务器,证书校验通过了才会正常返回。比如说我有个网站只有自己访问,就可以配置双向认证,自己电脑安装一下证书就可以访问,还可以通过吊销证书的方式来禁止对应的人访问网站。

CA 证书

生成 CA 私钥

1
openssl genrsa -out ca.key 4096

生成一个 ca.key 文件

生成 CA 证书

1
openssl req -utf8 -new -x509 -days 3650 -key ca.key -out ca.crt -subj '/C=CN/ST=Shanghai/L=Pudong/O=iuxt/OU=张理坤/CN=www.i.com/emailAddress=iuxt@qq.com'
1
openssl req -utf8 -new -x509 -days 3650 -key ca.key -out ca.crt

需要交互式输入:

提示 含义 输入内容
Country Name 国家 CN
State or Province Name Shanghai
Locality Name 留空
Organization Name 组织名,公司名 iuxt
Organizational Unit Name 团体名 留空
Common Name 你的名字或域名 zhanglikun
Email Address 电子邮箱 iuxt@qq.com

就可以生成 ca.crt 文件, 这个文件需要加入到客户端的 受信任的根证书颁发机构

制作双向认证客户端证书

我是在 Ubuntu 24.04 系统下操作。不同系统可能会有差别。

生成证书吊销列表

准备一份 openssl.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
[ ca ]
default_ca = CA_default

[ CA_default ]
# 根目录设置为自定义路径
dir = ./ca

# 默认算法
default_md = sha256

# CA 的数据库文件
database = $dir/index.txt
# 证书的序列号文件
serial = $dir/serial
# 新证书的默认有效期
default_days = 365
# 吊销证书的理由
crl_reason = unspecified
# 默认的证书颁发策略
policy = policy_anything

# CRL 选项
crlnumber = $dir/crlnumber
default_crl_days = 30
crl_extensions = crl_ext

[ policy_anything ]
# 配置任何策略
countryName = optional
stateOrProvinceName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[ crl_ext ]
# CRL 的扩展配置
authorityKeyIdentifier = keyid:always

吊销指定证书

其他的证书都是 ca 签发的, 不管是 nginx 用的 server 证书,还是双向认证用到的 client 证书, 吊销证书后需要重新生成 crl 文件

1
2
3
4
5
6
7
8
9
10
touch ca/index.txt

# crlnumber初始化,第一次给个初始值即可,后面不需要修改,每次重新生成crl的时候会自增。
[ ! -f ca/crlnumber ] && echo "01" > ca/crlnumber

# 吊销指定证书
openssl ca -config openssl.cnf -cert ca/ca.crt -keyfile ca/ca.key -revoke ssl/i.com.crt

# 吊销完成后,重新生成吊销列表,建议定期重新生成 CRL 文件,并在 Nginx 上 reload 配置
openssl ca -config openssl.cnf -cert ca/ca.crt -keyfile ca/ca.key -gencrl -out ca/crl.pem

服务端 nginx 配置

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
server {
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate ssl/i.com.crt;
ssl_certificate_key ssl/i.com.key;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
server_name i.com;

ssl_client_certificate ssl/ca.crt; # 配置 CA 证书,用于验证客户端证书的签发者
ssl_verify_client on; # 启用客户端证书验证
ssl_crl ssl/crl.pem; # 配置 CRL 文件路径,用于检查吊销的证书

client_max_body_size 1024m;

location / {
default_type text/plain;
return 200 "hello";
}
}

配置客户端 client 证书

证书生成方式和上面一样,p12 格式包含私钥和证书(iPhone 想导入的话,必须设置密码。)

1
openssl pkcs12 -export -in zhangsan.crt -inkey zhangsan.key -out zhangsan.p12

Windows 系统

双击导入,存储位置选择个人
image.png

访问对应网站的时候浏览器会提示让选择证书
image.png|593

这是证书被吊销的样子:
image.png|593

iPhone 手机

先在文件里点击一下 p12 文件
IMG_5978-1.png|283

然后到 VPN 与设备管理里
IMG_5979-1.png|302

选择已下载的描述文件,进行安装。

其他

Windows 删除个人证书

win + r 运行,输入 certmgr.msc 进入证书管理器。或者在开始菜单搜索 管理用户证书 进入。找到证书,右键删除即可。

iPhone 删除证书

删除描述文件即可。