重温梳理了一下计网方面的知识,感觉就像是两国元首如何进行会晤沟通一样,挺有趣,先抽一个安全方面的Https来进行一下首脑之间如何讲悄悄话。

加密算法简介

正文开始之前,我先来解释简单的解释下对称加密和非对称加密。

对称加密采用对称密码编码技术,也就是编码和解码采用相同描述字符,即加密和解密使用相同的密钥,实现这种加密技术的算法称对称加密算法。对称加密使用简单,密钥较短,加密和解密过程较快,耗时短,常见的对称加密算法有DES,3DES,lDEA,AES,RC4等。

非对称加密与对称加密不同,其加密算法需要两个密钥:公开密钥(publickey)和私有密钥(private),两者是一对的。如果用公钥加密,只能用私钥才能解密。非对称加密保密性好,但加密和解密花费的时间较长,不适合对大文件加密而只适合对少量的数据加密。常见的非对称加密算法有RSA,ECC,DSA(数字签名)等。

Hash算法是一种单向算法,通过Hash算法可以对目标数据生成一段特定长度、唯一的hash值,但是不能通过这个hash值重新计算出原始的数据,因此也称之为摘要算法,经常被用在不需要数据还原的密码加密以及数据完整性校验上,常用的算法有MD2,MD4,MD5,SHA等。

https

为了保证这些隐私数据能加密传输,于是网景公司设计了SSL(Secure Sockets Layer)协议用于对HTTP协议传输的数据进行加密,从而就诞生了HTTPS。SSL目前的版本是3.0,被IETF(Internet Engineering Task Force)定义在RFC 6101中,之后IETF对SSL 3.0进行了升级,于是出现了TLS(Transport Layer Security) 1.0,定义在RFC 2246。实际上我们现在的HTTPS都是用的TLS协议,但是由于SSL出现的时间比较早,并且依旧被现在浏览器所支持,因此SSL依然是HTTPS的代名词,但无论是TLS还是SSL都是上个世纪的事情,SSL最后一个版本是3.0,今后TLS将会继承SSL优良血统继续为我们进行加密服务。

验证流程

简明流程


上面这张图片已经清楚的展示了HTTPS工作的流程。

  1. [Server]生成一对密钥:公钥和私钥,我们称之为“KeyPub”,“KeyPri”
  2. [Server]服务端将公钥(KeyPub)发送到客户端
  3. [Client]生成一个对称密钥(姑且称之为key2),然后用key2加密数据。
  4. [Client]使用公钥(KeyPub)加密key2.这时,key2是安全的,因为只有服务度有私钥KeyPri
  5. [Client]发送用key2加密后的信息及用KeyPub加密过的key2到服务端
  6. [Server]服务端使用KeyPri解密得到加密过的key2,得到真正的key2
  7. [Server]使用key2解密消息正文。这样,数据就被安全的传输到了服务端。
    (上教程未说明证书的作用)

流程(含证书)


注:文中所写的序号与图不对应但流程是对应的

  1. 客户端发起一个https的请求,把自身支持的一系列Cipher Suite(密钥算法套件,简称Cipher)发送给服务端

  2. 服务端,接收到客户端所有的Cipher后与自身支持的对比,如果不支持则连接断开,反之则会从中选出一种加密算法和HASH算法

    以证书的形式返回给客户端 证书中还包含了 公钥 颁证机构 网址 失效日期等等。

  3. 客户端收到服务端响应后会做以下几件事

  • 验证证书的合法性(如何验证参考下文的数字证书部分)
    颁发证书的机构是否合法与是否过期,证书中包含的网站地址是否与正在访问的地址一致等

  • 生成随机密码
    如果证书验证通过,或者用户接受了不授信的证书,此时浏览器会生成一串随机数,然后用证书中的公钥加密。

  • HASH握手信息
    用最开始约定好的HASH方式,把握手消息取HASH值, 然后用 随机数加密 “握手消息+握手消息HASH值(签名)” 并一起发送给服务端
    在这里之所以要取握手消息的HASH值,主要是把握手消息做一个签名,用于验证握手消息在传输过程中没有被篡改过

  1. 服务端拿到客户端传来的密文,用自己的私钥来解密握手消息取出随机数密码,再用随机数密码 解密 握手消息与HASH值,并与传过来的HASH值做对比确认是否一致。

    然后用随机密码加密一段握手消息(握手消息+握手消息的HASH值 )给客户端

  2. 客户端用随机数解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密

    因为这串密钥只有客户端和服务端知道,所以即使中间请求被拦截也是没法解密数据的,以此保证了通信的安全

为何需要如此复杂

主要是因为非对称加密的性能比对称加密的性能差。可参考如下文章
http://blog.csdn.net/dd864140130/article/details/52598107

数字证书

由Certificate Authority机构发放。

我们将自己生成的CSR提交给签名商,他们用中级证书机构的私钥Private Key给我们的签名成证书。而他们的的证书又是通过Root CA颁发的(即Root CA通过它的私钥对中级机构提交的CSR进行了签名)。

证书组成

  1. 证书内容(Certificate):
    证书所有人公钥(Subject’s Public Key Info)、
    签发机构(Issuer)、
    标识名 (Distinguished Name) 等

  2. 加密算法(Certificate Signature Algorithm):
    包含hash算法和非对称算法两个算法,一般为SHA1和REA

  3. 数字签名(Certificate Signature Value):
    Certificate —> hash1 —签发机构签名—> 数字签名
    由hash算法对证书内容进行加密得到hash1,再使用签发此证书机构的私匙对hash1进行加密得到数字签名。
    (需要使用机构的公匙才可以进行解密)
    注意:此处是签发此证书的CA机构的私匙

证书链

一般现在有 根证书、中间证书、个人证书。事实会存在层数不同的证书。是父子关系。

  1. 根证书
    签发机构就是本身,windows自带有一部分根证书,这部分证书对于系统来说就是可信的证书。

证书验证过程

简单来说,通过hash算法对证书内容取得hash1值,再通过公匙对证书中的数字签名进行解密获得hash2值(为何hash2?参考数字签名组成),若hash1与hash2相符,则认为此证书可信。

签名验证说明

问题出现于hash2的解密公匙来于何处
此公匙即此证书的上级证书的证书内容中的所有者公匙。

在获得父证书并取得其公匙的过程中,需要验证父证书是否可信,此时若父证书不是根证书则需要继续获得父证书的上一级证书来验证父证书是否可信。若父证书为根证书,则可信,则可用其公匙进行验证。
(通过此规则,我们平时手动添加根证书是不安全的做法,根证书并的机构并不多,Android已经把将近150个CA根证书(数字证书认证机构认证过的证书)内置在我们手机中。)

多级验证过程

画图版

附:证书有多种格式

  • x.509
    x.509证书通常用于包含一个公钥

  • PKCS12
    PKCS12证书通常用来包含一个私钥。因此,PKCS12需要密码才能打开。

参考链接

http://www.cnblogs.com/zery/p/5164795.html

http://www.cnblogs.com/hyddd/archive/2009/01/07/1371292.html

http://lukejin.iteye.com/blog/587200
google,W3c要推进的内容加密协议ontent Security Policy Level 2 is a Candidate Recommendation.,https://developers.google.com/web/fundamentals/security/csp/