带你深入理解HTTP的秘密(密钥)

之前的文章说了一下关于 Cookie 的内容,但是也就引出来了一些问题,比如 HTTP 是怎么进行安全处理的?来了,本文给大家讲述 HTTP 的安全问题。

1. HTTPS

HTTPS 是最流行的 HTTP 安全形式。它是由网景公司首创的,所有主要的浏览器和服务器都支持此协议。

大家来看这个图,

HTTPS 方案的 URL 以 https://,而不是 http:// 开头,据此就可以分辨某个 Web 页面是通 过 HTTPS 而不是 HTTP 访问的(有些浏览器还会显示一些标志性的安全提示)

使用 HTTPS 时,所有的 HTTP 请求和响应数据在发送到网络之前,都要进行加密。 HTTPS 在 HTTP 下面提供了一个传输级的密码安全层。

我们可以来看一下关于 HTTP 和 HTTPS 的层。

大部分困难的编码及解码工作都是在 SSL or TLS 库中完成的,所以 Web 客户端和服务器在使用 安全 HTTP 时无需过多地修改其协议处理逻辑。在大多数情况下,只需要用 SSL 的输入 / 输出调用取代 TCP 的调用,再增加其他几个调用来配置和管理安全信息就行了。

2.数字加密

关于数字加密,很容易理解的,不知道大家看过一些 “神剧” 么? 在抗战时期的电报密码,都是用本子的形式,然后密码本不同的字母来对应不同的数据信息,然后把对应的数字拼接起来。这只是我们对数字密码的简单理解,来官方的说法:

这里面的编码器和解码器在 “神剧”中不就是密码本的存在么?用密码来生成保密信息已经有数千年了。传说尤利乌斯 · 凯撒(Julius Caesar)曾使用过 一种三字符循环移位密码,报文中的每个字符都由字母表中三个位置之后的字符来取代。 在现代的字母表中,“A”就应该由“D”来取代,“B”就应该由“E”来取代,以此类推。

我们按照 “旋转3” 为例子,

密码就可以将报文“meet me at the pier at midnight”编码为密文“phhw ph dw wkh slhu dw plgqljkw”。

1 通过解码,在字母 表中旋转 -3 个字符,就可以将密文解密回原来的明文报文。

但是缺点我们同时也能想到,密码本容易被对方给获取,编码机器也容易被敌人获取,在战争年代,密码本这是必争之物呀。

所以大部分机器上都有一些号盘,可以将其 设置为大量不同的值以改变密码的工作方式。即使机器被盗,没有正确的号盘设置(密钥值),解码器也无法工作。

这些密码参数被称为密钥(key)。要在密码机中输入正确的密钥,解密过程才能正确进 行。密码密钥会让一个密码机看起来好像是多个虚拟密码机一样,每个密码机都有不同的 密钥值,因此其行为都会有所不同。

上图中就是使用不同密钥的旋转 N 字符密码。。密钥越长,编码组合就越多,通过随机猜测 密钥来破解代码就越困难。

给定一段明文报文 P、一个编码函数 E 和一个数字编码密钥 e,就可以生成一段经过编码的密文 C 如下图。通过解码函数 D 和解码密钥 d,可以将密文 C 解码为原始的明文 P。当然,编 / 解码函数都是互为反函数的,对 P 的编码进行解码就会回到原始报文 P 上去。

3.对称密钥加密

我们来更详细地看看密钥和密码是怎样配合工作的。很多数字加密算法都被称为对称密 钥(symmetric-key)加密技术,这是因为它们在编码时使用的密钥值和解码时一样 (e=d)。我们就将其统称为密钥 k。

在对称密钥加密技术中,发送端和接收端要共享相同的密钥 k 才能进行通信。发送端用共 享的密钥来加密报文,并将得到的密文发送给接收端。接收端收到密文,并对其应用解密 函数和相同的共享密钥,恢复出原始的明文。大家看下面的一幅图:

对称密钥加密算法为编 / 解码使用相同的密钥,流行的对称密钥加密算法包括:DES、Triple-DES、RC2 和 RC4。

3.1 密钥长度与枚举攻击

在很多情况下,编 / 解码算法都是众所周知的,因此密 钥就是唯一保密的东西了。

好的加密算法会迫使攻击者试遍每一个可能的密钥,才能破解代码。用暴力去尝试所有的密钥值称为枚举攻击(enumeration attack)。如果只有几种可能的密钥值,居心不良的人通过暴力遍历所有值,就能最终破解代码了。但如果有大量可能的密钥值,他可能就要花 费数天、数年,甚至无限长的时间来遍历所有的密钥,去查找能够破解密码的那一个。

可用密钥值的数量取决于密钥中的位数,以及可能的密钥中有多少是有效的。

8 位的密钥只有 256 个可能的密钥值, 40 位的密钥可以有 240 个可能的密钥值(大约是一万亿个密钥),128 位的密钥可以产生 大约 340 000 000 000 000 000 000 000 000 000 000 000 000 个可能的密钥值。

但是也有例外,并不是所有的加密技术中的密钥值都是全部有效果的,比如,在最知名的非对称加密算法 RSA 中,有效密钥 必须以某种方式与 质数相关。可能的密钥值中只有少量密钥具备此特性。

在传统的对称密钥加密技术中,对小型的、不太重要的事务来说,40 位的密钥就足够安 全了。但现在的高速工作站就可以将其破解,这些工作站每秒可以进行数十亿次计算。 相比之下,对于对称密钥加密技术,128 位的密钥被认为是非常强大的。

