网络基础08 HTTPS

SSL/TLS协议

HTTPS(HTTP Secure)是HTTP加上加密、认证和完整性保护。不是一种新的协议,只是在HTTP通信接口部分用了SSL和TLS协议代替,也就是说在HTTP与TCP之间增加了SSL,HTTP与SSL通信,再由SSL与TCP通信。

TLS是SSL协议的升级版, 目前应用最广泛的是TLS1.0和SSL3.0。

不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文传播,带来了三大风险:

  1. 窃听风险(eavesdropping):第三方可以获知通信内容。
  2. 篡改风险(tampering):第三方可以修改通信内容。
  3. 冒充风险(pretending):第三方可以冒充他人身份参与通信。

SSL/TLS协议是为了解决这三大风险而设计的,希望达到:

  1. 所有信息都是加密传播,第三方无法窃听。
  2. 具有校验机制,一旦被篡改,通信双方会立刻发现。
  3. 配备身份证书,防止身份被冒充。

SSL/TLS协议的基本思路是采用了公开密钥加密法,客户端首先向服务器索要公钥,然后用公钥加密信息,服务器收到密文后,用自己的私钥解密。

这里面有两个问题:

(1)如何保证公钥不被篡改

将公钥放在CA机构颁发的数字证书中,客户端收到服务器的公钥时会使CA机构内置在浏览器中的公钥进行验证。因此只要数字证书是可信的,公钥就是可信的

(2)公钥加密计算量太大,如何减少耗用时间

在建立连接阶段使用公开密钥加密计算,生成一个“对话密钥”,在随后的通话期间信息由“对话密钥”进行共享密钥加密。共享密钥加密是对称加密,运算速度很快,而服务器公钥只用于加密“对话密钥”本身,这样就减少了加密运算的时间。

HTTPS的工作模式

非对称加密在性能上不如对称加密,所以HTTPS采取了对称加密和非对称加密相结合的工作模式:公钥私钥主要用于传输对称加密的秘钥,而真正的双方大数据量的通信都是通过对称加密进行的

非对称加密需要通过证书和权威机构来验证公钥的合法性。

HTTPS的握手机制

HTTPS的握手相当于SSL/TLS协议的握手和TCP协议的握手,这里主要介绍的是SSL/TLS的握手。

SSL/TLS的握手阶段设涉及四次通信,这四次通信都是明文的:

(1)客户端发出请求(ClientHello)

客户端先想服务器发出加密通信的请求,提供一些基本信息,比如支持的TLS/SSL版本、用于生成“对话密钥”的随机数,支持的加密方法等。

(2)服务器回应(ServerHello)

服务器收到客户端请求后,向客户端发出回应,包含用于协商建立SSL通信的信息,比如确认使用的加密通信加密版本,服务器证书(包含服务器的公钥)、确认使用的加密方法、服务器生成的用来生成“对话密钥“的随机数

此外,如果服务器需要确认客户端身份,就会再包含一项请求,要求客户端提供“客户端证书”。比如金融机构往往只允许认证客户连入自己的网络,就会想正式客户提供USB密钥,里面包含了一张客户端证书。

(3)客户端回应

客户端收到服务器的回应后,首先验证服务器证书,如果证书不是可信机构颁布,或者证书的域名与实际域名不一致,或者证书已经过期,就会想访问者显示警告,由其选择是否还要继续通信。

如果证书没有问题,客户端就会从证书中取出服务器的公钥,然后向服务器发送下面三项信息:

1. 一个随机数(pre-master-key)。这个随机数会用服务器公钥加密
2. 编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送
3. 客户端握手结束通知,表示客户端的握手阶段结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验

到此为止,握手阶段已经有了三个随机数,随后,双方就会用实现商定的加密方法,用着三个随机数各自生成用于本次会话加密的同一把“会话密钥”。为什么一定要用三个随机数呢?

SSL协议中的证书是静态的,因此十分有必要引入一种随机因素来保证每次会话协商出来的密钥的随机性。所以不管是客户端还是服务器,都需要随机数,这样每次会话生成的密钥才不会每次都一样。

对于RSA密钥交换算法来说,pre-master-key本身是一个随机数,再加上Hello消息中的随机数,三个随机数通过密钥到初七最终导出一个对称密钥。

SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么对话密钥就有可能被猜出来。而三个随机数一同生成的密钥就不容易被猜出来了,一个伪随机可能完全不随机,可是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。

此外,如果在第二步服务器要求客户端提供证书,那么客户端在这一步还会发送证书及相关信息。

(4)服务器的最后回应

服务器收到客户端的第三个随机数pre-master-key后,计算生成本次会话用的“会话密钥”,然后向客户端发最后发送下面信息

1. 编码改变通知,表示表示随后的信息都将用双方商定的加密方法和密钥发送
2. 服务器握手结束通知,表示服务器的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供客户端校验。

至此,整个握手阶段全部结束,接下来客户端与服务器进入加密通信,就是完全使用HTTP协议,只不过使用“对话密钥”加密内容。

数字证书

公开密钥加密还有一个问题:每个服务器都可以生成自己的私钥和公钥,客户端并没有办法确定自己接收到到的公钥是否真的是目标网站的公钥,还是被替换过。

即:如何证明服务器下发的公钥没有被替换?

现在通用的解决方法就是通过数字证书认证机构(Certificate Authority,CA)颁发的公开密钥证书来解决这个问题。

CA会为提交申请的服务器的公钥做认证,CA利用自己的私钥,对服务器的公钥和一些相关信息一起加密,生成数字证书(Digital Certificate)。这样服务器在建立HTTPS连接时不再直接下发公钥,而是下发包含着服务器公钥(经过CA私钥加密过的)的数字证书。

