在很多使用到证书的场景, 比如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.babudiu.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=*.babudiu.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=babudiu.com
DNS.2=*.babudiu.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证书。

windows信任CA

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

windows安装CA证书

Debian系信任CA

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

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

Redhat系信任CA

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等工具就受信任了。