Bootstrap

浅谈网络 | 应用层之HTTPS协议

使用 HTTP 协议浏览新闻虽然问题不大,但在更敏感的场景中,例如支付或其他涉及隐私的数据传输,就会面临巨大的安全风险。如果仍然使用普通的 HTTP 协议,数据在网络传输中极易被黑客截获和篡改。

举个例子,当你发送一个请求说要点外卖时,这个请求可能会被黑客截获。黑客可以冒充外卖平台伪装成服务器,提前给你发送一条虚假的消息,比如:“请提供银行卡号和密码。”如果你不加防范,真的把银行卡信息发给了黑客,那么很可能损失惨重。

解决这种安全问题的通用方法就是 加密。加密通常分为两种方式:对称加密非对称加密

对称加密 是一种简单高效的加密方式。加密和解密使用相同的密钥。也就是说,发送方和接收方共享同一个密钥来对数据进行加解密。为了确保数据安全,密钥必须保密,只有通信双方知道,不能泄露给其他人。

非对称加密 则更为复杂,使用的是成对的密钥:一个是公开的 公钥,另一个是私密的 私钥。非对称加密的特点是:

  • 用公钥加密的数据只能由私钥解密。
  • 用私钥加密的数据只能由公钥解密。

这种机制提供了更高的安全性,尤其是在初次建立通信时。例如,服务器可以使用私钥加密一条消息,客户端通过服务器的公钥解密后,可以确认消息确实来自该服务器,避免受到冒充攻击。

然而,对称加密 在性能上要远高于 非对称加密,因此,在实际的通信中,通常将两者结合使用。具体流程是:

  1. 在通信开始时,使用非对称加密交换对称加密的密钥。
  2. 接下来的数据传输使用对称加密,以提高效率。

这种组合方式既能保证安全性,又能兼顾性能,是现代网络中加密通信的主流方案。例如,HTTPS 协议就是在 HTTP 的基础上通过 SSL/TLS 加入加密机制,既确保了数据安全,又避免了性能损耗过高的问题。

对称加密

对称加密的安全性问题

假设你和外卖网站事先约定了一个密钥,使用该密钥进行数据加密和解密。这样,即便中间的黑客截获了通信内容,由于没有密钥,他们也无法破解数据。

看起来这一方法无懈可击,但问题在于:你们两个怎么安全地共享这个密钥呢?如果密钥通过互联网传输,它可能会被黑客截获。一旦黑客得到密钥,就能冒充你和外卖网站之间的通信者,窃取敏感信息,比如银行卡账号和密码。

这种情形类似于谍战剧中的情节,特工破译密码后,通过密码本破解无线电台的加密信息。关键问题在于,如何安全地传递这个密码本?这个问题只能通过线下接头来解决。

比如,你和外卖网站可能会约定一个见面地点,亲自交给你一个写有密钥的纸条,双方还可能约定一个口号,例如“天王盖地虎”,以确保纸条不被篡改。然而,问题在于,口号本身就成了新的密钥。那么,如何确保口号的安全性呢?这种一对一的接头方式,在特工世界中或许可行,但在互联网应用中,面对成千上万的用户,显然不可行。

非对称加密

对称加密虽然能保证信息的安全,但由于密钥需要在发送方和接收方之间共享,这就引发了一个安全问题——如何安全地交换密钥。这个问题使得对称加密无法彻底解决通信中的安全问题,直到非对称加密的出现。

在非对称加密中,外卖网站将私钥保留在自己的系统中,这个私钥永远不会在互联网上传输,保证了其安全性。而与私钥配对的公钥可以公开传播,外卖网站只需将公钥提供给你,你就可以开始安全地通信。

例如,你用外卖网站的公钥加密信息:“我要定外卖”,即使黑客截获了这个信息,由于没有私钥,黑客也无法解密。因此,信息能够安全地传送到外卖网站,外卖网站使用自己的私钥解密后,可以回复你:“请提供银行卡和支付密码。”

然而,这个方法仍然有一些安全隐患。问题在于,外卖网站的回复同样是通过私钥加密的,任何人(包括黑客)都可以解密。这就意味着,黑客可以窃听到“银行卡和支付密码”的请求。

那么,外卖网站能否用自己的公钥来加密信息呢?答案是否定的。因为只有外卖网站的私钥才能解密它自己加密的信息,公钥是公开的,任何人都能解密。

更复杂的是,黑客也能拥有外卖网站的公钥,模拟发送“我要定外卖”的请求。这就意味着,即使黑客截获了你的请求,它也能用外卖网站的公钥加密,伪造一个看似合法的消息。