浏览器会将CA的公开密钥事先内置到浏览器当中(避免了这个证书在传递中出现的问题)。所以客户端收到信息后,会利用CA的公钥解密数字证书,拿到服务器的真实的公钥。

拿到真实的公钥后,客户端(浏览器)会根据内置的“证书管理器”来验证公钥是否真的属于目标网站

客户端的“证书管理器”有`受信任的根证书办法机构”列表,客户端会根据这个列表,查看解开数字证书的公钥是否在列表内。

如果证书不是可信机构颁布,或者证书的域名与实际域名不一致,或者证书已经过期,就会想访问者显示警告,由其选择是否还要继续通信。

SSL延迟

HTTP耗时 = TCP握手(3次)

HTTPS耗时 = TCP握手(3次) + SSL握手

HTTPS肯定比HTTP耗时,这就叫SSL延迟。

从运行结果可以看到,SSL握手的耗时大概是TCP握手的三倍。也就是说,在建立连接的阶段,HTTPS连接比HTTP连接要长3倍的时间,具体数字取决于CPU的快慢和网络状况。

所以,如果是对安全性要求不高的场合,为了提高网页性能,建议不要采用保密强度很高的数字证书。一般场合下,1024位的证书已经足够了,2048位和4096位的证书将进一步延长SSL握手的耗时。

升级HTTPS

(1)获取证书

升级到HTTPS协议的第一步,就是要获得一张证书。

证书是一个二进制文件,里面包含经过认证的网站公钥和一些元数据,要从经销商购买。

  • GoGetSSL.com
  • SSLs.com
  • SSLmate.com

证书有很多类型,首先分为三种认证级别。

  • 域名认证(Domain Validation):最低级别认证,可以确认申请人拥有这个域名。对于这种证书,浏览器会在地址栏显示一把锁。
  • 公司认证(Company Validation):确认域名所有人是哪一家公司,证书里面会包含公司信息。
  • 扩展认证(Extended Validation):最高级别的认证,浏览器地址栏会显示公司名。

还分为三种覆盖范围。

  • 单域名证书:只能用于单一域名,foo.com的证书不能用于www.foo.com
  • 通配符证书:可以用于某个域名及其所有一级子域名,比如*.foo.com的证书可以用于foo.com,也可以用于www.foo.com
  • 多域名证书:可以用于多个域名,比如foo.combar.com

认证级别越高、覆盖范围越广的证书,价格越贵。还有一个免费证书的选择。为了推广HTTPS协议,电子前哨基金会EFF成立了Let's Encrypt,提供免费证书(教程和工具)。

拿到证书以后,可以用SSL Certificate Check检查一下,信息是否正确。

(2)安装证书

证书可以放在/etc/ssl目录(Linux 系统),然后根据你使用的Web服务器进行配置。

(3)修改链接(前端主要的工作都在此)

网页加载的HTTP资源,要全部改成HTTPS链接。因为加密网页内如果有非加密的资源,浏览器是不会加载那些资源的。

<script src="http://foo.com/jquery.js"></script>

上面这行加载命令,有两种改法:

<!-- 改法一 -->
<script src="https://foo.com/jquery.js"></script>

<!-- 改法二 -->
<script src="//foo.com/jquery.js"></script>

其中,改法二会根据当前网页的协议,加载相同协议的外部资源,更灵活一些。

另外,如果页面头部用到了rel="canonical",也要改成HTTPS网址。

<link rel="canonical" href="https://foo.com/bar.html" />

(4)301重定向

下一步,修改Web服务器的配置文件,使用301重定向,将HTTP协议的访问导向HTTPS协议。

server {
  listen 80;
  server_name domain.com www.domain.com;
  return 301 https://domain.com$request_uri;
}

HTTPS的七个误解

(1)HTTPS无法缓存

许多人以为,出于安全考虑,浏览器不会在本地保存HTTPS缓存。实际上,只要在HTTP头中使用特定命令,HTTPS是可以缓存的。

(2)SSL证书很贵

如果你在网上搜一下,就会发现很多便宜的SSL证书,大概10美元一年,这和一个.com域名的年费差不多。而且事实上,还能找到免费的SSL证书。

(3)HTTPS站点必须有独享的IP地址

每个IP地址只能安装一张SSL证书,这是毫无疑问的。但是,如果你使用子域名通配符SSL证书(wildcard SSL certificate,价格大约是每年125美元),就能在一个IP地址上部署多个HTTPS子域名。

比如,https://www.httpwatch.comhttps://store.httpwatch.com,就共享同一个IP地址。

(4)转移服务器时要购买新证书

IS的做法是生成一个可以转移的.pfx文件,并加以密码保护。将这个文件传入其他服务器,将可以继续使用原来的SSL证书了。

(5)HTTPS太慢

第一次打开网页的时候,HTTPS协议会比HTTP协议慢一点,这是因为读取和验证SSL证书的时间。

但是,一旦有效的HTTPS连接建立起来,再刷新网页,两种协议几乎没有区别。

(6)有了HTTPS,Cookie和查询字符串就安全了

虽然无法直接从HTTPS数据中读取Cookie和查询字符串,但是你仍然需要使它们的值变得难以预测。

(7)只有注册登录页,才需要HTTPS

这种想法很普遍。人们觉得,HTTPS可以保护用户的密码,此外就不需要了。在Twitter和Facebook上,劫持其他人的Session是非常容易的。

参考

发布了382 篇原创文章 · 获赞 91 · 访问量 33万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览