公钥 私钥 证书 HTTPS那些事儿

来源:互联网 发布:mac口红持久吗 编辑:程序博客网 时间:2024/06/16 11:49

加密方式

如今流行的加密主要分为对称加密和不对称加密两种.

对称加密

对称加密指的是通信双方加密解密使用事先约定好的同一个密钥.常用的算法有AES,DES等.
其优点是加密解密速度快,运算开销低.

但缺点也很明显,安全的将这个密钥传输到另一方的手中可能会是一个很困难的事情.在不安全的环境中,有可能是一件高风险的事情.事实上,密钥一旦暴露,整个加密系统也就随之失效.

不对称加密

由于对称加密的这个缺点,密码学专家又研究了不对称加密.

公钥 私钥

通信双方各持有一个密钥对,每一个密钥对由公钥和私钥组成.公钥是可以被公开的,你可以任意的将它放在网络上供别人下载.而私钥则是绝对不能公开的,必须妥善保存在一个安全的位置.

它们具有以下重要的性质:

  • 公钥即身份.这个结论对于理解后续证书的意义有非常大的帮助.你出示了A的公钥,就相当于你拥有了A的身份.别人想要冒充A是无意义的,因为你没有A的私钥,解不开任何用A的公钥加密过的信息.
  • 私钥可以导出公钥,但是反之则不行.
  • 公钥加密过的东西,可以用对应的私钥解开.私钥加密过的东西,可以用对应的公钥解开.

结合以上几点,不难知道,每一次通信的流程通常如下所示:

  • 通信双方AB互换公钥.由于公钥本身是可以公开的信息,因此即使在不安全的网络环境中,这套系统也可以工作.
  • A -> B传输时,A将消息用B的公钥加密得到密文.
  • A将密文发送给B.
  • B收到密文后,用自己的私钥解密,获取A发送的消息.

这个过程看似很完美,但存在着一个漏洞.我在前面写了,公钥即身份,问题是,有的时候很难验证这个公钥对应的身份.这也就引出了后面的中间人攻击以及CA签发证书.

签名

签名意为对某些东西的承诺.

纸质签名时,你在合同上签名了,意为你认同了这个合同上的全部条款.但这避免不了两个问题,

  • 一是签名可以伪造.在几十年前,有个著名的伪造签名的大师叫Frank William Abagnale,那时候银行的鉴别技术还不成熟,于是他靠着伪造支票签名空手套现百万美金.
  • 二是内容有被修改的风险.这也就是为何很多文件上会特地标有INTENTIONALLY LEFT BLANK字样: 防止别有用心的人私自添加东西.

现在有了密钥对,数字签名就变得简单了.前文中说公私钥性质的时候,有提到过私钥加密的东西,公钥可以解开.那么现在首先对原文M计算出其摘要H,再用私钥对其进行加密,并附在原文最后.那么就确保了两个事情:

  • 承诺,也即不可抵赖.公钥属于公开信息,假设A在原文后做了签名,即意味着A对原文中的内容作出了承诺.任何一个人都可以拿到A的公钥并解开签名获得摘要,并和原文摘要对比,也就知道了A对原文作出了承诺.同时,签名在上面,A是无法抵赖的.
  • 抗篡改.签名背后就是信息摘要.原文一旦被篡改,摘要随即变化,签名里的摘要也就对不上了.

该用什么密钥加密?

  • 我想和证书持有人通信的时候, 目的是通信内容只有他一个人能解开, 因此用公钥加密, 除了他谁也解不开.
  • 我想对某份文件作签名的时候, 别人应该都可以验证这个签名, 并且, 除了我以外谁也没法冒充我, 因此用私钥加密.

证书

前文中,我们提到了一个观点,叫做公钥即身份.回到之前提到的一个问题,就是如何去校验这个身份.因此,我们引入了证书这个概念.证书为了实现身份验证的功能,根据前面公钥即身份的概念,它会包含一个公钥.此外,还包含这个身份持有者的一些描述,一般包括:公司组织的相关信息,证书的有效期,签发组织机构,摘要使用的算法等,此外,还有一个最关键的,就是签名.签名者对这份证书在这段时间内的有效性做出了承诺.

