1 什么数字证书(Certificate)
数字证书是一种用于电脑的身份识别机制。由数字证书颁发机构(CA)对使用私钥创建的签名请求文件做的签名(盖章),表示 CA 结构对证书持有者的认可。数字证书拥有以下几个优点:
- 使用数字证书能够提高用户的可信度
- 数字证书中的公钥,能够与服务端的私钥配对使用,实现数据传输过程中的加密和解密
- 在证认使用者身份期间,使用者的敏感个人数据并不会被传输至证书持有者的网络系统上
X.509 证书包含三个文件:key,csr,crt。
key
是服务器上的私钥文件,用于对发送给客户端数据的加密,以及对从客户端接收到数据的解密csr
是证书签名请求文件,用于提交给证书颁发机构(CA)对证书签名crt
是由证书颁发机构(CA)签名后的证书,或者是开发者自签名的证书,包含证书持有人的信息,持有人的公钥,以及签署者的签名等信息
在密码学中,X.509 是一个标准,规范了公开秘钥认证、证书吊销列表、授权凭证、凭证路径验证算法等。
浏览器检查一个证书是否仍然有效有两种方法: OCSP (Online Certificate Status Protocol,在线证书状态协议) 和 CRL(Certificate Revoke List,证书吊销列表)。
2 创建自签名的证书
用于生产环境的数字证书,颁发机构(CA)必须是可信的第三方机构。在应用开发过程中,我们可以生成自签名的证书以配置开发或测试环境。
2.1 逐步生成私钥和自签名证书
2.1.1 生成服务器私钥
1 | openssl genrsa -des3 -out server.key 4096 |
2.1.2 生成证书签名请求
1 | openssl req -new -key server.key -out server.csr |
这里要填一大堆东西,注意 Common Name
处应填写你希望使用的网站域名
2.1.3 对上一步生成的证书签名请求进行签名
1 | openssl x509 -req -days 3650 - in server.csr -signkey server.key -out server.crt |
2.1.4 生成无需密码的服务器私钥
如果私钥是有密码的,则每次启动 web 服务器都会要求你输入密码。
1 2 3 | openssl rsa - in server.key -out server.key.insecure mv server.key server.key.secure mv server.key.insecure server.key |
修改证书秘钥的读取权限,确保你的私钥的安全性,因为该证书无法被吊销。
1 | chmod 999 server.key.secure server.key |
2.2 一步创建私钥和自签名证书
有一个简单的方法一步创建私钥和自签名请求:
1 | openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout server.key -out server.crt |
输入信息参考:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | writing new private key to 'server.key' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.' , the field will be left blank. ----- Country Name (2 letter code) [AU]:CN State or Province Name (full name) [Some-State]:GD Locality Name (eg, city) []:GZ Organization Name (eg, company) [Internet Widgits Pty Ltd]:lzwme Organizational Unit Name (eg, section) []:blog Common Name (e.g. server FQDN or YOUR name) []:*.lzw.me Email Address []:webmaster@lzw.me |
以上所有操作中, server.key 为私钥, server.crt 为证书。
3 创建私有 CA 证书,并创建用该 CA 证书签名的证书
3.1 生成 CA 私钥(ca.key)和 CA 证书(ca.crt)
CA 证书就是一个自签名的证书,只是在 Common Name
处可以随意填写。
1 2 3 4 | openssl genrsa -out server.key 2048 openssl req -new -x509 -days 3650 -key ca.key -out ca.crt // 或者一步生成 openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout ca.key -out ca.crt |
3.2 生成服务器使用的私钥(server.key)和证书签名请求文件(server.csr)
1 2 | openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr |
注意,这里的 Common Name
应当和希望使用的域名或 IP 相同。
3.3 使用 CA 私钥和证书对 server 证书签名
1 | openssl x509 -req -days 3650 - in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt |
4 网站服务器配置使用自签名的证书
nginx 配置和正常的 https 站点配置相同,主要信息参考:
1 2 3 4 5 6 7 | server { listen 443 ssl; ssl on; ssl_certificate /path/to/server .crt; ssl_certificate_key /path/to/server .key; server_name test .lzw.me; } |
自建 nodejs server
参考:
1 2 3 4 5 6 7 8 | const https = require( 'https' ); const fs = require( 'fs' ); const path = require( 'path' ); const server = https.createServer({ key: fs.readFileSync(path.join(__dirname, './ssl/server.key' ), 'utf8' ), cert: fs.readFileSync(path.join(__dirname, './ssl/server.crt' ), 'utf8' ), ca: [fs.readFileSync(path.join(__dirname, './ssl/ca.key' ), 'utf8' )], }, app); |
5 用户端添加 CA 证书为受信任的根证书颁发机构
用户端的机器上,需将 ca.crt
证书添加为可信颁发机构。方法步骤大致如下:
双击 ca.crt
-> 安装证书 -> 本地计算机 -> 选择“将所有的证书都放入下列存储” -> 浏览 -> 受信任的根证书颁发机构 -> 确定。
6 相关问题
6.1 如何查看各种证书的信息
以下为一些常见的查看证书相关信息的方法。
openssl rsa -noout -text -in server.key
查看私钥信息openssl req -noout -text -in server.csr
查看签名请求信息openssl rsa -noout -text -in ca.key
查看ca的私钥信息openssl x509 -noout -text -in ca.crt
查看证书信息openssl crl -text -in xx.crl
查看一个证书吊销列表信息openssl x509 -purpose -in cacert.pem
查看一个证书的额外信息openssl rsa -in key.pem -pubout -out pubkey.pem
从一个私钥里面提取出公钥openssl rsa -noout -text -pubin -in apache.pub
查看一个公钥的信息openssl verify -CAfile 指定CA文件路径 apache.crt
验证一个证书是否是某一个CA签发openssl s_client -connect 192.168.20.51:443
模拟一个ssl客户端访问ssl服务器。如果服务端要求客户端提供证书,则在加上 -cert 和 -key 参数。比如openssl s_client -connect 192.168.20.51:443 -cert client.crt -key client.key
openssl pkcs12 -in path.p12 -out newfile.crt.pem -clcerts -nokeys
从p12文件里面提取证书openssl pkcs12 -in path.p12 -out newfile.key.pem -nocerts -nodes
从p12文件里面提取私钥
6.2 代理软件、应用程序内访问 https 服务报错 Error: self signed certificate
如果正确地添加了 CA
证书为受信任的根证书颁发机构
,一般来说应该可以正常使用。如果在应用内访问出现该错误提示,可尝试禁用 SSL 安全验证。以 nodejs 中使用 http.request 为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | const https = require( 'https' ); const options = { host: 'test.lzw.me' , port: 8000, path: '/api/test' , // Add these next lines rejectUnauthorized: false , requestCert: true , agent: false , secure: false , }; https.request(options, function (res) { res.pipe(process.stdout); }).end(); |
相关参考
- https://blog.csdn.net/sdcxyz/article/details/47220129
- https://blog.csdn.net/h330531987/article/details/74991694