实际上,长密钥对密码安全有着非常重要的影响,美国政府甚至对使用长密钥的加密软件实施了出口控制,以防止潜在的敌对组织创建出美国国家安全局(National Security Agency,NSA)自己都无法破解的秘密代码。

Applied Cryptography 这本书中有一个表,记录了1995年的通过猜测所有的密钥来破解一个 DES 密码所需的时间进行了描述。

可能这个数据并不是很适用现在,计算机的速度在成倍数的增长,但是这个图,我们也可以乘以相对应的倍数,那还是比较有参考价值的哈。

对称密钥加密技术的缺点之一就是发送者和接收者在互相对话之前,一定要有一个共享的保密密钥。

比如你想要和淘宝卖家建立私密的对话的话,那么在安全下单之前,需要和淘宝网建立一个私有的保密密钥,你需要一种产生保密密钥并将其记住的方式,如果全网的人都是这样的,那就可能记住太多的东西了,这就是噩梦般的存在呀。于是就出现了后边的内容,请看下边:

4.公开密钥加密

公开密钥加密技术没有为每对主机使用单独的加密 / 解密密钥,而是使用了两个非对称密钥:一个用来对主机报文编码另一个用来对主机报文解码。编码密钥是众所周知的(这 也是公开密钥加密这个名字的由来),但只有主机才知道私有的解密密钥。

每个人都能找到某个特定主机的公开密钥,密钥的建立变得更加简单。但解码密钥是保密的,因此只有接收端才能对发送给它的报文进行解码。

公开密钥加密技术是非对称的,为编码和解码使用了不同的密钥。

那我们就需要把对称密钥加密和公开密钥加密来做个对比了。

所有公开密钥非对称加密系统所面临的共同挑战是:

  • 公开密钥(是公有的,所有人都可以获得);

  • 一小片拦截下来的密文(可通过对网络的嗅探获取);

  • 一条报文及与之相关的密文(对任意一段文本运行加密器就可以得到)。

就算你知道这三个条件,也无法计算出保密的私有密钥,这就是公开密钥非对称加密系统所要面临的挑战。

RSA 算法就是一个满足了所有这些条件的流行的公开密钥加密系统,关于RSA算法,本文先不深究,之后在我看完密码学这本书之后,然后再给大家进行解读。

5.数字签名

前面我们已经说了对称和非对称密钥加 / 解密,下面我们来说数字签名是什么意思。

百度百科:数字签名(又称公钥数字签名)是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。它是一种类似写在纸上的普通的物理签名,但是使用了公钥加密领域的技术来实现的,用于鉴别数字信息的方法。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。数字签名是非对称密钥加密技术与数字摘要技术的应用。

其实说白了,数字签名就是附加在报文上的特殊加密校验码。

我们用一个例子来进行解释,我们先看一幅图,节点 A 是如何向节点 B 发送一条报文,并对其进行签名的。

  1. 节点 A 将变长报文提取为定长的摘要。
  2. 节点 A 对摘要应用了一个“签名”函数,这个函数会将用户的私有密钥作为参数。因 为只有用户才知道私有密钥,所以正确的签名函数会说明签名者就是其所有者。在图中,,由于解码函数 D 中包含了用户的私有密钥,所以我们将其作为签名函数使用。
  3. 一旦计算出签名,节点 A 就将其附加在报文的末尾,并将报文和签名都发送给 B。
  4. 在接收端,如果节点 B 需要确定报文确实是节点 A 写的,而且没有被篡改过,节点 B 就可以对签名进行检查。节点 B 接收经私有密钥扰码的签名,并应用了使用公开 密钥的反函数。如果拆包后的摘要与节点 B 自己的摘要版本不匹配,要么就是报文在传输过程中被篡改了,要么就是发送端没有节点 A 的私有密钥(也就是说它不是节点 A)。

把图理解是,是不是关于数字签名就很好理解了呢?

6.数字证书

我们来看一下百度百科对他的解释:数字证书是指CA(电子认证服务)机构发行的一种电子文档,是一串能够表明网络用户身份信息的数字,提供了一种在计算机网络上验证网络用户身份的方式,因此数字证书又称为数字标识。数字证书对网络用户在计算机网络交流中的信息和数据等以加密或解密的形式保证了信息和数据的完整性和安全性。

数字证书其实并没有我们想的那么难,数字证书的基本架构是公开密钥PKI,即利用一对密钥实施加密和解密。其中密钥包括私钥和公钥,私钥主要用于签名和解密,由用户自定义,只有用户自己知道;公钥用于签名验证和加密,可被多个用户共享。

HTTPS 建立了一个安全 Web 事务之后,现代的浏览器都会自动获取所连接服务器的 数字证书。如果服务器没有证书,安全连接就会失败。服务器证书中包含很多字段,其中包括:

  • Web 站点的名称和主机名;
  • Web 站点的公开密钥;
  • 签名颁发机构的名称;
  • 来自签名颁发机构的签名

浏览器收到证书时会对签名颁发机构进行检查。1 如果这个机构是个很有权威的公共签名 机构,浏览器可能已经知道其公开密钥了(浏览器会预先安装很多签名颁发机构的证书)。

如果对签名颁发机构一无所知,浏览器就无法确定是否应该信任这个签名颁发机构,它通 常会向用户显示一个对话框,看看他是否相信这个签名发布者。签名发布者可能是本地的 IT 部门或软件厂商。

是不是很容易理解呢?

文章参考:

《图解 HTTP》

《HTTP 权威指南》

我是懿,一个正在被打击却努力前进的码农。

Java Geek Tech wechat
欢迎订阅 Java 极客技术,这里分享关于 Java 的一切。