深入浅出ssl技术

jopen 5年前

安全,是互联网服务中和应用中最重要也是最容易被忽视的问题。大多数厂商在系统开发初期对安全问题考虑甚少,甚至直接忽略。本文旨在对互联网安全中扮演重要角色的ssl加密技术进行介绍。

我们都在互联网中“裸奔”

裸奔

internet技术在设计之初,基本没有考虑安全问题,并没有对数据传输中的安全问题进行太多规范和考虑。时至今日,tcp/ip已经成为互联网数据通讯的事实标准,但是还是有大量的服务和应用没有采用任何加密技术,我们的每一次数据传输,每一次互联网行为,其实都是在“裸奔”。当你进行一次搜索,发布一条日志,阅读一条新闻时,你的行迹都完全暴露于互联网之中。可能你要问,上了十几年网了,貌似也没啥啊?这是因为你的记录在茫茫互联网之海中不过沧海一粟,很难引起别有用心之人的兴趣罢了。这就好比你现在去街上裸奔,必定引起众人注目;但是如果全世界大部分都在裸奔,穿衣服的是少数时,也没有人关注你了(⊙o⊙)…也许你又要问一个问题了,既然互联网这么不安全,那些厂商都不做点什么保护大家隐私么?是的,时至今日,像微博这种有大量用户数据的网站依然默认没有采用加密传输。这是为什么呢?原因很多。

  1. 成本问题。很多产品在开发初期的重心都是focus在业务上,对安全考虑甚少,业务发展起来后,再考虑安全问题也会涉及大量的业务修改和代码升级,很多厂商包着侥幸心理,在“出大事”之前都不愿意投入人力和时间去解决安全问题。(还记得csdn密码泄露事件吧?)
  2. 性能问题。数据的加密和解密都会消耗额外的运算资源,很多厂商处于成本考虑,都会选择敏感业务加密,不敏感业务明文的策略。(比如你在淘宝上看商品的时候是不加密的,一旦要付钱了,你懂的)
  3. 业务问题。有一些网站确实是没有必要加密的,比如新闻站点。但是在web2.0时代,大部分的新闻站点还是携带很多用户信息的,这里不加密也是厂商聊以自慰而已。

说了这么多原因,你发现了么?以上其实都是厂商从自己的角度出发,要不是为了省成本,要不是觉得不必要,都是厂商的借口。身为用户的你,其实是在不知情的情况下被厂商扒光了衣服,然后告诉你你穿了衣服别担心(皇帝的新衣?)。当然这种情况近些年已经大大改善,国内网一些主要站点非死book,google, baidu等,已经痛下决心,全站升级为加密技术了。

 如何保护我们的隐私

在以上所述的明文通信方式中,都面临以下三种风险:

  1. 窃听:第三方通过抓包工具抓取到的内容可以直接被理解
  2. 篡改:第三方可以修改通信的内容然后再转发
  3. 伪装:第三方可以假冒发送方或接收方进行通信

如何解决这三点风险呢?如果我们能做到让上面那个可恶的“第三方”无法抓取我们的通信内容,上面的三个风险全部一下化解了。但是现实是残酷的,我们没法做到,这是internet的基础通信架构决定的。要解决问题,只能试试各自击破,下面一一分析

  1. 针对窃听,如果对传输的内容进行加密,就算第三方抓取到通信内容,也无法理解。加密技术早在二战时期就开始成为科学家们研究热点,目前已经有很多成熟方案。
  2. 针对篡改,需要在通信双方增加校验机制,一旦通信内容被篡改,就可以通过校验立即被发现,通信双方可以不信任该消息。
  3. 针对伪装,通信双方必须配备由权威第三方机构颁发的通信证书,以此证明自己的身份。

所有的加密技术都是某种程度基于一个或多个密钥,最常见的就是对称加密技术

通信双方持有相同的密钥,可同时用于通信内容的加密解密。

