SSL基础介绍


SSL作为一个加密套件已经被广泛应用,甚至成为了互联网上加密通讯的工业标准。但是直到现在,依然有不少人对这个套件不熟悉,并且也对这个套件及其应用提出了诸多问题。而一个被问的最多的问题就是:

为什么安全性如此重要?

让我们来模拟一下你访问你最爱的某个网站的过程。如果你的网络环境良好,你从输入网址到打开网页这个过程只有短短数秒的时间。但是就在这短短数秒的时间内,你的请求和网站服务器的响应穿越了你自己的电脑,你的路由器,你的运营商的路由器和交换机(常常不止一个),然后经过骨干网,服务器机房,最终到达服务器。而如果有某个人别有用心,又正好出于某些原因可以访问到其中的某个环节的设备,那么他就有能力看到这个设备上经过的所有流量。

那有的人又要说了,我大丈夫心怀坦荡,从不做偷鸡摸狗的事情,让人看看就看看怎么啦?只要像是密码啊银行卡信息啊这种不能给人看的东西加密传输不就可以啦?

如果真的只是可以看,那上面的话确实有道理啊,可是问题在于人有了力量就会控制不住自己。看久了,就会想要动手脚。如何动手脚呢?诶,这用户好喜欢上网哦,每天看那么多网站,那我给他看几个广告,我不就能赚好多钱?于是从某天开始,该用户上的每个网页都要弹一两个广告,该用户心里急啊,还以为是自己的问题呢。打开xx卫士,xx助手,xx杀毒,怎么查都查不到。于是下定确信痛定思痛备份所有数据然后重装系统,满怀期待的打开浏览器,结果瞬间想起了慷慨激昂的背景音乐,弹出的窗口上赫然写着:“屠龙宝刀,点击就送”。如果你是该用户,你会是什么心情?如果你觉得你比该用户聪明点,会先各种百度各种谷歌,你应该会得到一个叫做ISP劫持的术语。而在不加密的http时代,这样的行为实在是过于简单了,毕竟所有网络流量都在那个作恶的黑衣人手中。如果你觉得我过于危言耸听,或者相信这个世界上“还是好人多”,那么你不妨看看这位用户的经历。

如果是加密过的流量,除了终端用户和源服务器以外,中间的任何一个环节都无法通过简单的传输来获取该加密流量。针对加密流量的攻击方法并非不存在,但是相对于ISP劫持这种几乎毫无成本的作恶,针对加密流量的攻击就要代价高昂的多,而大部分作恶者也会因收益并没有成本来的高因此知难而退。只有一些不计成本只为达成目的某些超级团体,才会去做这种“亏本生意”。比如这一影响极大的恶性攻击事件。但是这样群体的存在并不能说加密流量就是没有用的,反过来想,哪怕代价如此高昂都要去破解或者绕过加密,你的通信本身就是明文的,那岂不是把自己在互联网上最有价值的部分拱手送人?

Your data is more valuable than your self. –Watch Dogs 2

加密通信好处好多诶!那为什么大家都不默认启用加密呢?主要是各方面成本上的原因。大致有以下几点:

  • 加密数据使用更多计算资源
  • 加密数据使用更多带宽
  • 加密数据破坏缓存(因为无法得知具体的响应内容,而导致中途的代理就无法进行缓存加速响应,类似xxGo那样的带缓存代理也就不可能实现。)
  • 加密数据限制使用场景(比如poi这样的游戏浏览器就会因为读取不到加密过的游戏API而完全失效,甚至所有此类软件都难以在不威胁到用户系统安全的情况下被开发出来。)

在很久以前,加密数据还因为可信赖的CA签发证书费用高昂,一般人根本无力承担而作罢。不过现在随着类似Let’s Encrypt这样的免费证书的出现,获取受信赖的证书也就不再是个问题。


SSL/TLS/HTTPS分别是什么?

这三个名词关系紧密而又常常同时出现,对概念不熟悉的人确实非常容易一头雾水。
简单而言,SSL(Secure Sockets Layer)和TLS(Transport Layer Security)都是用于提供数据加密和通信鉴定的安全套件,他们本身不传输数据他们只加密数据。更形象的说法,TLS(SSL)本身像个隧道,隧道里面的车是轿车卡车火车不由隧道决定,而由隧道里面东西决定。