那么是谁来签名呢?假设,有一家公司C,我完全可以用openssl生成100个公私钥对,填上完全一样的信息,用私钥在每张证书上都做签名,这样可以做出一百张都看起来像是公司C的证书.这样肯定是行不通的,必须引入一个权威的第三方证书签发机构,这样的机构称为CA.这样做有以下两点好处:

  • CA在签发证书的过程中会对机构进行审核,确保这个身份的真实性.同时,CA为了保护其公信力,不会乱签发证书.
  • CA的证书通常都预装在设备里.收到一个声称是CA签发的证书时,只要找出证书的签发机构,去CA证书里找出公钥解密签名比对摘要,即可验证证书的真实性.

HTTPS

HTTPS是在传统的HTTP协议之下,TCP协议之上,插入了一个TLS/SSL协议。相比于HTTP,其主要特性在于,通信内容全部加密,这就使得第三方无法窃听你们的通信内容.

证书握手之单向验证

在开始加密通信之前, 需要有一个步骤来完成对服务端证书的获取和校验过程,这个过程称为证书握手.以浏览器为例, 这个证书握手的过程通常如下:

  • 浏览器向服务器发起证书请求,同时附上一个随机数A.此过程为明文传输.
  • 服务器向浏览器返回证书,并附带随机数B.此过程同样为明文传输.
  • 浏览器收到证书之后,利用本地的CA根证书检查该证书合法性. 确认无误之后,返回一个新的随机数C. 此消息用服务器证书公钥加密.

至此,一个单向验证的证书握手就完成了.之所以是单向验证,是只需要浏览器验证服务器证书,而服务器无需验证浏览器证书.为每一个浏览器配发一个证书和私钥成本太高,很多时候也没有必要关心浏览器的身份.

既然浏览器端没有证书和私钥,那加密是怎么实现的呢? 答案是对称加密.这个对称加密的密钥,是通过A B C三个随机数,用商定好的算法生成的(证书握手的前两步中包含了商定加密算法的内容). A B为明文传输,而C是密文传输,因此即使旁人监听到A 和B,仍然无法获得C,因为没有服务器的私钥就解不开这个密文, 因此整个随机数是安全的,从而保证对称密钥是无法窃听的并且难以破解的.

这里可以发现,只有C是整个密钥算法的核心,为什么不直接用C生成密钥呢? 答案是浏览器(客户端)的随机算法不一定可靠, 如果浏览器端随机数随机性太差,随机数被猜到的可能性就大大增加. 因此需要引入服务端的随机数,为整个随机数再增加一层不确定性,保证密钥难以被破解或猜测.

中间人攻击

整个HTTPS流程并没有太多的问题,唯一的可能的威胁就是中间人攻击.中间人攻击有两个重要的条件:

  • 浏览器端忽略证书错误,包括域名,IP,有效时间等
  • 服务器无需浏览器身份验证,即单向验证.

在满足以上两个前提的情况下,一次中间人攻击的流程如下所示:

  • 浏览器向服务器发起证书握手请求,被中间人H截获.
  • H伪装成浏览器,向服务器发起请求. 同时,又伪装成服务器,向浏览器返回H的证书.
  • 浏览器检测到证书不对,但错误被忽略.因而继续同H这个伪装的服务器完成证书握手.
  • 同时,H伪装成浏览器,和服务器完成证书握手.因为H无需出示身份,因此这一步也没有问题.

至此,浏览器发送给服务器的加密报文实际上是发送给了H,H再转发给服务器,整个通信内容就完全暴露在H的监控之下.

再回来看看之前的前提,为什么这两个条件缺一不可.

  • 忽略证书错误:

    • H是不可能向浏览器的出示服务器自己证书的,虽然这个证书是公开信息,但H没有服务器的私钥,握手的第三步是没法解密随机数的.
    • H证书如果是CA买的,那么信息核对必然无法通过(公司 域名等)
    • H证书如果是自签名的,就更不可能通过了.
  • 服务端单向验证: 如果需要校验浏览器身份, H同样无法伪造, 原理同上类似.

双向验证

因为有中间人攻击的存在,就引入了双向验证的机制.整体流程与单向验证类似,加入了浏览器端证书,彻底杜绝了中间人的存在.

原创粉丝点击