为了解决这些问题,仅仅依赖外卖网站的一对公钥和私钥是远远不够的。客户端也需要拥有一对公钥和私钥,并将自己的公钥提供给外卖网站。这样,当你向外卖网站发送请求时,使用外卖网站的公钥加密,而当外卖网站回复你时,它则使用你的公钥加密。

通过这种方式,即使黑客截获了通信内容,它也无法解密,因为没有私钥。这保证了通信双方的隐私和安全。、

数字证书

在非对称加密中,公钥的传输仍然面临一个重要问题:如何确保你收到的公钥是真正的外卖网站公钥?常见的传输方式包括:

  1. 将公钥放在公开的地址,供用户下载。
  2. 在建立连接时,直接传送公钥。

但无论哪种方式,作为普通用户,你如何确保收到的公钥是正确的?如果黑客冒充外卖网站,发送给你一个伪造的公钥,那么你们之间的通信看似没有问题,实际上却已被黑客窃听。

举个例子,假设我搭建了一个网站 cliu8site,首先可以通过以下命令生成私钥:

openssl genrsa -out cliu8siteprivate.key 1024

接着,从私钥生成对应的公钥:

openssl rsa -in cliu8siteprivate.key -pubout -out cliu8sitepublic.pem

在这种情况下,任何人都可以通过类似的命令生成自己的公钥和私钥,并提供给你。那么,如何证明公钥确实来自外卖网站呢?这就需要权威机构的介入,类似于身份证的作用。虽然每个人都可以自己生成公钥,但只有经过权威机构认证的公钥才是可信的。

证书的作用与生成过程
数字证书可以理解为“带有公钥的身份证”,它包含了以下关键信息:

公钥:外卖网站的公钥。
证书所有者:如外卖网站的名称和身份信息。
证书的发布机构:证书颁发机构(CA)的信息。
证书的有效期:证书的有效日期。
数字证书是由一个可信的第三方——证书颁发机构(CA)颁发的。为了获得证书,外卖网站需要向CA提交证书请求,并通过CA的审核。

生成证书请求的命令如下:

openssl req -key cliu8siteprivate.key -new -out cliu8sitecertificate.req

接着,将证书请求发送给CA,CA使用自己的私钥对请求进行签名。签名的过程是利用CA的私钥对信息进行加密,确保只有CA能够生成正确的签名。
CA证书签名过程
CA使用其私钥对证书请求进行签名。证书的签名保证了公钥的真实性,类似于公安局给身份证盖章。

签名的命令如下:

openssl x509 -req -in cliu8sitecertificate.req -CA cacertificate.pem -CAkey caprivate.key -out cliu8sitecertificate.pem

成功执行后,返回 Signature ok,证书就生成好了。

此时,cliu8sitecertificate.pem 就是签过名的证书,CA使用它的私钥给外卖网站的公钥签名,相当于为外卖网站背书。

查看证书内容
可以使用以下命令查看证书的详细内容:

openssl x509 -in cliu8sitecertificate.pem -noout -text

证书的内容包括:

Issuer:证书颁发机构。
Subject:证书的所有者。
Validity:证书的有效期。
Public-key:公钥。
Signature Algorithm:签名算法。

验证证书
通过获取证书后,用户不直接使用公钥,而是先获取该证书的签名,并用CA的公钥进行解密。如果成功解密并且哈希值一致,说明该公钥是真实有效的。

不过,这里还有一个新问题:如何确保CA的公钥是可靠的?如果我们不信任某个CA的公钥,该如何验证?

为了解决这个问题,CA的公钥同样需要被其他更权威的CA签名。通过层层授信,最终形成信任链,保证了每个证书的可靠性。

根证书与信任链
最终,所有的CA证书都会链式验证,从最顶层的根证书(root CA)开始,一直到最终的证书。这种方式类似于在政府认证机构的层层背书,确保了整个证书体系的安全性。

根证书通常由全球知名的几个CA(如VeriSign、Symantec等)进行背书,这些被称为“根CA”。

自签名证书
除了由CA签名的证书外,还有一种证书称为自签名证书(Self-Signed Certificate)。这类证书并不经过CA签名,通常用于非公开环境,或是“我就是我,你信不信”的场合。

虽然自签名证书能够提供加密保护,但它缺乏CA背书的可靠性,不适合在公开互联网上使用。

HTTPS 的工作模式

我们知道,非对称加密在性能上不如对称加密。那么,是否可以将两者结合起来呢?答案是肯定的。实际上,公钥和私钥主要用于传输对称加密的秘钥,而实际的大数据量通信则使用对称加密。
在这里插入图片描述

这就是 HTTPS 协议的总体思路。当你登录一个外卖网站时,使用 HTTPS 协议时,客户端和服务器会进行一系列的加密握手,确保安全通信。以下是 HTTPS 握手的过程:

  1. 客户端发起请求

