Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

深入理解 HTTPS #4

Open
Joey-J3 opened this issue Jan 7, 2021 · 0 comments
Open

深入理解 HTTPS #4

Joey-J3 opened this issue Jan 7, 2021 · 0 comments

Comments

@Joey-J3
Copy link
Owner

Joey-J3 commented Jan 7, 2021

HTTPS

1、加密方式

  1. 对称加密:

    通信双方加密和解密公用一个密钥,拥有密钥就可以对密文进行解密。

    优点:解密速度快

    缺点:如果通信被监听,在双方协商密钥时,密钥会被攻击者拦截到,这样加密就失去了意义。

  2. 非对称加密:

    私钥加密的密文可由公钥解密获取,而公钥加密的密文只能由私钥解密获取。在网络中,只有服务器持有它自身的私钥,公钥是公开的。所以客户端发送信息给服务器是安全的;而服务器发出的信息只要是持有公钥的都可以解密,可以被拦截破解。

    缺点:

    • 公钥并不包含服务器的信息,使用非对称加密算法无法确保服务器身份的合法性,存在中间人攻击的风险,服务器发送给客户端的公钥可能在传送过程中被中间人截获并篡改;
    • 公钥是公开的,黑客可以截获公钥对服务器发出的密文进行解密,获取其中内容;
    • 数据加密解密过程需要消耗一定时间,降低了数据传输效率;
  3. 混合加密(对称加密+非对称加密,HTTPS采用这种方式)

    在交换密钥环节使用非对称加密方式,之后的建立通信交换报文阶段则使用对称加密方式。

    具体做法是:发送密文的乙方使用对方的公钥进行加密处理“对称的密钥”,然后对方用自己的私钥解密拿到“对称的密钥”,这样就确保交换的密钥是安全的前提下(密钥协商时中间人可以截取密文,但无法破解,公钥只有客户端拥有),使用对称加密方式进行通信。

2、解决报文可能遭到篡改的问题——数字签名

虽然数据无法被解密,但可能被篡改,那么如何校验数据的完整性呢?——校验数字签名

  1. 数字签名的作用:

    • 能确定消息确实是由发送方发送的,别人无法假冒
    • 能确定消息的完整性,证明数据是否未被篡改过
  2. 数字签名如何产生

    将一段文本先用 Hash 函数生成消息摘要,然后用发送者的私钥加密生成数字签名,与原文一起传送给接收者。

  3. 校验数字签名流程

    接收者用发送者的公钥解密得到摘要信息,然后用 HASH 函数对收到的原文产生一个摘要信息,与解密得到的摘要信息对比,验证信息的完整性,如果相同,说明收到的信息没有被篡改。

3、解决通信方身份可能被伪装的问题——数字证书

如何确保客户端拿到的公钥是服务器端的?

数字证书认证机构(Certificate Authority,简称CA),客户端内置了所有受信任CA的证书。CA处于客户端与服务器双方都可信任的第三方机构的立场上,CA对服务器端的公钥数字签名后生成证书。

数字证书认证流程

数字证书认证机构的业务流程:(扩展)

  • 服务器的运营人员向第三方机构CA提交公钥、组织信息、个人信息(域名)等信息并申请认证;
  • CA通过线上、线下等多种手段验证申请者提供信息的真实性,如组织是否存在、企业是否合法,是否拥有域名的所有权等;
  • 如信息审核通过,CA会向申请者签发认证文件-证书。证书包含以下信息:申请者公钥、申请者的组织信息和个人信息、签发机构 CA的信息、有效时间、证书序列号等信息的明文,同时包含一个签名。 其中签名的产生算法:首先,使用散列函数计算公开的明文信息的信息摘要,然后,采用 CA的私钥对信息摘要进行加密,密文即签名;
  • 客户端 Client 向服务器 Server 发出请求时,Server 返回证书文件;
  • 客户端 Client 读取证书中的相关的明文信息,采用相同的散列函数计算得到信息摘要,然后,利用对应 CA的公钥解密签名数据,对比证书的信息摘要,如果一致,则可以确认证书的合法性,即服务器的公开密钥是值得信赖的。
  • 客户端还会验证证书相关的域名信息、有效时间等信息; 客户端会内置信任CA的证书信息(包含公钥),如果CA不被信任,则找不到对应 CA的证书,证书也会被判定非法。

