引子
前几天看到微信后台团队分享了TLS相关文章,正好gRPC里TLS数据加密是很重要的一块,于是整理出了这篇文章。
在gRPC里,如果仅仅是用来做后端微服务,可以考虑不加密。本文太长,先给个大纲。
1. HTTPS,HTTP/2介绍
2. TLS加密原理、实现库
3. HTTP/2协议协商机制
4. 自建数字证书(CA)
5. gRPC使用TLS
1. HTTP/1.x
目前绝大多数网站和APP都是建立在HTTP之上的,所有的数据都是明文传输,没有任何安全可言。
网图
2. HTTPS
HTTPS(Hypertext Transfer Protocol over Secure Socket Layer)是以安全为目标的HTTP通道,即HTTP下加入SSL层,HTTPS的安全基础是SSL。用来保护用户隐私,防止流量劫持。
(网图,懒得画了)
2.1 HTTPS的作用(来自百度)
HTTPS之所以安全,就是HTTP建立在SSL/TLS之上的。
(网图)
SSL/TLS协议的基本思路是采用公钥加密法,也就是说,客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。
(1)如何保证公钥不被篡改?
将公钥放在数字证书中。只要证书是可信的,公钥就是可信的。
(2)公钥加密计算量太大,如何减少耗用的时间?
每一次对话,客户端和服务器端都生成一个”对话密钥”,用它来加密信息。由于”对话密钥”是对称加密,所以运算速度非常快,而服务器公钥只用于加密”对话密钥”本身,这样就减少了加密运算的消耗时间。
也就是说,对于HTTPS,由于成本问题
-
握手阶段(handshake)用的非对称加密
-
数据通信用的是对称加密
2.2 加密算法
我们大致的讲一下加密相关术语。由于密码学太过复杂,我们不去深究,也千万别问我为什么公钥加密后,能够用私钥解密。
(主要是数学太难,门槛太高,我也不懂,逃。。。)
对称密钥
又称为共享密钥加密,对称密钥在加密和解密的过程中使用的密钥是相同的,常见的对称加密算法有DES、3DES、AES、RC5、RC6。对称密钥的优点是计算速度快,但是密钥需要在通讯的两端共享,让彼此知道密钥是什么对方才能正确解密,如果所有客户端都共享同一个密钥,那么这个密钥就像万能钥匙一样,可以凭借一个密钥破解所有人的密文了。
非对称密钥
服务端会生成一对密钥,一个私钥保存在服务端,仅自己知道,另一个是公钥,公钥可以自由发布供任何人使用。客户端的明文通过公钥加密后的密文需要用私钥解密。非对称密钥在加密和解密的过程的使用的密钥是不同的密钥,加密和解密是不对称的,所以称之为非对称加密。与对称密钥加密相比,非对称加密无需在客户端和服务端之间共享密钥,只要私钥不发给任何用户,即使公钥在网上被截获,也无法被解密,仅有被窃取的公钥是没有任何用处的。常见的非对称加密有RSA。
数字签名
数字签名就如同日常生活中的签名一样,这是任何人都没法仿造的。在计算机中的数字签名就是用于验证传输的内容是不是真实服务器发送的数据,发送的数据有没有被篡改过。
数字证书
数字证书简称CA,它由权威机构给某网站颁发的一种认可凭证,这个凭证是被大家(浏览器)所认可的。
3. HTTP/2
HTTP/2,主要是基于Google的SPDY协议,是自HTTP/1.1从1999年发布16年后的首次更新。Servlet4.0将完全支持HTTP/2。
3.1 HTTP/1.1的问题
3.2 HTTP/2主要特性:
-
request/response多路复用(multiplexing)
-
二进制帧传输(binary framing)
-
数据流优先级(stream prioritization)
-
服务器推送(server push)
-
头信息压缩(header compression)
HTTP/2是站在HTTP/1.1肩膀上的一个改进而已,跟HTTP/1.1相比:
-
相同的request/response模式
-
没有新的method
-
没有新的header
-
在应用层没有引入新的花样
-
没有修改URL规范、没有修改其他底层规范
HTTP/2仅是一个协议而已,它可以建立在TLS之上,也可以不。但是,根据 http://caniuse.com/,网站的统计,浏览器几乎只支持安全的HTTP/2,也就是说如果是网站的话,想要升到HTTP/2就必须支持HTTPS。当然如gRPC这种内部的服务开发,可以不用支持TLS。
3.3 HTTP/2 的协议协商机制
一个网站支不支持HTTP/2,对于浏览器来说是不知道的,只能通过两者的协商来确定是否使用HTTP/2协议,还是HTTP/1.1。我们分2种来讲。
a. HTTP(without TLS)
为了更方便地部署新协议,HTTP/1.1 引入了 Upgrade 机制,它使得客户端和服务端之间可以借助已有的 HTTP 语法升级到其它协议。
如果大家之前使用过 WebSocket,应该已经对 HTTP Upgrade 机制有所了解。下面是建立 WebSocket 连接的 HTTP 请求
GET ws://example.com/ HTTP/1.1
Connection: Upgrade
Upgrade: websocket
Origin: http://example.com
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: d4egt7snxxxxxx2WcaMQlA==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
这是服务端同意升级的 HTTP 响应:
HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: gczJQPmQ4Ixxxxxx6pZO8U7UbZs=
在这之后,客户端和服务端之间就可以使用 WebSocket 协议进行双向数据通讯,跟 HTTP/1.1 没关系了。可以看到,WebSocket 连接的建立就是典型的 HTTP Upgrade 机制。显然,这个机制也可以用做 HTTP/1.1 到 HTTP/2 的协议升级。
b. HTTPS(with TLS)
多了 TLS 之后,双方必须等到成功建立 TLS 连接之后才能发送应用数据。而要建立 TLS 连接,本来就要进行 CipherSuite 等参数的。引入 HTTP/2 之后,需要做