假如客户端要登录,将用户名和密码传到服务器
如果使用 HTTP,会有什么问题
HTTP 是明文传输,有以下问题
窃听风险:第三方可以获知通信内容(需要加密)
篡改风险:第三方可以修改通信内容(需要校验)
冒充风险:第三方可以冒充他人身份参与通信(需要信任——证书)
那我可以在客户端先加密,这样就不是明文传输了呀
你这种属于对称加密,如果你的密钥是在通信过程中传输,那可能被截获,这样你的信息就泄漏了
那服务器和客户端事先约定好密钥,而不是在通信时才传输,这样就不会泄漏了
可以的,但是实际上这样做会很麻烦
那你有什么更好的方法吗
使用非对称加密,服务器维护公钥和密钥,通信时,客户端先向服务器端索要公钥,然后用公钥加密信息再传输,服务器收到密文后,用自己的私钥解密
这里的公钥和私钥是什么
公开秘钥:简称公钥;私人秘钥:简称私钥
非对称加密的特点就是:
- 私钥加密后的密文,所有公钥都可以解密(比如数字证书的生成)
- 公钥加密后的密文,只有私钥可以解密(比如服务器和客户端的加密流程)
- 私钥只有一个人有,而公钥可以发给所有的人
那看起来很完美了呀
其实这样还有一个安全问题
非对称加密还存在什么安全问题
如果第三方拦截住了客户端的公钥请求,然后模仿了服务器的行为,传输给你他自己的公钥
同时,第三方也模拟了客户端向服务器发送公钥请求,得到了服务器的公钥
接着客户端就会把攻击者当做服务器,用假公钥把信息加密传给第三方,第三方再使用自己的私钥解密得到信息
同时,第三方得到了信息之后,模拟客户端使用服务器的公钥进行加密,再传给服务器
这个就是所谓的“中间人攻击”,通过这样的手段,便可以获取客户端和服务器之间通信的所有内容。
那有什么方法防止中间人攻击吗
有,使用CA(数字证书认证机构)颁发的数字证书
证书就是服务器将信息(公钥、姓名、邮件等)提供给 CA,CA 把信息写到证书里,再用自己的私钥对这些信息进行加密形成证书的签名,再返回给服务器
简单理解:证书 = CA 私钥对服务器公钥的加密结果
现在服务器不再返回公钥给客户端,而是返回证书
客户端收到证书之后,只需要用 CA 的公钥解密证书的签名得到加密之前的散列值,再计算数字证书中信息(公钥、姓名、邮件等)的散列值,将两者进行对比,只要散列值一致,就证明这张证书没有被篡改过
这个中间人攻击看起来很像 Charles/WireShark 的抓包
没错,抓包软件的原理就是中间人攻击,怪不得每次得信任证书是,只要客户端信任了 Charles 的证书,客户端就会把 Charles 当成服务器,Charles 变成了中间人,因此可以监听 HTTPS 的内容
那客户端怎么得到正确的 CA 的公钥呢
简单点说,操作系统和浏览器在设备出厂的时候就会内置很多根证书
非对称加密计算量太大,如何减少耗用的时间?
客户端得到正确的公钥之后,就可以使用对称加密来传播信息
客户端生成一个“会话密钥”,使用服务器的公钥对该密钥进行加密,将密钥密文传递给服务器。
服务器使用自己的密钥对密钥密文进行解密得到客户端密钥
接下来双方利用会话密钥,来实现对称加密的通信
每一次对话,客户端和服务器端都生成一个”会话密钥”(session key),用它来加密信息。由于”会话密钥”是对称加密,所以运算速度非常快,而服务器公钥只用于加密”会话密钥”本身,这样就减少了加密运算的消耗时间
HTTPS 整个工作流程
HTTPS 主要分为两个过程:
握手阶段:客户端向服务器端索要公钥;并协商 “会话密钥”
通信阶段:双方采用 “会话密钥” 进行加密通信
其中握手阶段的流程图如下:
我们看看整个流程:
- 客户端生成一个随机数 RNc(即 Random Number of Client)并发送给服务器【Client-Hello 阶段】
- 服务器收到后生成 RNs(即 Random Number Of Server),并把 RNs 和证书(含公钥)返回给客户端【Server-Hello 阶段】
- 客户端校验证书提取公钥并验证;生成 PMS(即 Pre Master Secret),使用公钥加密发送给服务器
- 服务器使用私钥进行解密得到 PMS
- 客户端和服务器都使用 RNc、RNs 和 PMS 生成会话密钥,接下来使用会话密钥对通信内容进行对称加密
为什么要使用三个随机数
不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于 SSL 协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。
对于 RSA 密钥交换算法来说,pre-master-secret 本身就是一个随机数,再加上 hello 消息中的两个随机数,三个随机数通过一个密钥导出器最终导出一个对称密钥。
pre-master-secret 的存在在于 SSL 协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么 pre-master-secret 就有可能被猜出来,那么仅适用 pre-master-secret 作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上 pre-master-secret 三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了
关于安全信任
- 双方通信内容的安全性是靠公钥加密、私钥解密来保证的,这一安全性由非对称加密的特性,即由公钥加密的信息只能使用对应的私钥才能解开来保证。由于私钥不会传递,只有拥有者知道,所以安全性就由公钥的正确性来保证
- 公钥由对方在通信初始所提供,但是这时很容易被中间人替换掉,为了保证公钥的正确性,所以在发送公钥的时候也会提供对应的数字证书,用于验证这个公钥是对方的而不是中间人的。那么安全性就是由数字证书的正确性来保证了
- 数字证书是由上级 CA 签发给个人 / 组织的,上级 CA 用自己的私钥给个人证书进行签名,保证证书中的公钥不被篡改,而接受者需要用上级 CA 证书中的公钥来解密个人数字证书中的数字签名来验证证书中的公钥是否是正确的。那么安全性就是由上级 CA 证书的正确性保证的了
- 但是,上级 CA 证书也是由其上级 CA 签发的,这种信任关系一直到根证书。根证书没有上级 CA 为其签名,而是自签名的,也就是说,它自身为自身签名,保证正确性。所以根证书就是这个信任链最重要的部分。如果根证书泄露的话,其签名的所有证书及使用其签名的证书所签名的证书的安全性将不复存在。现在,安全性就是靠系统根证书的私钥不被泄露或者其公钥不被篡改来保证的了
- 根证书不应该通过网络分发,因为通过网络分发的话,可能会被中间人攻击。一般根证书都通过操作系统或者浏览器分发,在操作系统中会内置很多根证书,但是最初的操作系统也不能通过网络分发,因为中间人可以修改操作系统中的根证书。所以要保证安全只能靠最原始的方法,当面交流。硬件厂商会和证书签发机构合作,在电脑、手机等设备出厂的时候在其操作系统中内置签发机构的根证书,再将这些设备分发出去,这样,这些设备的用户就可以安全地进行信息交换了。所以,安全性就依赖于这些设备在分发到消费者手中之前不会被恶意修改来保证了
关于完整性校验
HTTPS 通过证书解决了冒充风险,通过加密解决了窃听风险,那么篡改风险如何规避呢?
当握手阶段结束后,双方进入数据通信阶段。在这个阶段:
- 发送方会使用协商出来的“会话密钥”对原始消息进行加密,形成密文;同时也会使用哈希算法对原始消息进行计算,形成消息摘要;并将消息摘要和密文同时发送出去
- 接收方会使用“会话密钥”对密文进行解密,得到原始消息,然后对原始消息使用同样的哈希算法进行计算,将得到的值与消息摘要比较,以此判断是否被篡改过
哈希算法是不可逆的,可以把任意长度的输入,通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射。无论多长的消息都被映射成长度固定的散列值,因此消息长短不会影响完整性校验的性能
More
对称加密:客户端用密钥将对信息进行加密,服务器用同一把密钥将对信息进行解密
发送方和接收方如何共享相同的密钥比较麻烦。一种方法是通过事先协商好而不是通过通信进行协商,避免被监听和截获;另一种是通过非对称加密通道进行对称加密的密钥的传输
对称加密的密钥是一对一的,若服务器要跟多个客户端通信则需要维护多对密钥
非对称加密:公钥和私钥;客户端先向服务器端索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密
不存在密钥分发的问题,解码方可以自己生成密钥对,一个做私钥存起来,另外一个作为公钥进行发布
解决了密钥管理的复杂度问题,多个加密方都可以使用一个已知的公钥进行加密,但只有拥有私钥的一方才能解密
缺点是比对称加密慢
常见算法
- 常见的对称加密算法:DES、AES、RC2、RC4
- 常见的非对称加密算法:RSA、DSA
- 常见的完整性校验算法:MD5、SHA1、SHA256