--- title: 制作和使用自签名证书 abbrlink: 097e5b7c categories: - 基础运维 tags: - SSL - Auth date: 2022-05-28 14:05:52 --- 在很多使用到证书的场景, 比如HTTPS, 可以选择去申请一个免费的证书, 也可以尝试自签名证书, 申请免费证书请看:[使用certbot自动申请ssl证书](/posts/28c679c3)或者[使用acme.sh来自动更新https证书](/posts/1e777b9e), 本文介绍自签名证书. ## SSL协议加密方式 SSL协议即用到了对称加密也用到了非对称加密(公钥加密),在建立传输链路时,SSL首先对对称加密的密钥使用公钥进行非对称加密,链路建立好之后,SSL对传输内容使用对称加密。 - 对称加密 速度高,可加密内容较大,用来加密会话过程中的消息。 - 公钥加密 加密速度较慢,但能提供更好的身份认证技术,用来加密对称加密的密钥。 ## CA 证书 ### 生成 CA 私钥 ```bash openssl genrsa -out ca.key 4096 ``` 生成一个 `ca.key` 文件 ### 生成 CA 证书 {% tabs TabName %} ```bash 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 | ```bash 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' ``` {% endtabs %} 就可以生成 `ca.crt` 文件, 这个文件需要加入到客户端的`受信任的根证书颁发机构` - 可选: 将CA证书转换成p12文件 ```bash openssl pkcs12 -export -in ca.crt -inkey ca.key -out ca.p12 ``` ## Server 证书 ### 生成 server 端的私钥 ```bash openssl genrsa -out server.key 4096 ``` ### 生成 server 端数字证书请求 {% tabs TabName %} ```bash 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 | ```bash 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' ``` {% endtabs %} ### 用 CA 私钥签发 server 的数字证书 > 解决chrome不受信任的问题 vim server.ext ```conf 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和域名, 支持通配符 ```bash openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 -sha256 -extfile server.ext ``` 生成 `server.crt` 证书文件 ## 吊销证书 ### 生成证书吊销列表 {% tabs TabName %} > 具体用什么目录需要查看openssl的配置文件中dir项 > ubuntu的配置文件在`/usr/lib/ssl/openssl.cnf` ```bash 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` ```bash 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 ``` {% endtabs %} ### 吊销指定证书 其他的证书都是ca签发的, 不管是nginx用的server证书,还是双向认证用到的client证书, 吊销证书后需要重新生成crl文件 ```bash openssl ca -revoke client.crt openssl ca -gencrl -out ca.crl ``` ## 服务端nginx配置 ```conf 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证书](https://static.zahui.fan/images/202305251008396.png) ### Debian系信任CA ```bash sudo cp cacert.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates ``` 然后使用curl等工具就受信任了。 ### Redhat系信任CA ```bash 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等工具就受信任了。