而TLS本质上就是个新版本的SSL,TLSv1.0其实本身对应的是SSLv3.1。只是规范化以后改名了。而在实际应用中,SSL和TLS常常不区分名字混用,几乎就是互相指代。而现在传统的SSLv3.0已经被认为是不安全的而弃用,因此这样的互相指代并不会引起歧义。

HTTPS(HTTP over TLS)则是指经过TLS传输层加密的HTTP,HTTP就是跑在TLS隧道里面的车,负责传输数据。什么?你不知道HTTP是什么?百度一下,你就知道比百度更强大


客户端/服务器怎么知道数据已经被加密过了?

主要是两种方法:

  • 通过端口确定的(显式)。往特定端口传输的数据必须是加密数据。比如443端口,https所使用的就是这个端口。如果你往443端口传入了未经加密的数据,部分网页服务器(如nginx)会返回400: The plain HTTP request was sent to HTTPS port错误。一般而言这些特定端口的存在就是为了处理加密数据,因此完全不需要判断传入数据是否经过加密,只需要统统按照加密信息处理即可。但是通过port不能直接确认加密信息的加密方式,因此即使是特定端口,也会使用下面的隐式方法。
  • 通过协议决定的(隐式)。这种连接在建立的时候会对服务器先”say hello”(在一个不加密的环境中),然后双方互相传输所支持的连接方式和加密套件,一个共同支持的套件,然后切换到加密后的流量来传输。如果这个协商(术语叫handshake)失败,也就是双方没有共同支持的加密方式,而其中一方只接受加密数据(比如这个连接的目标端口为443)的话,这个连接会被切断。

SSL怎么确保连接安全?

公钥加密

SSL依赖于非对称加密的概念。非对称密钥加密拥有一个公钥和一个私钥,公钥用来将明文加密成密文,私钥用来将密文重新解密成明文。

当密文生成后,它只能用对应的私钥解密。一个密钥对里的公钥和私钥都只能进行加密或解密中的一项操作。因此公钥可以安全的被投放给客户端而不用担心数据会被窃取,但是私钥必须妥善的保管在服务器上。如果私钥被盗,后果将不堪设想。

但是这也引发了新的问题。因为加密连接要在密钥交换后才可以建立,也就是说公钥必须要在一个不安全的、可以被监听的环境中进行传递。那么这时候如果有不怀好意的监听者,偷偷的获取私钥,然后解密流量怎么办?当然有办法,因为我们有办法让监听者就算截获了通信的每一个数据包,也没法得知公钥是什么。

这怎么可能呢?数学!

最为通行的办法是通过Diffle-Hellman密钥交换。该算法依赖离散对数问题的复杂性来确保安全。A = g^a \mod p ,就算A g p全部都是已知,也非常难以求得a。而在这个算法的应用中,p又偏偏是一个非常非常大的素数。比如1024-bit 2048-bit 3076-bit。而这么长的一个密钥的时间复杂度是多少呢?是2^n ,n为密钥长度。那么一个2048bit的密钥就有大概2^{2048} \approx 10^{616} 这个量级,可观测的宇宙中原子总数大概10^{80} 个。以目前所有可用的计算能力也无法依次求解这样的一个数学问题。但是若是未来有了进步,拥有高效求解离散对数问题的方案了以后,本系统以及依赖本系统的所有加密系统都将变得不安全。

https连接建立过程

在有了公钥交换的概念后,理解连接建立的过程就轻易的多了。但是非对称加密并不能让客户端理解加密后的数据,所以现在通行的办法是利用服务器的公钥算出一个session key,这个密钥是个对称密钥,既可以加密,又可以解密。在密钥交换完成并且连接建立后双方通信所使用的就是这个对称密钥。因为这个对称密钥是加密传输的,并且这个密钥是一次性的,每次连接建立后都会重新创建一个。所以就算你的通信数据被缓存,未来某个时候对称密钥可以被探知,也无法用未来获取的对称密钥来解密你现在的流量数据。

  1. 浏览器通过https连接到某网站,并要求网站验明正身。
  2. 服务器发回了自己的一份SSL证书,里面包含了服务器自身的公钥
  3. 浏览器检查服务器证书的CA是否受信任,是否被revoke,是否过期,并且证书中的common name字段是否与网站匹配。如果以上问题的答案全部为是,浏览器建立加密连接,返回用服务器公钥加密过后的对称密钥。
  4. 服务器利用私钥解密对称密钥,然后发回一条用对称密钥加密后的确认信息。
  5. 加密连接建立,双方均使用对称密钥加密并传输数据。

Leave a Reply

Your email address will not be published. Required fields are marked *