这里不详细说明 TLS 协议的内容,请另行查阅文档
个人笔记,不保证正确。
我们需要加密网络数据以实现安全通信,但是有一个现实的问题:
于是 TLS 协议在握手阶段使用非对称算法验证服务端,并安全地生成一个对称密钥,然后使用对称算法进行加密通信。
TLS 通过两个证书来实现服务端身份验证,以及对称密钥的安全生成:
CA 证书和 TLS 证书,都只在 TLS 握手阶段有用到,之后的通信就与它们无关了。
前面讲到了 TLS 协议的握手需要使用到两个证书:
在 TLS 连接的建立阶段,客户端(如浏览器)会使用 CA 证书的公钥对服务端的证书签名进行验证,验证成功则说明该证书是受信任的。
如果我们要生成一个面向公共网络的 TLS 证书,那最好的方法,应该是申请一个 Let‘s Encrypt 免费证书。
该证书可以手动申请,另外 Traefik 等反向代理也有提供自动生成并更新 Let‘s Encrypt 证书的功能。
除了公网可用的受信证书,在内网环境,我们需要也使用 TLS 证书保障通信安全,这时我们可能会选择自己生成证书,而不是向权威机构申请证书。
可能的原因如下:
xxx.local
/xxx.lan
/xxx.srv
等),权威机构不签发这种域名的证书。(因为没有人唯一地拥有这个域名)自己生成的证书有两种方类型:
一般来说,直接生成一个泛域名的自签名证书就够了,但是它不方便拓展——客户端对每个自签名证书,都需要单独添加一次信任。
而第二种方法生成的证书就没这个问题。
总的来说,使用自签名证书不方便进行拓展,未来可能会遇到麻烦。因此建议使用第二种方法。
另外介绍下这里涉及到的几种文件类型:
xxx.key
: 就是一个私钥,一般是一个 RSA 私钥(SHA256 算法),长度通常指定为 2048 位。
openssl genrsa -out xxx.key 2048
xxx.csr
: 即 Certificate Sign Request,证书签名请求。使用 openssl 等工具,通过 TLS 密钥+TLS 证书的相关信息,可生成出一个 CSR 文件。
openssl req -new -key server.key -out server.csr -config csr.conf
,给定 TLS 密钥 server.key
以及证书相关信息 csr.conf
xxx.crt
: 这就是我们所说的 TLS 证书,CA 证书和服务端 TLS 证书都是这个格式。
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 10000 -extensions v3_ext -extfile csr.conf
csr
文件进行签名,就能得到最终的服务端 TLS 证书——一个 crt
文件。总结一下,使用如下命令可生成一个自签名的 TLS 证书(RSA256 算法):
# 1. 生成 2048 位 的 RSA 密钥
openssl genrsa -out server.key 2048
# 2. 生成证书签名请求,需要输入域名(Common Name, CN)等相关信息,也可通过 `-config csr.conf` 指定相关信息
openssl req -new -key server.key -out server.csr
# 3. 生成最终的证书,这里指定证书有效期 10 年
openssl req -x509 -sha256 -days 3650 -key server.key -in server.csr -out server.crt
Let‘s Encrypt 目前也已经支持了 ECC 证书。
ECC(Elliptic Curve Cryptography) 算法被认为是比 RSA 更优秀的算法。与 RSA 算法相比,ECC 算法使用更小的密钥大小,但可提供同样的安全性,这使计算更快,降低了能耗,并节省了内存和带宽。
对于 RSA 密钥,可以提供不同的密钥大小(密钥大小越大,加密效果越好)。
而对于 ECC 密钥,您应选择要用哪种曲线生成密钥对。各个组织(ANSI X9.62、NIST、SECG)命名了多种曲线,可通过如下命名查看 openssl 支持的所有椭圆曲线名称:
openssl ecparam -list_curves
生成一个自签名的 ECC 证书:
# 生成 ec 算法的私钥,使用 prime256v1 算法,密钥长度 256 位。(强度大于 2048 位的 RSA 密钥)
openssl ecparam -genkey -name prime256v1 -out key.pem
# 生成证书签名请求,需要输入域名(Common Name, CN)等相关信息
openssl req -new -sha256 -key key.pem -out csr.csr
# 生成最终的证书,这里指定证书有效期 10 年
openssl req -x509 -sha256 -days 3650 -key key.pem -in csr.csr -out certificate.pem
P.S. 另外还有使用 ECC 进行签名的 ECDSA 算法,被用在了 SSH 协议中,另外 Web 编程中 JWT 的签名也可选用该算法。
JWT 选用 ECDSA(如 ES256) 的最大好处,就是签名变短了,JWT 本身也就变短了,比 RS256 更节约流量,而且具有同等的安全性(这个不 100% 确定)。
服务端需要两个文件:
server.key
server.crt
一般如 Nginx 等服务端应用,都可以通过配置文件指定这两个文件的位置。修改配置后重新启动,就有 TLS 了,可以通过 https 协议访问测试。
如果你在证书不是权威 CA 机构颁发的(比如是一个自签名证书),那就需要在客户端将这个 TLS 证书(公钥)添加到受信证书列表中。
这个步骤可以在 OS 层面进行——添加到 OS 的默认证书列表中,也可以在代码层面完成——指定使用某个证书进行 TLS 验证。
sudo cp ca.crt /usr/local/share/ca-certificates/server.crt
sudo update-ca-certificates
certmgr.msc
安装证书原文:https://www.cnblogs.com/kirito-c/p/12872119.html