对称加密的根本数学原理就是单向函数,对于f(a)=b,输入a可以求出b,但是知道b很难猜出a。

也许你会想,这不,只要双方都有同一个密钥,通信的内容就很容易被加密了,也只有收信人才能解密理解,窃听风险不就迎刃而解了么?so easy!确实如此,但是有两个问题就很蛋疼了:

  1. 密钥如何分发?假如alice和bob需要进行加密通讯,但是在他们进行加密通讯之前alice总得想办法告诉bob她的密钥是啥吧!但是alice又不能通过网络明文发给bob啊(因为网络不安全啊魂淡)!alice能做的只能是把密钥写在纸条上,写信寄给bob了(呵呵了)。如果alice要给jim,tony…等等各种人通信,我已经不敢想象这有多蛋疼了…
  2. 密钥泄露风险。如果alice和bob协商好的通信蜜钥被任何一方泄露,后果都是不堪设想的。任何人都能收到alice发给bob的“私密信息”,任何人都能假装alice给bob发信…

对于第二个问题,如果我们能够每次通讯都使用不同的密钥,就算密钥泄露,下次通话之前泄露的密钥还是没有用的。这时,如何安全的进行密钥协商就成了最关键的问题。这时就可以采用非对称加密技术

非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。

非对称加密的基本数学原理是大数难分解。以最常用的rsa算法为例,其基本原理如下:

1.随机选择两个大质数p和q,p不等于q,计算N=pq;
2.选择一个大于1小于N的自然数e,e必须与(p-1)×(q-1)互素。
3.用公式计算出d:(d×e)mod( (p-1)×(q-1) )= 1 。
4.销毁p和q。
最终得到的N和e就是“公钥”,N和d就是“私钥”,发送方使用公钥去加密数据,接收方只有使用私钥才能解开数据内容。

在通信之前alice的公钥是公开的,所以无论是bob还是tony,以及其他任何人,都是知道这个公钥的。alice和bob在通信之前,可以用自己的私钥加密一些有意义的信息,bob通过公钥解密来验证这个信息,如果是对的,则证明alice确实持有该公钥对应的私钥,bob则放心的与其通信。这时alice可以选择一个对称加密算法并随机生成一个密钥发送给bob,后续通话他们采用该密钥对称加密通信即可。好吧,我相信你一定又有两个疑问,;-)

  1. 干吗还要回到对称加密来通信啊,直接全称非对称通信不行么?答案是可以,但是非对称加密的开销非常大,会对通信速度造成显著影响,所以强烈不建议这样。
  2. bob怎么知道他手上拿到的alice的公钥就是alice给的呢?万一有黑心的捣蛋鬼到处谎称自己是alice并散播自己制作的公钥给所有人呢?(如何证明你妈是你妈(⊙o⊙)…)答案是,bob确实无法知道,所以一般需要有权威的第三方机构,对alice进行认证,bob也会到第三方权威机构去获取alice的公钥,而不是随便相信某个无名小卒。
  3. 通信双方如何校验?good question,我们可以在alice和bob的所有通话中增加一个校验和,比较常用的有md5或者sha1等,这样,双方针对通信内容计算的校验和如果不匹配,那就说明消息被篡改过啦!

好吧,上面讲的这些不是ssl,但是基本上涵盖ssl的基本原理啦!哈哈,其实也不是那么复杂。下面再具体讲下ssl的工作流程。

ssl工作流程

ssl工作流程大体可分为握手和记录两个阶段,其中握手阶段是不包含实际需要传输的数据,通信数据都是在握手成功后,在记录阶段传送。记录阶段,发送方对传输的数据进行压缩、计算校验和并采用协商的对称密钥进行加密,接收方通过该过程的逆过程进行解密。ssl工作流中关键的是握手阶段,下面重点介绍。

ssl握手允许服务器和客户机相互验证,协商加密和校验算法以及保密密钥,用来保护在SSL记录中发送的数据。握手协议是在应用程序的数据传输之前使用的。握手协议的4个阶段如图:

