SSL CA HTTPS

CA,Catificate Authority,它的作用就是提供证书(即服务器证书,由域名、公司信息、序列号和签名信息组成)加强服务端和客户端之间信息交互的安全性,以及证书运维相关服务。

HTTPS证书

CA 之前,我们不得不去先聊聊 SSL,因为 HTTP 传输数据的明文性质,导致了后续社区提出了加密方案,也就是 SSL(Secure Socket Layer) 在原有的 Socket 之上增加一层加密传输,HTTPS 也就是 HTTP + SSL, TLS 是被 IETF 标准化的 SSL -> Transport Layer Security

SSL 本身也不是很复杂,在建立好 TCP 协议之后,我们通过 SSL 协议协商,完成加密。

  • 客户端先向服务器发出加密通信的请求,这被叫做ClientHello请求。
  • 服务器收到客户端请求后,向客户端发出回应,这叫做ServerHello
  • 客户端回应
  • 服务器的最后回应

其中比较复杂的就是 RSA 非对称加密技术了,这里就不做展开,可以参考 RSA算法原理

CA

在上一节中,我们知道了服务器之间是需要交换公私钥的,因此其实有被串改的风险的,因为其实我们是没办法辨别对方是否是真实性,因此我们在此加入了一个中间公正机构,也就是 CA 提供商,因此我们访问一些自定义的服务SSL会导致如下

就是因为 RSA 证书不受信任,因此CA提供商,提供了有偿服务,在服务器上维护了大量公私钥,不过有人会问,为什么CA本身不能是假的呢?其实这个也是可以的,不过在绝大多数的系统中,会提供默认的证书提供商的公钥,只要不去恶意的替换就不存在被替换的风险。

Root 根证书

为什么需要根证书呢?这就是和上面信任的问题,我们知道绝大多数的系统会内置一些 CA 提供商的证书,这些证书就是根证书,此时我们去访问一个 HTTPS 服务器的时候,那我们怎么知道它的证书是可靠的呢?解决之道就是 证书链

证书链 在生成证书的时候就会生产出来,一般来说就就是三级

  • end-user:即 www.google.com,是该网站使用 HTTPS 安装的数字证书
  • intermediates:即 Google Internet Authority G3,是给 end-user 签发证书的中间 CA 的证书,中间 CA 可能不止一个
  • root:即 Google Trust Services - GlobalSign Root CA-R2,是根 CA 的证书,它给中间 CA 签发证书

为什么需要证书链,并不是担心 end-user 的私钥丢失,丢失了再生成就好了,主要担心的是 intermediates 的私钥丢失,这样会影响所有下游系统,因此当 intermediates 的私钥丢失,root 会放弃这个 intermediates 的证书,认为不合法,然后换一个CA给所有的 end-user 生产一个人新的证书,这样中间CA 产生的不安全被隔离了。

1
2
# 比如这里我们生成一个 ca 的证书(x509格式, ca.key 为私钥  ca.crt为数字证书[公钥] )
openssl req -x509 -sha256 -newkey rsa:4096 -keyout ca.key -out ca.crt -days 356 -nodes -subj '/CN=My Cert Authority'

数字证书

公钥和私钥,是非常基础的设施,在 A 和 B 两个服务之间,建立链接的时候,我们知道会发送 Hello 请求,其中包含的也就是服务器的数字证书,数字证书。

用于 SSL 的公钥和私钥本质上是用于加密和签署数据的长字符串。使用公钥加密的数据只能用私钥解密。但是直接传递长字符串并不明智,实则是服务端将自己的公钥发送给 CA,CA 将其一些其他信息(失效时间)一起打包,用自己的私钥签名,打包成一个数字证书。

这样当对端收到这个数字证书的时候,可以使用 CA 的公钥进行验签,保证了这个传递的数字证书本身是可靠的。

1
2
3
4
5
# 生成服务端证书 (server.key 为私钥, server.csr 为证书签名请求(Certificate signing request)[其中包含了公钥])
openssl req -new -newkey rsa:4096 -keyout server.key -out server.csr -nodes -subj '/CN=mydomain.com'

# 将 server.csr 通过 CA 签名成 server.crt 数字证书[公钥]
openssl x509 -req -sha256 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

验签

经过上面的一通操作,此时如别有个 Client 需要进行访问的时候

  1. Client 是有 ca.crt 的(这个是公开的)
  2. Client 请求 Server 发出 Hello, Server 进行响应,返回了 server.crt
  3. server.crt 收到,Client 使用 ca.crt 进行验签,保证合法,从而得知 server 的公钥
  4. 请求后续使用 server 的公钥

Real World

一般我们生成自签名的系统的时候,第一步都是生产自签名的 ROOT 证书

  • root-cert.pem: root 证书
  • root-key.pem: root 私钥

然后根据我们的 ROOT 证书生成 intermediates 证书

  • ca-cert.pem: intermediate 证书
  • ca-key.pem: intermediate 私钥
  • cert-chain.pem: 证书链

因此我们到时候直接需要把 root-cert 加入我们的系统之中,这些 IMT 证书就可以直接使用了。

参考