协商加密密钥
在客户端与服务器进行通信时,如果不对传输内容进行加密,数据可能会在传输过程中被监听或篡改。为了保障数据的机密性和安全性,通常会使用对称加密来加密通信内容,因为对称加密的速度较快,适合大规模的数据加密。然而,对称加密需要双方共享一个加密密钥,这就带来了一个问题:如何安全地交换对称加密的密钥?
为了解决这个问题,通常会采用非对称加密。服务器会生成一对公钥和私钥,并将公钥发送给客户端。客户端使用服务器的公钥加密对称加密密钥,并将加密后的密钥发送回服务器。服务器收到加密后的密钥后,使用自己的私钥解密,从而获得对称加密的密钥。这种方式确保了密钥交换过程的安全性,即使数据在传输过程中被截获,攻击者也无法获取密钥,因为只有服务器拥有私钥可以解密。
中间人攻击
- 客户端请求公钥:假设客户端需要与服务器建立加密通信,它首先向服务器请求公钥
- 攻击者拦截公钥并伪造:在没有安全验证的情况下,攻击者可以劫持客户端与服务器之间的通信。它不仅拦截客户端请求的公钥,还伪装成服务器,将自己生成的公钥发送给客户端。
- 客户端使用伪造的公钥加密密钥:客户端收到攻击者的公钥后,误以为这是服务器的公钥,并使用它加密对称加密密钥。
- 中间人解密并获取密钥:由于攻击者拥有自己的私钥,它能够解密客户端加密的密钥,获取对称密钥。这样,攻击者就掌握了加密通信的核心密钥。
- 重新加密并转发数据:攻击者将解密后的密钥用服务器的公钥重新加密,然后转发给服务器。服务器通过自己的私钥解密,从而获得客户端的对称密钥。
- 安全通信看似无问题:此时,虽然客户端和服务器之间的通信看似正常,实际上,攻击者已经能悄无声息地解密和篡改通信内容,因为它掌握了对称加密密钥。
数字证书
在客户端与服务器的通信中,我们遇到的一个关键问题是:如何验证公钥的合法性。没有验证公钥的来源,就像《西游记》中的孙悟空和六耳猕猴,无法分辨哪个才是真的。如果我们仅凭自己接收到的公钥来加密数据,黑客就有可能伪造公钥,进行中间人攻击(MITM)。这时,“如来佛祖”的角色就是CA。
服务器需要把公钥放到受信任的第三方CA,CA根据公钥和其他信息生成数字证书,数字证书相当于把公钥和该网站绑定起来了。网站把数字证书发送给客户端,客户端看到数字证书属于受信任的CA,继续协商加密。
数字签名
不过,我们如何信任数字证书是由受信任的CA颁发的呢?这就需要数字签名。
CA首先会对公钥和网站信息进行哈希计算,生成一串较短的哈希字符,这里是为了压缩需要传输的信息,减少后续私钥签名的时间。
然后CA也生成一对公钥和私钥,然后用这个私钥对哈希字符进行加密,这就是所谓的数字签名。
然后客户端用CA签名时候生成的公钥对数字签名解密,并对数字证书进行相同的哈希运算,比对两个哈希值是否相同,判断证书是否被篡改。
中间人由于没有CA私钥,所以无法生成正确的数字签名,公钥解密的时候会不匹配,所以无法伪造证书。
看到这里肯定会有疑问,这个公钥哪里来的?万一中间人用自己的私钥进行签名,然后提供自己的公钥给客户端进行解密呢?这就不得不提信任链了。下面会说。
当然,还可以大胆提出一种猜想,假设攻击者没有CA的私钥,但能否通过“巧合”的方式篡改证书信息,使得签名仍然有效呢?具体来说,就是攻击者通过修改证书内容,生成一个新的哈希值,然后构造一个“自己的数字签名”,使得公钥解密出来的哈希值与篡改后的证书生成的哈希值一致。
然而,这种攻击依赖于哈希碰撞的存在。哈希碰撞是指不同的输入数据产生相同的哈希值,理想的哈希函数应该尽量避免这种情况。在理论上,哈希算法如MD5和SHA-1在较早的应用中曾暴露出哈希碰撞漏洞,使得攻击者能够通过精心构造碰撞来伪造有效的数字签名。然而,这种攻击在现代加密算法(例如SHA-256或SHA-3)的环境下几乎不可能发生。现代哈希算法的设计目标是保证高度的抗碰撞性,即使是通过巨大的计算资源也难以找到两个具有相同哈希值的不同输入。
因此,虽然理论上存在通过碰撞攻击篡改证书的可能性,但随着安全性不断增强的加密标准和算法的普及,这种攻击的实际发生概率已经接近于零。
信任链
我们该如何安全地拿到CA公钥?
其实CA也需要数字证书证明自己的身份,因此会把这把公钥放在自己的数字证书里面,这时候就需要另一把私钥进行数字签名,这就需要再加一层了(开始套娃)。最终到根CA。
根证书通常存储在操作系统和浏览器的信任存储中。操作系统或浏览器安装时,会预装多个受信任的根证书。这些根证书不通过网络传输,因此避免了篡改风险,并且被视为可信任的证书。浏览器或操作系统会在与网站通信时,使用这些根证书来验证服务器证书的合法性。
当客户端接收到服务器证书时,它会通过证书链逐级向上验证,直到最终追溯到根证书。客户端信任的是根证书及其签发的整个证书链,而不是单一的公钥。这样中间人想伪造CA公钥就不行了。