4、SSL/TLS 协议建立流程(四次握手)

  1. 客户端发送加密通信请求「Client Hello」,发送以下内容:

    • 客户端支持的 SSL/TLS 协议版本,如 TLS 1.2 版本
    • 客户端生产的随机数(Client Random),后面用于生产会话密钥
    • 客户端支持的密码套件列表,如 RSA 加密算法
  2. 服务端收到请求后,会确认 TLS 版本号是否支持,如果浏览器不支持,则关闭加密通信;否则从密码套件列表中选择一个密码套件、生成随机数。然后发送信息给客户端:

    1. 先响应「Server Hello」消息,内容如下:
      • 确认 SSL/TLS 协议版本,如果浏览器不支持,则关闭加密通信
      • 服务器生产的随机数(Server Random),后面用于生产会话密钥
      • 确认的密码套件列表
    2. 服务端为了证明自己的身份,会发送「Server Certificate」给客户端,这个消息里含有数字证书(包含公钥和数字签名)。
    3. 随后,服务器端发送「Server Hello Done」消息,目的是告诉客户端 Server Hello 过程结束。
  3. 客户端收到响应后,首先通过浏览器或操作系统中的 CA 公钥,确认服务器的数字证书的真实性(第三点中有详细解释),如果证书没有问题(否则认为该证书是非法的),客户端会从数字证书中取出服务器的公钥、生成一个随机数(pre-master key)然后用服务器的公钥对随机数加密。然后发送信息给服务器:

    1. 发送「Change Cipher Key Exchange」给服务器,包含加密后的随机数(pre-master key
    2. 发送「Change Cipher Spec」,告诉服务器开始使用加密方式发送消息
    3. 然后,再发送「Encrypted Handshake Message」消息,把之前所有发送的数据做个摘要,再用会话密钥加密一下,让服务器做个验证,验证加密通信是否可用和之前握手信息是否被中途篡改过。

    至此,客户端和服务器都拥有了握手过程产生的三个随机数,接着就用双方协商的加密算法,各自生成本次通信的会话密钥

  4. 服务器收到客户端的第三个随机数(pre-master key)之后,使用私钥进行解密,计算出本次通信的会话密钥。然后,向发送消息给客户端,服务器也是同样的操作,发「Change Cipher Spec」和「Encrypted Handshake Message」消息,如果双方都验证加密和解密没问题,那么握手正式完成。

    整个 SSL/TLS 的握手流程全部结束,接下来,双方进入加密通信,就完全是普通的 HTTP 协议,只不过用会话密钥加密 HTTP 请求和响应。

5、DH 密钥交换

使用 RSA 密钥协商算法的最大问题是不支持向前保密,一旦第三个随机数(pre-master key)被破解,前面所有的被截获的 TLS 通讯密文也会被破解。

虽然理论上,只要服务器的公钥足够长(比如2048位),那么 pre-master key 可以保证不被破解,但是为了足够安全,可以考虑把握手阶段的算法从默认的 RSA 算法,改为 Diffie-Hellman算法(简称DH算法)。

采用 DH 算法后,pre-master key 不需要传递,双方只要交换各自的参数,就可以算出这个随机数。

DH 密钥交换

客户端和服务端各自生成随机数,并以此作为私钥,然后根据公开的 DH 计算公式算出各自的公钥,通过 TLS 握手双方交换各自的公钥,这样双方都有自己的私钥和对方的公钥,然后双方根据各自持有的材料算出一个随机数,这个随机数的值双方都是一样的,这就可以作为后续对称加密时使用的密钥。

DH 密钥交换过程中,即使第三方截获了 TLS 握手阶段传递的公钥,在不知道的私钥的情况下,也是无法计算出密钥的,而且每一次对称加密密钥都是实时生成的,实现前向保密

参考文章

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant