0.背景
公私钥、证书体系、Https等基础知识。
这个之前有写过ppt,空了我编辑成文章传上来,再更新这里。
1.密钥及证书角色
区分自签名证书和CA签名证书
自签名:根证书是自己的私钥签名的,意味着它是由相应的私钥持有者(即CA本身)签发的,而不是由另一个CA签发。
1.1 CA
以RSA为例
该环节,模拟自己作为CA,生成ca的私钥和根证书。
1.1.1 私钥生成
openssl genrsa -out ca-private.key 2048
genrsa:生成 RSA 密钥的 OpenSSL 命令。
-out server.key:指定生成的私钥文件名为 server.key。
2048:指定密钥的位数,通常为 2048 位。
1.1.2 根证书生成
openssl req -new -x509 -key ca-private.key -out ca.crt -days 3650
req:执行证书请求和生成证书操作的 OpenSSL 子命令。
-new:创建一个新的证书请求 (CSR)。
-x509:生成自签名的 X.509 证书,而不仅仅是 CSR。
-key server.key:指定用于生成证书的私钥文件。
-out ca.crt:指定生成的自签名根证书文件名为 ca.crt。
-days 3650:指定证书的有效期,这里设置为 3650 天(大约 10 年)。
1.1.3 总结
1.2 用户
1.1.1 私钥生成
openssl genrsa -out user-private.key 2048
1.2.2 生成请求文件CSR
这个玩意有时候也叫p10文件
openssl req -new -key user-private.key -out user.csr
req:执行证书请求操作的 OpenSSL 子命令。
-new:创建一个新的证书请求 (CSR)。
-key server.key:指定用于生成 CSR 的私钥文件。
-out server.csr:指定生成的 CSR 文件名为 server.csr。
制作csr的时候,一般在Common Name
处输入我们的域名。
Common Name (e.g. server FQDN or YOUR name) []:example.com
1.2.3 总结
3.CA签发用户证书
1.3.1 签发证书
无非就是私钥给我们的csr文件签名下
openssl x509 -req -days 3650 -in user.csr -CA ca.crt -CAkey ca-private.key -CAcreateserial -out user.crt
x509:执行 X.509 证书操作的 OpenSSL 子命令。
-req:指定输入文件为 CSR。
-days 3650:指定生成的服务器证书的有效期,这里设置为 3650 天(大约 10 年)。
-in server.csr:指定输入的 CSR 文件。
-CA ca.crt:指定用于签名 CSR 的根证书文件。
-CAkey server.key:指定用于签名 CSR 的根证书的私钥文件。
-CAcreateserial:指定在生成证书时创建序列号文件。
1.3.2 总结
经过签发后,我们就有了一个证书文件user.crt
。
2.Nginx配置(服务端)
https最开始的步骤,就是握手前问服务器要下证书,然后通过本地根证书验证下这个证书靠谱不。
然后,证书验证通过,利用这个可信的“公钥证书”来与服务器构建会话密钥。
所以,作为nginx服务器,配置证书时,我们应该要做这2个事情。
- 将私钥对应的公钥证书返回给客户端
- 配置私钥文件,用于解密客户端发送的“公钥证书加密“的数据包。
2.1 配置
2.1.1 linux
#ssl
server {
#SSL 访问端口号为 443
listen 443 ssl;
#填写绑定证书的域名
server_name yang37.cn;
#证书文件路径
ssl_certificate /etc/nginx/key/ssl/user.crt;
#私钥文件路径
ssl_certificate_key /etc/nginx/key/ssl/user-private.key;
ssl_session_timeout 5m;
#请按照以下协议配置
ssl_protocols TLSv1.2 TLSv1.3;
#请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
#网站主页路径。此路径仅供参考,具体请您按照实际目录操作。
#例如,您的网站运行目录在/etc/www下,则填写/etc/www。
root html;
index index.html index.htm;
}
}
2.1.2 windows
#ssl
server {
#SSL 访问端口号为 443
listen 443 ssl;
#填写绑定证书的域名
server_name yang37.cn;
#证书文件路径
ssl_certificate D:/Software/nginx/nginx-1.22.1/cert/user.crt;
#私钥文件路径
ssl_certificate_key D:/Software/nginx/nginx-1.22.1/cert/user-private.key;
ssl_session_timeout 5m;
#请按照以下协议配置
ssl_protocols TLSv1.2 TLSv1.3;
#请按照以下套件配置,配置加密套件,写法遵循 openssl 标准。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
#网站主页路径。此路径仅供参考,具体请您按照实际目录操作。
#例如,您的网站运行目录在/etc/www下,则填写/etc/www。
root html;
index index.html index.htm;
}
}
2.2 重载ng
nginx -s reload
2.3 验证
此处使用nginx在win下配置了刚才的证书,本地访问https://127.0.0.1
可以看到已经能够通过https正常访问了。
那么,为啥浏览器提示不安全呢?因为证书是我们自己生成的,可信任根证书里没有我们自己作为CA时的根证书。
当然可以手动操作下,导入就好了,参照3.4、3.5节。
3.扩展
3.1 私钥文件加密
生成私钥时,可以使用对称算法加密私钥,这样私钥就不能直接使用,而是需要输入密码。
# 生成加密的rsa私钥,长度为2048
openssl genrsa -des3 -out server.key 2048
genrsa:生成 RSA 密钥的 OpenSSL 命令。
-des3:使用 DES3 算法加密私钥,需要输入至少四位密码。
-out server.key:指定生成的私钥文件名为 server.key。
2048:指定密钥的位数,通常为 2048 位。
通过此种方式生成出来的私钥,是通过des3加密了的,打开生成的文件可以看到ENCRYPTED
标记。
既然加密了,使用的时候肯定需要使用密码操作。如果想要方便,执行下方命令。
openssl rsa -in server.key -out server.key
这样私钥使用时就不再需要输入密码了。
3.2 CSR文件是啥
csr就是公钥带着刚才那堆备注信息而已,可以在这个网站解析csr文件。
公钥和证书的差别就是证书额外多了个CA签发,其实可以推断,CA无非就是拿着自己的私钥给我们这个csr签名下而已。
3.3 签发后咋多出来一个srl文件
多出来了个srl文件,这个就是证书的序列号信息,签发的证书里面可以看到是一样的。
这个序列号当作唯一id就好了,每个证书都不一样。
3.4 关于自签名证书的问题
上面的演示中,可以发现服务端只是导入了用户私钥user-private.key
和用户证书user.crt
,可以看到服务端根本都没有上传过根证书ca.crt
。
那么问题来啦:如果服务器没有提供 CA 的根证书,客户端如何验证服务器证书的真实性?
-
通常客户端并不需要服务器提供 CA 的根证书
因为根证书应该已经预安装在客户端的操作系统或浏览器中。
根证书通常是由全球信任的证书颁发机构提供的,这些机构的证书内置在客户端软件中。
-
本例中使用的是自签名的根证书
所以客户端必须事先知道并信任这个根证书才能验证服务器证书(
user.crt
)的真实性。如果客户端没有预先安装这个根证书,它将不能验证服务器证书,从而导致安全警告或拒绝建立连接。
-
为了让自签名证书工作,必须手动将 CA 的根证书(
ca.crt
)安装到每个客户端设备上。这样,当 SSL 握手发生时,客户端可以使用已安装的根证书来验证服务器证书。
在实际生产环境中,由于无法要求所有用户都安装自签名的根证书,因此通常会使用具有公信力第三方 CA 签发的证书。
3.5 win导入根证
win + r 打开命令框,输入certmgr.msc
进入win证书管理器。
找到受信任的根证书颁发机构,右键选择导入。
找到我们刚才自己的ca根证,执行导入操作。
导入完成后,可以看到我们的根证书。