HTTPS加密机制
1、明文:
明文,是指没有加密的文字(或者字符串),一般人都能看懂的意思,属于密码学术语。在通信系统中它可能是比特流,如文本、位图、数字化的语音或者数字化的视频图像等。
2、密钥:
密钥是一种参数,它是在明文转换为密文或将密文转换为明文的
算法中输入的参数。密钥分为对称密钥与非对称密钥。
3、密文:
密文是加了密的的文字,明文是加密之前的文字。加密这个词有时指密文,但通常用来指加密的方法。对明文施加某种伪装或变换后的输出。也可理解为不可直接理解的字符或比特集。但可通过算法还原的被打乱的消息,与明文相对。
RSA
非对称加密,公钥加密,私钥解密,反之亦然。由于需要大数的乘幂求模等算法,运行速度慢,不易于硬件实现。
通常私钥长度有512bit,1024bit,2048bit,4096bit,长度越长,越安全,但是生成密钥越慢,加解密也越耗时。
既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密;
同理,既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。
AES
对称加密,密钥最长只有256个bit,执行速度快,易于硬件实现。由于是对称加密,密钥需要在传输前通讯双方获知。
AES的最大的问题是怎么把密钥传递给对方。RSA可以实现密钥的安全传递。
基于以上特点,通常使用RSA来首先传输AES的密钥给对方,然后再使用AES来进行加密通讯。
对称加密
对称加密算法是指在加密和解密过程中使用相同的密钥。
异或加密:要求进行异或运算的密钥与明文长度要一致的。明文有大有小,大到可以是几百兆甚至是几个G,要求密钥是同样的大小是不可能的。
**分组加密:**就是把明文切成各个大小相等的组,分别对每一组加密,最后一组可能需要填充
- 电子密码本
ECB
模式–Electronic codebook
:就是直接将明文分解为多个块,对每个块进行加密。缺点在于同样的明文块会被加密成相同的密文块;因此,它不能很好的隐藏数据模式。 - 密码分组链接
CBC
模式–Cipher-block chaining
:每个明文块先与前一个密文块进行异或后,再进行加密,主要缺点在于加密过程是串行的,无法被并行化。
- 计数器模式
CTR
模式–Counter
CTR
将块密码变为流密码。它通过递增一个加密计数器以产生连续的密钥流,其中,计数器可以是任意保证长时间不产生重复输出的函数。
缺点:无法提供密文的完整性校验。当密文在传输过程中存在丢失的情况下,是无法保证密文的完整性的。
MAC算法解决完整性校验
- 发送方使用密文与密钥通过
MAC
算法生成一个MAC
序列。然后将密文与MAC
序列值一起打包发送。 - 接收方拿到之后,将密文与密钥使用相同的
MAC
算法也生成一个MAC
序列。然后比对这两个MAC
序列是否相同。
CTR
分组工作模式加上MAC
算法就诞生了GCM
分组工作模式。
AES对称加密算法
- 常用的填充方法:
PKCS7
- 常用的分组工作模式:
GCM
AES加密数据块分组长度必须为128比特,密钥长度可以是128比特、192比特、256比特中的任意一个(如果数据块及密钥
长度不足时,会补齐)。
RSA非对称密码(密钥)
RSA加密机制:公钥用于对数据进行加密,私钥对数据进行解密,两者不可逆。公钥和私钥是同时生成的,一一对应
PKI公钥基础设施:基于私钥加密,只能使用公钥解密的原理实现身份验证的作用。
- 首先网站站长通过
RSA
算法生成一对公私钥,然后将公钥与站长的个人身份发送给Certificate Authority
数字证书认证机构 - 签名:
- 将站长的个人信息通过
hash
函数生成一个hash
值。 - 然后用
CA
机构的私钥对hash
值进行加密。 - 将加密后的内容与站长的个人信息还有网站的公钥一起打包成一个公钥数字证书。
- 验签:
- 当浏览器拿到这个公钥数字证书之后,就把该证书内容分解出两部分:站长个人信息与加密的
hash
值。 - 浏览器将站长的个人信息通过证书说明的
hash
函数生成一个hash
值。 - 然后用
CA
机构的公钥解密证书中的加密的hash
值。 - 对比两个
hash
值是否相等。
加解密大概过程
假设Android客户端拥有公钥PublicKey,服务器端拥有公钥PublicKey和私钥PrivateKey,这里的公钥和私钥
客户端要做的:
- 首先随机生成单次请求加密密钥(clientAesKey,长度为 16 位,可以用 26 个字母和数字组成),就是生成密钥
- AES负责用第一步生成的密钥将明文加密为一个密文。
- RSA利用客户端公钥PublicKey负责将第一步生成的密钥进行加密(签名验签机制)
- 客户端将密文和RSA加密后的密钥一起传输给服务端
服务端要做的:
- 解密时首先要用服务端的私钥PrivateKey,用RSA对加密的密钥进行解密(签名验签机制),拿到第一步生成的随机密钥
- 然后再用AES通过解密的密钥对密文进行解密。
- 处理密文后,将返回数据通过第一步的随机密钥,进行AES加密后,Response返回。
- 客户端收到Response的数据后,利用之前本地生成的随机密钥RandomKey直接进行AES解密即可
知乎上的摘要:https://zhuanlan.zhihu.com/p/43789231
改良的非对称加密方案,似乎可以?
我们已经理解通过一组公钥私钥,已经可以保证单个方向传输的安全性,那用两组公钥私钥,是不是就能保证双向传输都安全了?请看下面的过程:
- 某网站拥有用于非对称加密的公钥A、私钥A’;浏览器拥有用于非对称加密的公钥B、私钥B’。
- 浏览器像网站服务器请求,服务器把公钥A明文给传输浏览器。
- 浏览器把公钥B明文传输给服务器。
- 之后浏览器向服务器传输的所有东西都用公钥A加密,服务器收到后用私钥A’解密。由于只有服务器拥有这个私钥A’可以解密,所以能保证这条数据的安全。
- 服务器向浏览器传输的所有东西都用公钥B加密,浏览器收到后用私钥B’解密。同上也可以保证这条数据的安全。
的确可以!抛开这里面仍有的漏洞不谈(下文会讲),HTTPS的加密却没使用这种方案,为什么?最主要的原因是非对称加密算法非常耗时,特别是加密解密一些较大数据的时候有些力不从心,而对称加密快很多,看来必须得用对称加密,那我们能不能运用非对称加密的特性解决前面提到的对称加密的问题?
非对称加密+对称加密?
既然非对称加密耗时,非对称加密+对称加密结合可以吗?而且得尽量减少非对称加密的次数。当然是可以的,而且非对称加密、解密各只需用一次即可。
请看一下这个过程:
- 某网站拥有用于非对称加密的公钥A、私钥A’。
- 浏览器像网站服务器请求,服务器把公钥A明文给传输浏览器。
- 浏览器随机生成一个用于对称加密的密钥X,用公钥A加密后传给服务器。
- 服务器拿到后用私钥A’解密得到密钥X。
- 这样双方就都拥有密钥X了,且别人无法知道它。之后双方所有数据都用密钥X加密解密。
完美!HTTPS基本就是采用了这种方案。完美?还是有漏洞的。
中间人攻击
中间人的确无法得到浏览器生成的密钥B,这个密钥本身被公钥A加密了,只有服务器才有私钥A’解开拿到它呀!然而中间人却完全不需要拿到密钥A’就能干坏事了。请看:
- 某网站拥有用于非对称加密的公钥A、私钥A’。
- 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
- 中间人劫持到公钥A,保存下来,把数据包中的公钥A替换成自己伪造的公钥B(它当然也拥有公钥B对应的私钥B’)。
- 浏览器随机生成一个用于对称加密的密钥X,用公钥B(浏览器不知道公钥被替换了)加密后传给服务器。
- 中间人劫持后用私钥B’解密得到密钥X,再用公钥A加密后传给服务器。
- 服务器拿到后用私钥A’解密得到密钥X。
这样在双方都不会发现异常的情况下,中间人得到了密钥X。根本原因是浏览器无法确认自己收到的公钥是不是网站自己的。那么下一步就是解决下面这个问题:
数字证书
网站在使用HTTPS前,需要向“CA机构”申请颁发一份数字证书,数字证书里有证书持有者、证书持有者的公钥等信息,服务器把证书传输给浏览器,浏览器从证书里取公钥就行了,证书就如身份证一样,可以证明“该公钥对应该网站”。然而这里又有一个显而易见的问题了,证书本身的传输过程中,如何防止被篡改?即**如何证明证书本身的真实性?**身份证有一些防伪技术,数字证书怎么防伪呢?解决这个问题我们就基本接近胜利了
数字签名制作过程(上图)
数字签名的制作过程:
- CA拥有非对称加密的私钥和公钥。
- CA对证书明文信息进行hash。
- 对hash后的值用私钥加密,得到数字签名。
明文和数字签名共同组成了数字证书,这样一份数字证书就可以颁发给网站了。
那浏览器拿到服务器传来的数字证书后,如何验证它是不是真的?(有没有被篡改、掉包)
浏览器验证过程:
- 拿到证书,得到明文T,数字签名S。
- 用CA机构的公钥对S解密(由于是浏览器信任的机构,所以浏览器保有它的公钥。详情见下文),得到S’。
- 用证书里说明的hash算法对明文T进行hash得到T’。
- 比较T是否等于T’,等于则表明证书可信。
总结:公钥加密、私钥解密、私钥签名、公钥验签。
TLS1.2
中经常使用的一个安全套件是:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
具体说明一下:
- ECDHE:密钥交换算法
- RSA:身份验证算法
- AES:对称加密的算法
- 128:对称加密的密钥长度
- GCM:对称加密的工作模式
- SHA256:hash算法