客户端发送 Client Hello 消息到服务器,消息内容包括:

  • 明文传输的 TLS 版本信息。
  • 加密套件候选列表(支持的加密算法)。
  • 压缩算法候选列表(支持的数据压缩方法)。
  • 一个随机数,用于后续的密钥协商。

这一步类似于客户端说:“您好,我想定外卖,但你要保密我吃的是什么。这是我的加密套路,再给你个随机数,你留着。”

  1. 服务器响应

服务器返回 Server Hello 消息,内容包括:

  • 选择的协议版本。
  • 服务器选择的加密套件和压缩算法。
  • 一个服务器随机数,供后续密钥协商使用。

这类似于服务器回应:“您好,保密没问题,你的加密套路还挺多,咱们就按套路 2 来吧,我这里也有个随机数,你也留着。”

接着,服务器会发送其 服务器证书,并表示 Server Hello Done,完成该阶段的协商。

  1. 客户端验证证书

客户端收到服务器的证书后,必须验证证书的有效性。客户端通过从自己信任的 CA 证书库 中获取 CA 的公钥,用来解密服务器证书中的签名。如果验证成功,证明外卖网站是可信的。

如果证书验证通过,客户端就会生成一个 Pre-master secret,并通过服务器的公钥加密后发送给服务器。服务器使用其私钥解密该数据。

  1. 密钥协商

到目前为止,客户端和服务器各自拥有了三个随机数:

  • 客户端生成的随机数。
  • 服务器生成的随机数。
  • 客户端生成的 Pre-master secret。

基于这三个随机数,客户端和服务器都可以计算出相同的对称密钥,用于后续的加密通信。

  1. 通信加密

一旦对称密钥生成,双方会通过 Change Cipher Spec 消息告知对方:“咱们以后都采用协商的通信密钥和加密算法进行加密通信了。”

然后,客户端发送一个 Encrypted Handshake Message,用协商的密钥加密,并将参数等信息发送给服务器进行验证。

同样,服务器也会发送 Change Cipher Spec,确认采用协商的密钥加密通信,并发送加密的握手消息给客户端,确认双方都已经准备好进行加密数据传输。

  1. 数据传输

一旦握手完成,双方就可以开始通过对称密钥加密的数据传输。此时的加密解密过程和普通 HTTP 请求类似,只不过所有数据都使用协商的对称密钥进行加密。

  1. 单向认证与双向认证

上面的过程涉及的是 单向认证,即客户端仅验证服务器的证书,这是大多数场景下的使用模式。

在需要更严格安全性要求的情况下,可以启用 双向认证,也就是说,客户端和服务器互相验证对方的证书。这样,双方不仅确保了通信的加密性,还能确保双方身份的真实性。

重放与篡改

在加密通信中,虽然加密和解密能够保证数据的机密性,但仍然存在一些潜在的安全问题,尤其是重放攻击和篡改攻击。

重放攻击是指攻击者截获了合法的加密数据包,并将其重复发送给服务器。因为加密过程本身无法防止数据被重复发送,攻击者可能通过这种方式重复执行某些操作,导致数据被不当使用。

为了解决重放攻击,通常会使用时间戳 (Timestamp) 和随机数 (Nonce) 的结合:

  • Nonce 随机数保证每个请求的唯一性。
  • Timestamp 时间戳记录请求的时间。

这两个元素的结合,确保每次请求都是唯一的,不可能重复。当服务器接收到请求时,会检查请求中的时间戳和随机数,如果发现重复的时间戳和随机数组合,就会拒绝请求,防止重复操作。

篡改攻击是指攻击者在传输过程中改变了数据内容。例如,攻击者修改请求中的一些字段,伪造请求内容,甚至改变传输的数据。即使攻击者无法解密数据,但它仍然可以尝试修改数据后再发送。

为了防止篡改攻击,通常会采用签名机制。签名用于保证请求的数据在传输过程中未被修改。具体实现方式如下:

  • 在请求中加入时间戳和随机数,并对这些数据进行签名。
  • 使用不可逆的哈希算法生成签名,再使用私钥对签名进行加密,形成数据包的签名。
  • 服务器收到请求后,用服务器的公钥解密签名,验证数据是否未被篡改。

如果攻击者修改了请求内容,签名就会不匹配,服务器便无法通过验证,最终拒绝该请求。

通过使用时间戳 (Timestamp) 和随机数 (Nonce) 防止重放攻击,结合签名机制保证数据的不可篡改性,我们能够有效地提高加密通信的安全性,防止重放和篡改等常见攻击。

;