HTTPS 解决了 HTTP 不安全的问题
HTTP 整个传输过程数据都是明文的,任何人都能够在链路中截获、修改或者伪造请求/响应报文,数据不具有可信性。
① HTTPS 使用加密算法对报文进行加密,黑客截获了也看不懂
② HTTPS 使用摘要算法对报文进行完整性确认,黑客一旦修改报文,那么 HTTPS 可以及时发现并做相应处理
③ HTTPS 使用数字签名,保证黑客不能伪造请求或响应报文
HTTPS 由 HTTP + SSL/TLS 组成,即在 HTTP 下面增加了一个 SSL 安全套接层(运行在SSL之上的HTTP协议)
SSL 即安全套接层(Secure Sockets Layer),在 OSI 七层网络模型中处于第 5 层(会话层),由网景公司于 1994 年发明,常用 v2 和 v3 两个版本。
IETF 在1999 年把它改名为 TLS(传输层安全,Transport Layer Security),正式标准化,版本号从 1.0 重新算起,所以 TLS1.0 实际上就是 SSLv3.1。
今天 TLS 已经发展出了三个版本,分别是 2006 年的 1.1、2008 年的 1.2 和 2018 年的1.3,目前应用的最广泛的 TLS 是 1.2 。
HTTPS 的安全性是基于 TLS 的加密算法,因此要理解 HTTPS 其实就是要理解 TLS 背后的加密算法原理。
在古代战争中,为了防止书信被截获后重要信息泄露,人们开始对书信进行加密。
如密码棒,使用布条缠绕在木棒上的方式来对书信进行加密。
按规则使用不同的文字来替换掉原先的文字来进行加密。
例如,码表:
原始字符:ABCDEFGHIJKLMNOPQRSTUVWXYZ
密码字符:BCDEFGHIJKLMNOPQRSTUVWXYZA
原始书信:I love you
加密书信:J mpwf zpv
解读后:I love you
与古典密码学相对应的就是现代密码学,主要包括两大分类:对称加密算法和非对称加密算法
对称加密算法:使用相同的密钥,不同的加密和解密算法,对明文加密,对密文解密。
TLS 里有非常多的对称加密算法可供选择,比如 RC4、DES、3DES、AES、ChaCha20 等,前三种被认为不安全,目前常用的只有 AES 和 ChaCha20
AES 的意思是“高级加密标准”(Advanced Encryption Standard) ,密钥长度可以是 128 位(比特)、192 位(比特)或 256 位(比特)。安全强度很高,性能也很好,而且有的硬件还会做特殊优化,所以非常流行,是应用最广泛的对称加密算法。
ChaCha20 是 Google 设计的另一种加密算法,密钥长度固定为 256 位,纯软件运行性能要超过 AES,曾经在移动客户端上比较流行,但 ARMv8 之后也加入了 AES 硬件优化,所以现在不再具有明显的优势,但仍然算得上是一个不错的算法。
破解思路:
反破解:
对称加密算法面临的最大问题:如何把密钥安全地传递给对方,术语叫做“密钥交换”。
对称加密算法的缺点就是不能在不安全的网络上传输密钥,因为一旦密钥泄露则加密通信失败。
非对称加密算法是使用相同的加密算法 + 两个不同的密钥(不对称),一个叫公钥(public key),一个叫私钥(private key),公钥可以公开给任何人使用,而私钥必须严格保密。
公钥和私钥有个特点:单向性,虽然都可以用来加密解密,但公钥加密后只能用私钥来解密,反过来,私钥加密后也只能用公钥来解密。
使用非对称加密通信,可以在不可信网络上将双方的公钥传给对方,然后在发消息前分别对消息使用对方的公钥来加密和使用自己的私钥来签名,做到不可信网络上的可靠密钥传播及加密通信。
非对称加密算法的设计要比对称算法难得多,在 TLS 里只有很少的几种,比如 DH、DSA、RSA、ECC 等。
RSA 可能是其中最著名的一个,几乎可以说是非对称加密的代名词,它的安全性基于“整数分解”的数学难题,使用两个超大素数的乘积作为生成密钥的材料,想要从公钥推算出私钥是非常困难的。
10 年前 RSA 密钥的推荐长度是 1024,但随着计算机运算能力的提高,现在 1024 已经不安全,普遍认为至少要 2048 位。
ECC (Elliptic Curve Cryptography)是非对称加密里的“后起之秀”,它基于“椭圆曲线离散对数”的数学难题,使用特定的曲线方程和基点生成公钥和私钥,子算法 ECDHE 用于密钥交换,ECDSA 用于数字签名。
目前比较常用的两个曲线是 P-256(secp256r1,在 OpenSSL 称为 prime256v1) 和 x25519。P-256 是 NIST (美国国家标准技术研究所)和 NSA(美国国家安全局)推荐使用的曲线,而 x25519 被认为是最安全、最快速的曲线。
比起 RSA,ECC 在安全强度和性能上都有明显的优势。160 位的 ECC 相当于 1024 位的 RSA,而 224 位的 ECC 则相当于 2048 位的 RSA。因为密钥短,所以相应的计算量、消耗的内存和带宽也就少,加密解密的性能就上去了,对于现在的移动互联网非常有吸引力。
破解思路:
反破解:
对称加密 | 非对称加密 |
---|---|
有密钥交换问题 | 没有密钥交换问题 |
运算速度快 | 运算速度很慢 因为非对称加密算法基于复杂的数学难题,即使是 ECC 也要比 AES 差上好几个数量级 |
如果只用非对称加密,虽然保证了安全,但通信速度非常慢,实用性就变成了零。
在通信刚开始的时候使用非对称算法,比如 RSA、ECDHE,首先解决密钥交换的问题。
混合加密就解决了对称加密算法的密钥交换问题,而且安全和性能兼顾。
然后用随机数产生对称算法使用的“会话密钥”(session key),再用公钥加密。因为会话密钥很短,通常只有 16 字节或 32 字节,所以慢一点也无所谓。
黑客虽然拿不到会话密钥,无法破解密文,但可以通过窃听收集到足够多的密文,再尝试着修改、重组后发给网站。因为没有完整性保证,服务器只能“照单全收”,然后他就可以通过服务器的响应获取进一步的线索,最终就会破解出明文。
实现完整性的手段主要是摘要算法(Digest Algorithm)。
你可以把摘要算法近似地理解成一种特殊的压缩算法,它能够把任意长度的数据“压缩”成固定长度、而且独一无二的“摘要”字符串,就好像是给这段数据生成了一个数字“指纹”。
换一个角度,也可以把摘要算法理解成特殊的“单向”加密算法,它只有算法,没有密钥,加密后的数据无法解密,不能从摘要逆推出原文。
MD5 (Message-Digest 5) 和 SHA-1 (Secure Hash Algorithm 1)就是最常用的两个摘要算法,能够生成 16 字节和 20 字节长度的数字摘要。但这两个算法的安全强度比较低,不够安全,在 TLS 里已经被禁止使用了。
目前 TLS 推荐使用的是 SHA-1 的后继者:SHA-2
SHA-2 实际上是一系列摘要算法的统称,总共有 6 种,常用的有 SHA224、SHA256、SHA384,分别能够生成 28 字节、32 字节、48 字节的摘要。
如果黑客在中间哪怕改动了一个标点符号,摘要也会完全不同,网站计算比对就会发现消息被窜改,是不可信的。
黑客可以伪装成网站来窃取信息。而反过来,他也可以伪装成你,向网站发送支付、转账等消息,网站没有办法确认你的身份,钱可能就这么被偷走了。
实际生活中,解决身份认证的手段是签名和印章,只要在纸上写下签名或者盖个章,就能够证明这份文件确实是由本人而不是其他人发出的。
在 TLS 里有什么东西和现实中的签名、印章很像,只能由本人持有,而其他任何人都不会有呢?只要用这个东西,就能够在数字世界里证明你的身份。
这个东西就是非对称加密里的“私钥”,使用私钥再加上摘要算法,就能够实现“数字签名”,就可以实现“身份认证”。
数字签名就是把摘要算法生成的摘要再用私钥进行加密后的内容,将这部分内容与原摘要一起放入报文,作为身份认证。
客户端向服务端发送加密报文的流程:
客户端签名流程:
服务端验证签名流程:
服务端向客户端发送加密报文流程与上面类似:
服务端签名流程:
客户端验证签名流程:
找一个公认的可信第三方,让它作为“信任的起点,递归的终点”,构建起公钥的信任链。
这个“第三方”就是我们常说的 CA(Certificate Authority,证书认证机 构)。它就像网络世界里的公安局、教育部、公证中心,具有极高的可信度,由它来给各个公钥签名,用自身的信誉来保证公钥无法伪造,是可信的。
CA 对公钥的签名认证也是有格式的,不是简单地把公钥绑定在持有者身份上就完事了,还要包含序列号、用途、颁发者、有效时间等等,把这些打成一个包再签名,完整地证明公钥关联的各种信息,形成“数字证书”(Certificate)。
知名的 CA 全世界就那么几家,比如 DigiCert、VeriSign、Entrust、Let’s Encrypt 等,它们签发的证书分 DV、OV、EV 三种,区别在于可信程度。
DV 是最低的,只是域名级别的可信,背后是谁不知道。EV 是最高的,经过了法律和审计的严格核查,可以证明网站拥有者的身份。
问题:CA 怎么证明自己值得信任呢?
有了这个证书体系,操作系统和浏览器都内置了各大 CA 的根证书,上网的时候只要服务器发过来它的证书,就可以验证证书里的签名,顺着证书链(Certificate Chain)一层层地验证,直到找到根证书,就能够确定证书是可信的,从而里面的公钥也是可信的。
ECDHE 和 RSA 的详细 TLS 握手流程请参考:https://www.processon.com/view/link/62bed0685653bb214fa3d58f
HTTPS:
HTTPS的安全性主要体现在三个方面:
对称加密算法:
非对称加密算法:
TLS 使用混合加密的方式:
先通过非对称加密算法解决密钥交换的问题,用随机数生成用于对称加密算法使用的"会话密钥“,然后用公钥加密”会话密钥“发给对方,对方使用私钥解密出”会话密钥“,后续双方就可以使用”会话密钥"基于对称加密算法进行通信了。
1)服务端下发公钥(非对称加密算法)
2)客户端使用公钥来加密生成的 [会话密钥] (非对称加密算法)
3)服务端使用私钥来解密客户端发来的 [会话密钥](非对称加密算法)
4)然后客户端和服务端后面使用该 [会话密钥] 来通信(对称加密算法)
这样首先用非对称加密算法解决了密钥交换问题,又利用对称性加密算法提高了性能。
数据完整性:
摘要算法:可以理解为一种特殊的压缩算法,或者Hash算法,它可以把任意长度的数据压缩成固定长度且独一无二的摘要字符串,也可以把摘要算法理解成特殊的单向加密算法,它只有算法,没有密钥,加密后的数据无法解密,不能从摘要逆推出原文。
常用的摘要算法有 MD5、SHA-1 但这两个不够安全已经被 TLS 禁用了,目前推荐的是SHA-2,SHA-2是一系列的摘要算法,常用的有 SHA224、SHA256、SHA384,分别能够生成 28、32、48 字节的摘要。
数字签名:
这是客户端向服务端发送加密报文的流程,反过来,服务端向客户端发送加密报文流程与这个类似。
公钥信任问题:
交互流程图:
补充其他和编码相关的内容:
将二进制数据转换成由 64 个字符组成的字符串的编码算法。
算法:将原数据每 6 位对应成 Base 64 索引表中的一个字符编排成一个字符串(每个字符 8 位)。
Base64 索引表:
编码示例:把「Man」进行 Base64 编码
编码示例:Base64 的末尾补足
Base64 的用途
Base64 的缺点
「Base64 加密图片传输更安全和高效」???
不。首先,Base64 并不是加密;另外,Base64 会导致数据增大 1/3,降低网络性能,增大用户流量开销,是画蛇添足的手段。
Base64 对图片进行编码的用处在于,有时需要使用文本形式来传输图片。除此之外,完全没必要使用 Base64 对图片进行额外处理。
变种:Base58
压缩的目的是减小数据占用的存储空间。
粗暴算法举例
将下面文本内容压缩:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaabb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
使用某种算法压缩后的数据为:
compress:a:1062;b:10
注:具体的压缩场景有很多,因此压缩算法也会复杂得多,上面只是一个原型算法。
压缩是编码吗?
常见压缩算法:DEFLATE、JPEG、MP3 等。
把任意数据转换成指定大小范围(通常很小,例如 256 字节以内)的数据。
作用:相当于从数据中提出摘要信息,因此最主要用途是数字指纹。
Hash 的实际用途:
hashCode()
方法。(怎么重写 hashCode 方法?把 equals()
方法中的每个用于判断相等的变量都放进 hashCode()
中,一起生成一个尽量不会碰撞的整数即可)