第一阶段:问候

SSL握手的第一阶段启动逻辑连接,双方互通信息。首先客户机向服务器发出client hello消息并等待服务器响应,随后服务器向客户机返回server hello消息,对client hello消息中的信息进行确认。

Client Hello消息包括Version(客户端支持的ssl版本号),Random(一个客户端生成的随机数,用于生成对称密钥),Session id(会话id),Cipher suite(客户端支持的加密算法表),Compression method(客户端支持的压缩算法)等信息。

Server Hello服务器用ServerHello信息应答客户,包括Version(取客户端支持的最高版本号和服务器支持的最高版本号的较低者),Random(一个服务器生成的随机数,也是用于生成对称密钥),Session id(会话id),Cipher(从客户端支持的加密算法中选择的一个算法),Compression(从客户端支持的压缩算法中选择的一个算法)

第二阶段: 服务器鉴别与密钥交换

该阶段只有服务端向客户端发送消息。该阶段分为4步:

(a)服务器将数字证书发给客户端

(b)服务器密钥交换(可选):这里视密钥交换算法而定

(c)证书请求(可选):服务端可能会要求客户自身进行验证。

(d)服务器发送结束命令,结束该阶段

第三阶段:密钥鉴定与密钥交换:

该阶段只有客户端向服务器发送消息。该阶段分为3步:

(a)证书(可选):为了对服务器证明自身,客户要发送一个证书信息。

(b)密钥交换(Pre-master-key):这里客户端生成的第二个随机数,连通之前生成的两个随机数共同作为对称密钥的生成因子。使用服务端的公钥进行加密后将该随机数发送给服务端。

(c)证书验证(可选),对Pre-master-key进行签名,证明拥有(a)证书的公钥。

第四阶段:完成

客户机启动SSL握手第4阶段,整个握手过程结束。该阶段分为4步,前2个消息来自客户机,后2个消息来自服务器。

(a)客户端发送编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。

(b)客户端握手结束通知,表示客户端的握手阶段已经结束。

(c)服务器发送编码改变通知,表示随后的信息都将用双方商定的加密方法和密钥发送。

(d)服务器握手结束通知,表示客户端的握手阶段已经结束。

现在和将来

如今,ssl已经基本成为了互联网安全加密的事实标准。从谷歌、非死book、BAT这种一线厂商,到初创企业,甚至银行、券商等金融机构,都在大量使用ssl技术进行加密通信。世界似乎很美好!我们的互联网已经安全了么?

前不久,使用最广泛的开源ssl实现库openssl被发现重大漏洞,人称Heartbleed漏洞。这次漏洞的严重性和影响范围之大堪称惨烈。这里就不做详细介绍了,具体分析可以看这里。随后不久,又爆出了同样相当严重的FREAK漏洞。是的,很多时候我们大意了,以为大家都用,肯定没啥大问题。也许有人要怒吼一声:不如自己设计一个闭源的加密算法,源代码没有,别人肯定难破解了!强烈不建议这样,因为

  1. 加密算法的安全性和闭源开源没有太多关联。一个加密算法的本身安全性其实是纯数学问题,开发者不是密码专家,基本不可能设计出现在最常用的加密算法安全级别的加密算法,就算你设计的算法闭源,相信破解难度很可能还小于目前的公开算法!
  2. 软件的bug和漏洞永远是无法避免的。就算是不公开的实现,也很可能有各种漏洞。反而开源的加密算法实现漏洞会少一些,因为经过很多人围观、测试以及修正。

所以,除非你是做密码学研究,工程中还是建议别折腾了!

相信ssl技术在未来能依然保持主流地位,我们也能看到ssl技术一直在发展,比如这个项目就很赞,可以让我们从证书申请的复杂申请流程和不菲申请费用中解脱出来!这也是ssl部署最繁琐的痛点。

来自:http://blog.pandocloud.com/?p=376