HTTP的问题
由于 HTTP 天生明文传输的特性,在 HTTP 的传输过程中,任何人都有可能从中截获、修改或者伪造请求发送,所以可以认为 HTTP 是不安全的;在 HTTP 的传输过程中不会验证通信方的身份,因此 HTTP 信息交换的双方可能会遭到伪装,也就是没有用户验证
;在 HTTP 的传输过程中,接收方和发送方并不会验证报文的完整性
,综上,为了解决上述问题,HTTPS 应用而生。
HTTPS的改进
HTTPS 就是身披了一层 SSL 的 HTTP,也就是 HTTP + SSL(TLS) = HTTPS
HTTPS 协议提供了三个关键的指标
加密(Encryption)
, HTTPS 通过对数据加密来使其免受窃听者对数据的监听,这就意味着当用户在浏览网站时,没有人能够监听他和网站之间的信息交换,或者跟踪用户的活动,访问记录等,从而窃取用户信息。数据一致性(Data integrity)
,数据在传输的过程中不会被窃听者所修改,用户发送的数据会完整
的传输到服务端,保证用户发的是什么,服务器接收的就是什么。身份认证(Authentication)
,是指确认对方的真实身份,也就是证明你是你
(可以比作人脸识别),它可以防止中间人攻击并建立用户信任。
对称加密
特点:加密和解密时使用的密钥都是同样的密钥
优点:加密解密的计算量小,速度快,简单易用,适合于对海量数据进行加密处理。
缺点:安全性低。这就好比《小兵张嘎》去送信(信已经被加密过),但是嘎子还拿着解密的密码,那嘎子要是在途中被鬼子发现了,那这信可就是被完全的暴露了
非对称加密
非对称加密中有两个密钥,一个是公钥,一个是私钥,公钥进行加密,私钥进行解密。公开密钥可供任何人使用,私钥只有你自己能够知道。使用公钥加密的文本只能使用私钥解密,同时,使用私钥加密的文本也可以使用公钥解密。公钥不需要具有安全性,因为公钥需要在网络间进行传输,非对称加密可以解决密钥交换
的问题。网站保管私钥,在网上任意分发公钥,你想要登录网站只要用公钥加密就行了,密文只能由私钥持有者才能解密。
优点:安全性更高
缺点:加密和解密花费时间长、速度慢,只适合对少量数据进行加密
混合加密
TLS 是使用对称加密
和非对称加密
的混合加密方式来实现机密性。
在通信刚开始的时候使用非对称算法,比如 RSA、ECDHE ,首先解决密钥交换
的问题。然后用随机数产生对称算法使用的会话密钥(session key)
,再用公钥加密
。对方拿到密文后用私钥解密
,取出会话密钥。这样,双方就实现了对称密钥的安全交换。
现在我们使用混合加密的方式实现了机密性,是不是就能够安全的传输数据了呢?还不够,在机密性的基础上还要加上
完整性
、身份认证
的特性,才能实现真正的安全。而实现完整性的主要手段是 摘要算法(Digest Algorithm)
摘要算法
如何实现完整性呢?在 TLS 中,实现完整性的手段主要是 摘要算法(Digest Algorithm)
。摘要算法你不清楚的话,MD5 你应该清楚,MD5 的全称是 Message Digest Algorithm 5
,它是属于密码哈希算法(cryptographic hash algorithm)
的一种,MD5 可用于从任意长度的字符串创建 128 位字符串值。尽管 MD5 存在不安全因素,但是仍然沿用至今。
消息摘要算法又称为散列算法,其核心在于散列函数的单向性。即通过散列函数可获得对应的散列值,但不可通过该散列值反推原始信息。这是消息摘要算法的安全性的根本所在。
其实你可以把摘要算法理解成一种特殊的压缩算法,它能够把任意长度的数据压缩
成一种固定长度的字符串,这就好像是给数据加了一把锁。我们可以通过对比生成的字符串来判断当前的数据是否完整和唯一来保证HTTPS传输数据的一致性。目前 TLS 推荐使用的是 SHA-2
。
现在我们又解决了完整性的问题,那么就只剩下一个问题了,那就是认证
,认证怎么做的呢?我们再向服务器发送数据的过程中,黑客(攻击者)有可能伪装成任何一方来窃取信息。它可以伪装成你,来向服务器发送信息,也可以伪装称为服务器,接受你发送的信息。那么怎么解决这个问题呢?
数字签名
如果用「公钥」对数据加密,用「私钥」去解密,这是「加密」; 反之用「私钥」对数据加密,用「公钥」去解密,这是「签名」。
由于所有人都持有公钥,所以「签名」并不能保证数据的安全性,因为所有人都可以用公钥去解密。 但「签名」却能用于保证消息的准确性和不可否认性。因为公钥和私钥是一一对应的,所以当一个公钥能解密某个密文时,说明这个密文一定来自于私钥持有者。
我们来看一下具体签名和验证的过程:
- 消息发送者持有 私钥 和 加密算法,称为信源;信源用私钥和加密算法对明文数据进行加密,得到密文数据,称为签体;
- 接着把明文数据和密文数据同时给到消息接收者;
- 消息接收者收到后,先取出密文数据,用公钥对密文解密,得到一份明文数据;
- 再将这份明文数据和收到的明文数据做对比,如果相同则数据完整且可信。
即使他人截获并篡改了「明文数据」,由于「私钥」是保密的,篡改者也无法生成正确的「签体」。所以签名能保证消息的准确性。 但在单独使用非对称加密的数字签名方案时,要对所有明文消息进行加密,效率很低。怎么提高效率呢?
更高效的数字签名方案: 将摘要算法和非对称加密结合使用。 如何签名:先用摘要算法计算明文数据的摘要值,再对这个摘要值用私钥加密。这样就能较快速地得到了原始信息的签名; 如何验证:先用相同的摘要算法计算原始信息的摘要值,再用公钥对签名解密,得到收到的摘要值,最后对比这两个摘要值判断是否相等。如果不相等说明数据不可信。
数字签名方案的问题: 数据接收者如何获取正确的公钥呢?如果公钥本身都被篡改了,这个签名方案就不正确了。所以需要有某种方式确保公钥的正确性,这就是数字证书。
数字证书(Certificate)
数字证书的作用: 确保数据接收者的公钥是没有被篡改过的。
数字证书通常包含以下内容: (1) 证书所有人的公钥; (2) 证书发行者对证书的数字签名; (3) 证书所用的签名算法; (4) 证书发布机构、有效期、所有者的信息等其他信息。
数字证书的验证过程需要用到 CA根证书 和 业务相关证书,根证书 是预装在操作系统中的。
在理解数字证书工作原理之前,我们需要先理解这两种证书是怎么生成的:
1. CA根证书的生成
步骤:
- 权威机构利用RSA等算法,生成一对 公钥PK1 / 私钥SK1;
- 将 公钥PK1 和 证书发布机构、有效期等信息组成一份原始的证书内容,设为 C1;
- 利用某种摘要算法,计算原始内容 C1 的数字摘要,设为 H1;
- 用第一步生成的私钥SK1,对摘要H1签名,得到签名内容S1;
- 将原始内容C1 和 签名内容S1 合在一起,就得到了证书。
- 根证书安装在操作系统中,我们认为根证书是一定正确的。
2. 业务相关证书的生成
步骤:
- 企业利用RSA等算法,生成一对 公钥PK2 / 私钥SK2;
- 将 公钥PK2 和 证书其他内容 组成原始证书内容,设为C2,给到权威机构;
- 权威机构拿到 C2 后,利用摘要算法,生成摘要信息 H2;
- 权威机构用自己的私钥SK1 (这是关键点),对摘要信息H2 签名,得到签名内容S2;
- 将 原始内容C2 和 签名内容S2 合并到一起,得到证书,交给企业。
区别点在于: 业务申请的证书,在签名时用的私钥是CA机构的私钥。这个私钥是和根证书中的公钥对应的。
3. 数字证书的真伪验证 有了根证书,我们就能校验其他证书的真伪了:
用根证书的公钥,可以验证其他证书的签名是否正确。如果签名正确,则证书是可信的、没有被篡改的。后续就可以使用这个被信任证书中包含的公钥,去验证收到的消息是否可信了。
用CA证书去证明另外一个证书是否可信,我们可以称之为 证书的递归验证。类似地,我们也可以用一个受信任的证书,去验证其他证书是否可信。
TLS握手过程
在 http 协议中,TCP三次握手成功后,浏览器会立即发送请求报文;但是https协议,它还需要另一个握手过程(TLS握手),在TCP上建立安全连接,之后才是收发报文。TLS握手的主要目的是使用非对称加密交换对称密钥,这个对称密钥是由三个随机数生成的。
1.客户端发出请求
- 支持的协议版本,比如TLS 1.0版
- 一个客户端生成的随机数,稍后用于生成"会话密钥"
- 支持的密码套件(支持的加密方法)
2.服务器回应
- 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
- 一个服务器生成的随机数,稍后用于生成"会话密钥"
- 确认使用的加密方法,比如RSA公钥加密
- 服务器证书
3.客户端回应
客户端收到服务器回应以后,开始走证书链逐级验证,确认证书的真实性,如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信:
如果证书真实有效,从证书中拿出服务器公钥,向服务器发送下面三项信息:
- 一个用服务器公钥加密随机数(pre-master key),防止被窃听
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送(Change Cipher Spec)
- 客户端握手结束通知(Finished),表示客户端的握手阶段已经结束。这一项是把之前所有发送的数据做个摘要(hash值),再加密一下,供服务器校验
上面第一项的随机数,是整个握手阶段出现的第三个随机数,又称"pre-master key"。有了它以后,客户端和服务器就同时有了三个随机数,接着双方就用事先商定的加密方法,各自生成本次会话所用的同一把"会话密钥"。
4.服务器的最后回应
服务器收到客户端的第三个随机数pre-master key之后,计算生成本次会话所用的"会话密钥"。
然后,向客户端最后发送下面信息:
- 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送(Change Cipher Spec)
- 服务端握手结束通知(Finished),表示服务端的握手阶段已经结束。这一项是把之前所有发送的数据做个摘要(hash值),再加密一下,供客户端校验
TLS握手结束后,双方开始使用对称会话密钥进行加密通信。
TLS简化版本
客户端发送支持的协议版本和支持的加密套件和客户端随机数client_random,服务端接受到以后传给浏览器一个服务端随机数server_random,并确定协议版本和加密算法,及数字证书(包含了公钥。然后浏览器对数字证书进行逐级验证,如果验证通过,则生成一个 pre_random,然后用公钥加密传给服务器,此时双方都有了三个随机数。服务器用 client_random、server_random 和 pre_random ,使用公钥加密生成会话密钥secret,然后之后的传输使用这个会话密钥 secret 作为对称加密算法的秘钥来进行数据的加解密。
HTTPS的优缺点
优点
- 使用 HTTPS 协议可认证用户和服务器,确保数据发送到正确的客户机和服务器;
- HTTPS 协议是由 SSL/TLS+HTTP 协议构建的可进行加密传输、身份认证的网络协议,要比 http 协议安全,可防止数据在传输过程中不被窃取、改变,确保数据的完整性。
- HTTPS 是现行架构下最安全的解决方案,虽然不是绝对安全,但它大幅增加了中间人攻击的成本。
- 谷歌曾在2014年8月份调整搜索引擎算法,并称“比起同等 HTTP 网站,采用 HTTPS 加密的网站在搜索结果中的排名将会更高”。
缺点
- HTTPS 协议握手阶段比较费时,会使页面的加载时间延长近 50%,增加 10% 到 20% 的耗电;
- HTTPS 连接缓存不如 HTTP 高效,会增加数据开销和功耗
- SSL 证书需要钱,功能越强大的证书费用越高,个人网站、小网站没有必要一般不会用。
- HTTPS 协议的加密范围也比较有限,在黑客攻击、拒绝服务攻击、服务器劫持等方面几乎起不到什么作用。最关键的,SSL 证书的信用链体系并不安全,特别是在某些国家可以控制 CA 根证书的情况下,中间人攻击一样可行。