在很多使用到证书的场景, 比如 HTTPS, 可以选择去申请一个免费的证书, 也可以尝试自签名证书, 申请免费证书请看:使用certbot自动申请ssl证书 或者 使用acme.sh来自动更新https证书, 本文介绍自签名证书.

SSL 协议加密方式

SSL 协议即用到了对称加密也用到了非对称加密 (公钥加密),在建立传输链路时,SSL 首先对对称加密的密钥使用公钥进行非对称加密,链路建立好之后,SSL 对传输内容使用对称加密。

  • 对称加密
    速度高,可加密内容较大,用来加密会话过程中的消息。

  • 公钥加密
    加密速度较慢,但能提供更好的身份认证技术,用来加密对称加密的密钥。

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

需要交互式输入:

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

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

  • 可选: 将 CA 证书转换成 p12 文件

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

Server 证书

生成 server 端的私钥

1
openssl genrsa -out server.key 4096

生成 server 端数字证书请求

1
openssl req -utf8 -new -key server.key -out server.csr

需要交互式输入:

提示 含义 输入内容
Country Name 国家 CN
State or Province Name Shanghai
Locality Name 留空
Organization Name 组织名,公司名 iuxt
Organizational Unit Name 团体名 留空
Common Name 你的名字或域名 这里必须写域名或者 ip
Email Address 电子邮箱 iuxt@qq.com
1
openssl req -utf8 -new -key server.key -out server.csr -subj '/C=CN/ST=Shanghai/L=Pudong/O=iuxt/OU=张理坤/CN=*.i.com/emailAddress=iuxt@qq.com'

用 CA 私钥签发 server 的数字证书

解决 chrome 不受信任的问题

vim server.ext

1
2
3
4
5
6
7
8
9
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName=@SubjectAlternativeName

[ SubjectAlternativeName ]
DNS.1=i.com
DNS.2=*.i.com
IP.1=192.168.1.1
IP.2=192.168.1.2

在里面填写证书绑定的 IP 和域名, 支持通配符

1
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile server.ext

生成 server.crt 证书文件

吊销证书

生成证书吊销列表

具体用什么目录需要查看 openssl 的配置文件中 dir 项
ubuntu 的配置文件在 /usr/lib/ssl/openssl.cnf

1
2
3
4
5
6
7
mkdir -p ./demoCA/{private,newcerts}
touch ./demoCA/index.txt
[ ! -f ./demoCA/seria ] && echo 01 > ./demoCA/serial
[ ! -f ./demoCA/crlnumber ] && echo 01 > ./demoCA/crlnumber
cp -f ca.key ./demoCA/private/cakey.pem
cp -f ca.crt ./demoCA/cacert.pem
openssl ca -gencrl -out ca.crl

具体用什么目录需要查看 openssl 的配置文件中 dir 项
centos 的配置文件在 /etc/pki/tls/openssl.cnf

1
2
3
4
5
6
7
mkdir -p /etc/pki/CA/{private,newcerts}
touch /etc/pki/CA/index.txt
[ ! -f /etc/pki/CA/seria ] && echo 01 > /etc/pki/CA/serial
[ ! -f /etc/pki/CA/crlnumber ] && echo 01 > /etc/pki/CA/crlnumber
cp -f ca.key /etc/pki/CA/private/cakey.pem
cp -f ca.crt /etc/pki/CA/cacert.pem
openssl ca -gencrl -out ca.crl

吊销指定证书

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

1
2
openssl ca -revoke client.crt
openssl ca -gencrl -out ca.crl

服务端 nginx 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
server {
listen 443 ssl;
server_name localhost;
ssl_certificate ssl/server.crt; # 配置证书位置
ssl_certificate_key ssl/server.key; # 配置秘钥位置
ssl_client_certificate ssl/ca.crt;
ssl_verify_client on;
ssl_crl ssl/ca.crl;
ssl_session_timeout 5m;
ssl_protocols SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
root html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}

配置客户端信任 CA 证书

使用自签名的证书的域名,客户端是不信任的, 除非客户端信任对应的自签名 CA 证书。

右键 cacert.crt 选择安装证书, 放进受信任的根证书颁发机构。

windows安装CA证书

1
2
sudo cp cacert.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

然后使用 curl 等工具就受信任了。

1
2
3
sudo cp cacert.crt /etc/pki/ca-trust/source/anchors/
sudo ln -s /etc/pki/ca-trust/source/anchors/cacert.crt /etc/ssl/certs/cacert.crt
sudo update-ca-trust

然后使用 curl 等工具就受信任了。

其他

查看证书有效期

1
openssl x509 -in cacert.crt -noout -dates