HTTPS权威指南:在服务器和Web应用上部署SSL-TLS和PKI(txt+pdf+epub+mobi电子书下载)

作者:伊万·里斯蒂奇(Ivan Ristic)

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

HTTPS权威指南:在服务器和Web应用上部署SSL-TLS和PKI

HTTPS权威指南:在服务器和Web应用上部署SSL-TLS和PKI试读:

前言

各位读者即将踏上密码学的神秘旅程。我已经结束了我的旅程,完成了本书;这是一段令人惊叹的经历。尽管我从SSL诞生之初就开始使用它,但直到2004年开始撰写第一本书Apache Security时,才对它产生了浓厚的兴趣。在五年之后的2009年,我决定寻找一些新的事情去做,于是决定在SSL上投入更多时间。自此我便专注于此,随后写成了本书。

我重新关注SSL的主要原因是我认为可以改善它:这一项重要的技术由于工具和文档的缺乏而受到阻碍。密码学这门学科非常吸引人,对这个领域了解得越多,实际上就越不了解它。换言之,了解得越多,就会发现有更多仍不了解的部分。当我对某个复杂命题的理解达到新的境界以后,另一层复杂性就随之展现在我面前。这种情况我已经数不清遇到过多少次,而这也正是密码学的迷人之处。

我花了近两年时间撰写本书。起初我认为只要花一部分精力就可以了,并没有全身心投入,但是不行。有一天我突然意识到,这个领域的变化实在太快,原本“已经完成”的章节到后来不得不返工甚至重写。到了最后,大约六个月以前,为了跟上变化,我开始抓紧每一刻闲暇撰写本书。

我写作的初衷是为了节省各位读者的时间。最近五年,我尽我所能学习了关于SSL/TLS和PKI的所有知识,我想只有少数人能像我这样付出。如果我将学到的最重要的部分写进书中,也许其他人的学习能够事半功倍——这一想法促成了本书的问世。

本书的英文标题中包含bulletproof(刀枪不入)这个单词,但这并不意味着TLS是坚不可摧的。它真正的含义是,如果读者遵循本书的指引,就可以最大化地利用TLS,并且可以将TLS部署得非常安全,让自己毫不逊色于世界上的其他任何人。这通常并不容易,尤其是针对Web应用,但如果读者坚持本书所倡导的原则,就可以拥有比其他99.99%的服务器更好的安全性。事实上,即使只付出一点点努力,拥有的安全性也会比互联网上99%的服务器更好。

一般来说,读者可以通过两种方式阅读本书。(1) 按部就班地从第1章开始。如果时间充足,通过这种方式能更好地理解本书的内容。(2) 如果需要快速解决问题,那么请直接阅读第8章和第9章。这两章阐述了如何在获得良好性能的同时部署安全服务器,包含读者需要了解的所有细节。如果之后有需要,可以将第1章至第7章的内容作为参考,将第10章至第16章的内容作为实际操作的指导。

范围和读者

本书的存在是为了记录在实际的日常工作中需要了解的关于SSL/TLS和PKI的一切。我着眼于正确地结合理论、协议细节、漏洞和弱点信息以及部署建议,以帮助读者完成工作。

在撰写本书时,我想象有以下三个群体的代表密切注视着我,希望我回答他们提出的问题。● 系统管理员系统管理员一贯时间有限而被迫处理系统上日益增加的安全

问题,因此他们需要有关TLS的可靠指导,从而可以快速有效地

配置他们的服务器。盲目相信从网络上找到的信息往往适得其反,

因为有非常多不正确和过时的信息。● 开发人员虽然SSL从诞生之初就承诺为基于TCP的协议提供透明的安

全保障,但现实情况却是开发人员在确保应用安全的任务中扮演

着十分重要的角色。对Web应用而言尤其如此,因为Web应用一

边围绕着SSL和TLS构建安全,一边整合着各种会破坏安全性的

特性。理论上“仅仅启用加密”即可,而实践中不仅需要启用加

密,同时也需要关注许多破坏安全性的问题,不论它们是大是小。

在本书中,我尽力不遗漏这类读者可能会遇到的每一个问题。● 管理人员最后是管理人员,虽然他们不必关心实施细节,但仍然需要

理解发生了什么并做出决策。安全领域变得越来越复杂,理解攻

击和威胁往往就是其工作的一部分。解决问题的方法经常不止一

种,最好的方法往往是依情况而定。

总之,

本书内容

全面覆盖了HTTP和Web应用,但几乎没有提及其他协议。这主要是因为浏览器。浏览器已经成为最流行的应用分发平台,而HTTP在浏览器上运用加密的方法非常特殊,带来了很多问题。因此本书才花了非常多的篇幅讲HTTP。

事实上,除了有关HTTP的章节,全书仍有三分之二的内容提供了可以应用到任何使用TLS协议的一般性指导。关于OpenSSL、Java和Microsoft的几章分别为相应的平台提供了协议的一般信息。

也就是说,如果各位读者正在寻找Web服务器以外的其他产品的配置示例,那么将无法在本书中找到。因为Web服务器主要由几大平台占据, 其他类型的应用则有大量的产品。只提供Web服务器相关的最新指导已经是相当大的挑战了,毕竟Web服务器一直在不断发展。我无法在更大的范围跟进,因此有意将其他配置示例发布在网上,并希望能够在社区中起到抛砖引玉的作用,从而保持这些指导及时更新。本书内容

本书主要内容共16章1,分为若干部分。这些部分彼此依托,构成一幅完整的蓝图,始于理论介绍,最后给出实践建议。

1第17章为全书总结。——编者注

第一部分包括第1~3章,是全书的基础,讨论了密码学、SSL、TLS和PKI。● 第1章 SSL、TLS和密码学这一章首先介绍了SSL和TLS,讨论这些安全协议从哪里融

入互联网基础设施;其余部分介绍密码学,并讨论了主动网络攻

击者的经典威胁模型。● 第2章 协议这一章讨论TLS协议的各种细节,内容覆盖了最新的TLS

1.2,并酌情提供了早期版本的信息。这一章最后包括了从SSL 3

起协议演变的概述以供参考。● 第3章 公钥基础设施这一章介绍互联网PKI。PKI是当今互联网上使用的主要信

任模型。这一章着重介绍其标准、组织、管理、生态系统的弱点

以及未来可能的改进。

第二部分包括第4~7章,详细列举各种问题。这些问题与信任基础设施、安全协议以及实现它们的库和程序有关。● 第4章 攻击PKI这一章内容涉及对信任体系的攻击,涵盖了所有主要的CA

事故,详细列举了种种弱点、攻击和效果。这一章以纯粹的历史

视角来回顾PKI体系的安全性,这对于理解其发展非常重要。● 第5章 HTTP和浏览器问题这一章讲述HTTP和TLS之间的关系,在Web出现根本性增

长后产生的问题,以及不同的网络体系之间杂乱的相互作用。● 第6章 实现问题这一章内容包括随机数生成、证书验证以及其他核心TLS和

PKI功能的设计和编码错误。此外,还讨论了自愿协议降级和截

断攻击,涵盖心脏出血、FREAK和Logjam等备受瞩目的攻击。● 第7章 协议攻击这是本书中篇幅最长的一章,涵盖了近年来发现的所有主要

的协议缺陷:不安全的重新协商、BEAST、CRIME、Lucky 13、

POODLE和POODLE TLS、RC4、TIME和BREACH,以及三次握

手攻击。这一章还简单讨论了Bull Run项目及其对于TLS安全性

的影响。

第三部分包括第8~10章,为以安全且高效的方式部署TLS提供了综合指导。● 第8章 部署这一章是整本书的地图,提供了如何一步一步地部署安全且

工作良好的TLS服务器和Web应用的操作指南。● 第9章 性能优化这一章着眼于TLS的速度,为那些希望从服务器中榨取每一

点速度的读者详述了各种提升性能的技术。● 第10章 HTTP严格传输安全、内容安全策略和钉扎这一章涉及加强Web应用的一些高级主题,比如HTTP严格

传输安全和内容安全策略。这一章也涉及钉扎,它是减少由当前

PKI模型带来的庞大攻击面的有效方法。

第四部分是最后一部分,由第11~16章组成,为在主流部署平台和Web服务器上使用和配置TLS以及如何使用OpenSSL探测服务器配置提供可行的指导。● 第11章 OpenSSL这一章描述了OpenSSL最常用的功能,主要介绍其安装、

配置、私钥和证书管理。最后的11.4节给出如何构建和管理一个

私有证书颁发机构的操作指南。● 第12章 使用OpenSSL进行测试这一章继续介绍OpenSSL,解释如何使用它的命令行工具

测试服务器配置。尽管使用自动化工具测试经常更加简单,但当

读者想确定当前具体的情况时,仍然可以使用OpenSSL工具。● 第13章 配置Apache这一章讨论流行的Web服务器Apache httpd的TLS配置。从

这一章开始,将有一系列章节提供实践指导,与前面章节的理论

相配合。每一章都专注于一个主要的技术层面。● 第14章 配置Java和Tomcat这一章涉及Java(第7版和第8版)和Tomcat服务器。除了

配置信息,这章也包含Web应用安全的指导。● 第15章 配置Microsoft Windows和IIS这一章讨论在Microsoft Windows平台和Internet Information

Server上部署TLS的问题,也为在ASP.NET下运行的Web应用上

使用TLS提供指导。● 第16章 配置Nginx这一章讨论Nginx服务器,除了阐述最新稳定版的特性,也

会对开发分支中的一些改进一探究竟。

SSL与TLS

非常不幸,本身相同的协议却有两个名称。根据我的经验,大多数人很熟悉在传输层加密的场景中使用SSL这个名称。有一些人,通常是那些在协议上花费更多时间的人,会使用或尝试使用更适合特定场景的正确名称。虽然也许并不能成功做到,但我仍尝试这样做。有时这显得很烦琐,但我通过下面的步骤做到了这一点:(1) 尽量不单独提及某一个名称;(2) 如果某条指导建议适用于所有版本,那么将两个名称都列出来;(3) 其他情况都使用TLS。各位读者可能不会注意到这些,那也没关系。

SSL Labs

SSL Labs(www.ssllabs.com)是我从2009年开始的一个研究项目,关注SSL/TLS和PKI的实用领域。我于2010年携带此项目加入Qualys公司。开始,我的主要职责并不在此,但是到了2014年,我将全部精力放在了SSL Labs上。

这个项目的出现主要是由于我了解到,缺乏优秀的文档和工具是导致TLS服务器配置普遍很糟的主要原因(默认配置很差是另一个重要原因)。我想,如果不能将问题可视化,我们就不能开始解决问题。多年以后,SSL Labs扩展成为以下四个主要项目。● 服务器测试SSL Labs的主要特性是服务器测试,这可以帮助网站访问

者审阅任何公开的Web服务器的配置。该测试包括一些其他网站

都没有的重要检查,并提供服务器配置的综合视图。等级系统也

很容易理解,可以帮助那些并非安全专家的人区分问题的大小。

测试中最有用的部分之一是模拟握手,它可以预测在大约40种

最广泛使用的程序和设备上的协商协议和加密套件。该功能可以

有效地猜测TLS配置。在我看来,该功能是不可缺少的。● 客户端测试客户端测试是一个较新的补充,并非众所周知,但是它仍然

非常有用,主要目的是帮助我们了解客户端在众多设备上的能

力。这个测试获得的结果将用于驱动服务器测试中的握手模拟器。● 最佳实践“SSL/TLS部署最佳实践”是一个简洁而合理的综合指南。

它为TLS服务器的配置提供了明确指导。这篇文档非常简短(英

文版约14页),能够让读者在短时间内吸收,并可以作为服务器

测试伴侣。● SSL Pulse最后,SSL Pulse的设计旨在监控整个SSL体系,并通知我

们整个体系的运转情况。它从2012年开始运作,专注于一个由

启用了TLS的网站组成的核心群体,而这些网站是从Alexa排行

前一百万的网站中选出来的。从那时起,SSL Pulse一直为这个

关键体系统计每月快照。

还有其他一些小的项目,读者可以从SSL Labs的网站上找到关于它们的更多信息。

在线资源

本书没有在线伴侣(虽然你可以认为SSL Labs就是),但是它确实有一个包含全书中引用文档的在线存储库:github.com/ivanr/bulletproof-tls。我会及时扩展这个存储库,使它容纳其他有用的内容作为本书的补充。

如果希望得到事件和消息通知,请在Twitter上关注@ivanristic。TLS是我在这些日子里的一切工作,我努力在这里通报每一件有关联的事件。这里几乎没有垃圾信息。此外,如果本书的内容有改进,我也会在Twitter上提醒大家。

我的博客地址是blog.ivanristic.com。我会在这里对SSL体系的重要新闻和发现作出回应,宣布SSL Labs的改进,公布我的研究。

如果你购买的是本书的英文电子版,那么可以随时重新登录你在Feisty Duck网站上的账户,下载最新的版本。一次购买包括对同一版次更新的无限次访问权限。你还可以选择在本书增加新内容或者发生某些非常重要的事情(比如,发现某个新的协议缺陷)时,收到临时电子邮件通知。

反馈

我很幸运,只要我想更新本书,就可以随时更新。这并不是一个巧合,我是专门这样做的。如果我今天修改了,经过每天的自动化构建,明天大家就能看到。更新纸质的书相对麻烦,不过有了按需印刷,我们可以在需要时发布修订版。

因此,与许多其他的书永远不会再版不同,读者的反馈可以影响本书。如果读者发现一处错误,那么几天之内这个错误就会得到修正。当然,对于小的改进也是一样,比如语法修改或者说明解释。如果某个平台在某些地方发生了变化,或者有新的发展,我也会跟踪到。我的目的是,只要读者有兴趣,我就会保持本书与时俱进。

请通过ivanr@webkreator.com写信给我。

关于作者

在这部分内容中,我会以第三人称介绍自己。这就是我的“官方”自传。Ivan Ristić是一位安全研究员、工程师、作者。他对于

Web应用防火墙领域的发展,开源Web应用防火墙

ModSecurity的开发,以及在SSL Labs网站上对SSL/TLS和

PKI的研究、工具和指南的发表,都作出了很大的贡献,因

此享誉世界。他写过Apache Security、ModSecurity Handbook和《HTTPS权威指南》三本书,并将其发表到Feisty Duck上。

Feisty Duck是他持续写作和发表的平台。Ivan是安全社区的

活跃参与者,经常在Black Hat、RSA、OWASP AppSec等

各种安全会议上进行演讲。他之前就职于Qualys公司,担任

应用安全研究主任。

我也应该提一下《OpenSSL攻略》,这是一本免费电子书,其中包含了本书第11章和第12章的内容,以及文档“SSL/TLS部署最佳实践”的内容。2

2这本小册子的中文版可在图灵社区本书主页(http://www.ituring.com.cn/book/1734)免费下载。——编者注

致谢

虽然这是我写的一本书,但我并不是唯一的作者。本书内容建立在分散于各种书籍、标准文档、研究论文、会议演讲、博客文章,甚至Twitter上有关加密和计算机安全的大量信息之上,多得令人难以置信。是上千人的工作成就了本书。

多年来,我有幸与许多在计算机安全领域的同仁共事,他们扩展了我在这方面的知识。他们中的很多人都帮助我审阅过部分手稿。我非常感谢他们的帮忙。本书的核心章节由许多高手帮我审阅,其中不乏那些设计标准或推翻标准的大师,也有我提到的程序开发者,这令我轻松了许多。

Kenny Paterson对第7章,也就是全书最长也是最复杂的一部分,进行了仔细的审阅,这使我受益匪浅。我认为他对待我就像对待他的学生一样,我的作品也因此有了很大的改进。我花了整整一周时间才按照Kenny的意见完成了内容修改。

Benne de Weger审阅了密码学和攻击PKI的相关章节。Nasko Oskov审阅了关于Microsoft协议实现的核心章节。来自Symantec的Rick Andrews和他的同事们帮忙审阅了第4章和第5章,此外Adam Langley也提供了帮助。Marc Stevens曾经针对PKI攻击,尤其是MD5和SHA1的选择前缀攻击写信给我。Nadhem AlFardan、Thai Duong和Juliano Rizzo审阅了第7章,并且回答了我关于他们工作的提问,非常有用。Ilya Grigorik对第9章的审查非常仔细,他的建议也非常有用。Jakob Schlyter对DANE有一种特别的关注,他审阅了关于进阶话题的章节(HSTS和CSP)。Rich Bowen和Jeff Trawick审阅了第13章,Jeff还修正了Apche中有关TLS的一些问题,这使我更加努力地跟上变化。Oracle的Xuelei Fan和Erik Costlow审阅了第14章,此外还有Mark Thomas、William Sargent和Jim Manico。Andrei Popov和Ryan Hurst审阅了第15章。Maxim Dounin总是很快地回答我对Nginx的问题,并且审阅了第16章。

Vincent Bernat的microbenchmarking工具在我写关于性能的第9章时起了很大作用。

Eric Lawrence发给我无数的注释和问题,我从没想到过我会遇到这样仔细的审阅人。Eric是每位作者所梦想的那种评论家,我非常感谢他严谨的态度。

同样,十分感谢我的读者,是你们给了我非常好的意见反馈:Pascal Cuoq、Joost van Dijk、Daniël van Eeden、Stephen N. Henson博士、Brian Howson、 Rainer Jung、Brian King、Hendrik Klinge、Olivier Levillain、Colm MacCárthaigh、Dave Novick、Pascal Messerli和Christian Sage。感谢你们!

我要特别感谢文字编辑Melinda Rankin,你总是能快速响应我的编辑要求,并将其并入基于DocBook的工作流。我还要感谢Qualys公司,感谢你们支持我的写作,支持SSL Labs的工作。 第1章SSL、TLS和密码学

我们生活在一个互联网时代。在20世纪的最后十年,互联网已经十分普及,并且永久性地改变了我们的生活方式。今天,我们依靠手机和计算机进行通信、购买商品、支付账单、旅行、工作,等等。很多人的口袋里总是装着处于开机状态的设备;我们并不只是连接到互联网,其实就是互联网的一部分。目前手机的数量已经超过了人口的数量。智能手机的数量已经达到数十亿,并且仍保持着快速增长。与此同时,诸多计划正酝酿将各种设备连接到同一网络。显然,这一切才刚刚开始。

所有连接到互联网的设备都有一个共同点,它们依赖安全套接字层(secure socket layer,SSL)和传输层安全(transport layer security,TLS)协议保护传输的信息。1.1 传输层安全

人们最初设计互联网时,很少考虑到安全。这样的结果是,核心通信协议本质上是不安全的,只能依靠所有参与方的诚信行为。互联网在早期由少数节点(大部分是大学)构成,那时这也许行得通;但现在所有人都可以连接到互联网,这种方式便土崩瓦解。

SSL和TLS都是加密协议,旨在基于不安全的基础设施提供安全通信。这意味着,如果正确部署这些协议,你就可以对互联网上的任意一个服务打开通信信道,并且可以确信你会与正确的服务器通信,安全地交换信息(你的数据不会被他人截取,而且在接收时会保持原样)。这些协议保护着通信链路即传输层,这也是TLS名称的由来。

安全不是TLS的唯一目标。TLS实际上有以下四个主要目标(按优先顺序排列)。● 加密安全这是主要问题:为任意愿意交换信息的双方启用安全通信。● 互操作性独立的编程人员应该能够使用通用的加密参数开发程序和

库,使它们可以相互通信。● 可扩展性你很快就会看到,TLS是一种能高效开发和部署加密协议的

框架。其重要目标是独立于实际使用的加密基元(例如密码和散

列函数),从而不需要创建新的协议,就允许从一个基元迁移到

另一个。● 效率最终的目标是在实现上述所有目标的基础上保持性能成本在

可接受的范围内。这需要尽量减少昂贵的加密操作的执行次数,

并提供一个会话缓存方案,以避免这些加密操作在随后的连接中

被执行。1.2 网络层

互联网的核心是建立在IP(internet protocol)和TCP(transmission control protocol)协议之上的,这些协议用于将数据分割成小数据包进行传输。这些数据包在全世界范围内历经数千里的传输,在此期间需要跨越许多国家的许多计算机系统(称为跃点,hop)。由于核心协议本身不提供任何安全保障,任何有权访问通信链路的人都可以获得所有数据,并且可以在不被察觉的情况下改变这些数据。

IP和TCP不是唯一易受攻击的协议,还有一系列其他路由协议用于协助发现网络上的其他计算机。DNS和BGP就是这样的两个协议。它们同样是不安全的,可以被他人通过各种方式劫持。如果出现这种情况,发往一台计算机的连接可能由攻击者响应。

如果部署了加密,攻击者也许有能力得到加密数据的访问权限,但是不能解密数据或者篡改数据。为了避免伪装攻击,SSL和TLS依赖另外一项被称为公钥基础设施(public key infrastructure,PKI)的重要技术,确保将流量发送到正确的接收端。

为了理解SSL和TLS的运作,我们需要从描述网络通信的理论模型入手,即开放系统互联(open systems interconnection,OSI)模型,参见表1-1。简单来说,所有功能都被映射到七个层上。最底层是最接近物理通信链路的层,后面的层依次建立在其他层之上,提供更高级别的抽象。最顶层就是应用层,携带着应用数据。

注意现实中的协议并非总能与OSI模型完全对应。比如

SPDY和HTTP/2因为要对连接进行管理,所以被归入会话层

协议,但它们却在数据加密以后生效。第五层及更高层的划

分经常是模糊的。表1-1 OSI模型层层号OSI层描述协议示例HTTP、7应用层应用数据SMTP、IMAPSSL/6表示层数据表示、转换和加密TLS-5会话层多连接管理TCP、4传输层包或流的可靠传输UDP网络节点间的路由与数据IP、3网络层分发IPSec数据链可靠的本地数据连接2以太网路层(LAN)直接物理数据连接(电1物理层CAT5缆)

以这种方式安排通信可以清晰地划分概念:高层的协议不必担心在底层实现的功能。进一步说,不同层次的协议可以加入通信或者从通信中删除,一种底层协议可以服务于多种上层协议。

SSL和TLS是这一原则如何在实践中运用的一个重要示例。它用于TCP协议之上,上层协议(如HTTP)之下。当不需要加密时,可以将TLS从模型中去掉,这并不会对上层协议产生影响(它们将直接与TCP协同工作)。当需要加密时,就可以利用TLS加密HTTP,以及其他TCP协议(比如SMTP、IMAP等)。1.3 协议历史

SSL协议由Netscape公司开发,历史可以追溯到Netscape Navigator浏览器统治互联网的时代1。协议的第一个版本从未发布过,第二版则于1994年11月发布。第一次部署是在Netscape Navigator 1.1浏览器上,发行于1995年3月。

1若想了解更详细的SSL协议早期历史,建议阅读Eric Rescorla的SSL and TLS: Designing and Building Secure Systems(Addison-Wesley出版社于2001年出版),第47~51页。

SSL 2的开发基本上没有与Netscape以外的安全专家进行过商讨,所以有严重的弱点,被认为是失败的协议,最终退出了历史的舞台。这次失败使Netscape专注于SSL 3,并于1995年年底发布。虽然名称与早先的协议版本相同,但SSL 3是完全重新设计的协议。该设计一直沿用到今天。

1996年5月,TLS工作组2成立,开始将SSL从Netscape迁移至IETF。由于Microsoft和Netscape当时正在为Web的统治权争得不可开交,整个迁移过程进行得非常缓慢、艰难。最终,TLS 1.0于1999年1月问世,见RFC 2246。尽管与SSL 3相比,版本修改并不大,但是为了取悦Microsoft,协议还是进行了更名3。

2TLS工作组,https://datatracker.ietf.org/wg/tls/documents/(IETF,检索于2014年6月23日)。

3Security Standards and Name Changes in the Browser Wars,http://tim.dierks.org/2014/05/security-standards-and-name-changes-in.html(Tim Dierks,2014年5月23日)。

直到2006年4月,下一个版本TLS 1.1才问世,仅仅修复了一些关键的安全问题。然而,协议的重要更改是作为TLS扩展于2003年6月发布的,并被集成到了协议中,这比大家的预期早了好几年。

2008年8月,TLS 1.2发布。该版本添加了对已验证加密的支持,并且基本上删除了协议说明中所有硬编码的安全基元,使协议完全弹性化。

协议的下一个版本正在开发过程中。该版本预计会成为一个主要版本,其目标是简化设计,除去安全性较弱或者不太需要的功能,并且提升性能。各位读者可以关注TLS工作组邮件列表的讨论4。

4TLS working group mailing list archives,http://www.ietf.org/mail-archive/web/tls/current/(IETF,检索于2014年7月19日)。1.4 密码学

密码学是一门通信安全的科学,同时也是一门艺术。虽然我们总是将密码学与现代联系在一起,但在上千年以前,人们事实上就已经开始利用它的力量了。考古发现,加密工具密码棒5首次被提及是在公元前7世纪。我们今天所知的密码学诞生于20世纪,用于军事领域;而它现在已经成为了我们日常生活的一部分。

5Scytale,https://en.wikipedia.org/wiki/Scytale(维基百科,检索于2014年6月5日)。

部署正确的密码能解决安全的三个核心需求:保持秘密(机密性)、验证身份(真实性),以及保证传输安全(完整性)。

本章剩余部分将对一个加密环境的基本构造进行讨论,展示安全性从何而来。同样,还会讨论加密体系通常是如何受到攻击的。密码学是一个非常多样化的领域,并且有非常深厚的数学基础。我会将视角保持在很宽泛的层面上,给大家介绍一些基础知识,使大家能够看懂后面的讨论。如果主题需要,我会在本书的其他部分更详细地介绍密码学的相关内容。

注意如果想花更多时间学习密码学,你可以找到很多文献。

我最喜欢的一本书是《深入浅出密码学》(Understanding

Cryptography,作者是Christof Paar和Jan Pelzl,2010年由

Springer出版)。1.4.1 构建基块

在最底层,使用密码加密依赖于各种加密基元(cryptographic primitive)。每种基元都着眼于某个特定功能而设计。比如,我们会使用某个基元加密,使用另外一个基元进行完整性检查。单个基元本身的作用并不大,但是我们可以将它们组合成方案(scheme)和协议(protocol),从而提供可靠的安全性。Alice和Bob是谁?讨论密码学时,我们为了方便起见,通常会使用Alice

和Bob这两个名字6。他们可以使枯燥的密码学命题变得更

加有趣一些。大家公认,Ron Rivest在1977年介绍RSA密码

系统的论文中,首次使用了这两个名字7。此后,又有其他

一些名字进入了密码学文化。在这一章中,我将一位具备窃

听能力的攻击者命名为Eve,并将另一位能够妨碍网络流量

的主动攻击者命名为Mallory。

6Alice and Bob,https://en.wikipedia.org/wiki/Alice_and_Bob(维基百科,检索于2014年6月5日)。

7Security's inseparable couple,http://www.networkworld.com/article/2318241/lan-wan/security-s-inseparable-couple.html(Network World,2005)。

1. 对称加密

对称加密(symmetric encryption)**(private-key cryptography),是一种混淆算法,能够让数据在非安全信道上进行安全通信。为了保证通信安全,Alice和Bob首先得到双方都认可的加密算法和密钥。当Alice需要向Bob发送数据时,她使用这个密钥加密数据。Bob使用相同的密钥解密。Eve能够访问信道,所以可以看到加密数据;但因为没有密钥,所以看不到原始数据。Alice和Bob只要能保证密钥安全,就能一直安全地通信,如图1-1所示。图 1-1 对称加密

注意讨论加密时通常会使用到三个术语:明文(plaintext,

即原始数据)、密钥(cipher,用于加密)和密文(ciphertext,即加密后的数据)。

对称加密可以追溯到上千年以前。比如,加密时将字母表中的每个字母替换成其他字母,解密时反向操作,这就是代替密码加密。在这个例子中,不存在密钥;安全性取决于保守加密方法的秘密。那就是最早的算法的例子。随着时间的流逝,我们采用了另一种方法。它是依照19世纪的一位密码破解专家Auguste Kerckhoffs的观察结果发展而来的8。

8la cryptographie militaire,http://petitcolas.net/kerckhoffs/(Fabien Petitcolas,检索于2014年6月1日)。即使攻击者知晓了整个密码系统除密钥以外的所有情

报,系统仍然应当能保证安全。

Kerckhoffs的原则初看起来有些奇怪,但如果继续深刻思考,就会觉得有道理,原因如下。● 如果一种加密算法要得到广泛使用,就必须让其他人知道。

当越来越多的人接触到这个算法,那么敌人得到这个算法的可能

性也会增加。● 没有密钥的简单算法非常不便于在大群体中使用;每个人都

可以解密所有人的通信。● 设计出优秀的加密算法非常困难。一种算法想要更安全,就

得经过更多的曝光和审视。当需要采用一种新算法时,密码学家

推荐使用保守的方法来确定算法是否安全,那就是算法需要经过

许多年的破解尝试。

优秀的加密算法需要产出表面上看来随机的密文,这样攻击者就无法分析得出任何关于明文的信息。比如,替换密码就不是一种好算法,因为攻击者可以确定密文中各个字母的使用频率,并将其与英语中的字母使用频率进行对比。因为某些字母比其他字母使用得更频繁,攻击者可以利用这个结果恢复明文。如果加密算法优秀,攻击者只有一种方法,那就是尝试所有可能的解码密钥,俗称穷举密钥搜索(exhaustive key search)。

基于这一点,我们可以说密文的安全性完全取决于密钥。如果密钥是从某个非常大的密钥空间中选取出来的,那么破解也需要遍历所有这些可能的密钥,其数量极大,几乎不可能。我们可以说这种算法在计算上是安全性的。

注意通常我们通过密钥长度来衡量加密强度;有一个假设

是,密钥本质上是随机的,所以密钥空间才可以由密钥的位

数来定义。比如,某个128位的密钥(被认为非常安全)有37

34×10种可能的组合。

密码可以分为两大类:序列密码和分组密码。● 序列密码从概念上讲,序列密码(stream cipher)的操作过程与我们

想象中加密的过程一致。将1字节的明文输入加密算法,就得到

1字节的密文输出。在对端则进行相反的过程。整个过程持续重

复,直到所有数据处理完成。序列密码的核心是生成一串称为密钥序列(keystream)的

无穷序列,看似杂乱无章。加密就是将密钥序列中的1字节与明

文序列中的1字节进行异或操作。因为异或操作是可逆的,所以

解密就是将密文序列中的1字节与密钥序列中的相同字节进行异

或操作。这个过程在图1-2中描述。图 1-2 RC4加密只要攻击者无法预测密钥序列中对应位置的字节,就可以认

为加密过程是安全的。基于这个理由,序列密码绝不能第二次使

用相同的密钥,这一点非常关键。这是因为在实际使用中,攻击

者知道或者可以预测特定区域的明文(请思考加密HTTP请求的

情景;许多请求的请求方法、协议版本、请求头名称都是一样

的)。当你知道明文,又观察到密文时,就可以解析一部分密钥

序列。如果使用了相同的密钥,那么就可以解密后续的部分密文。

为了解决这个问题,序列密码都与从长期密钥中提取出来的一次

性密钥一同使用。RC4是最为人熟知的序列密码9。因为它很快很简单,所以

一度非常流行。但是它已经不再安全。我将在7.5节中讨论它的

弱点。其他现代的安全序列密码则由ECRYPT Stream Cipher

Project10进行推进。● 分组密码分组密码(block cipher)每次加密一整块数据,并且现代

的分组密码倾向于使用128位(16字节)大小的块。一种分组密

码就是一个变换函数:接受输入并生成看似杂乱无章的输出。只

要使用相同的密钥,每一个可能的输入组合都有唯一的输出。分

组密码的关键特性是在输入上制造一个小变化(比如,在任意一

处变换1位),从而得到大量输出变体。分组密码本身不是非常有用,因为它们自身有一些限制。第

一个问题是,只能使用它们加密长度等于加密块大小的数据。因

此在实际使用分组算法时,需要一个方法处理任意长度的数据。

另一个问题是,分组密码是确定的。对于相同的输入,输出也是

相同的。这个特性会使许多攻击成为可能,需要解决。实践中,人们通过称为分组密码模式(block cipher mode)

的加密方案来使用分组密码。这种方案能规避这些限制,有时还

可以添加身份验证。分组密码也可以作为其他加密基元的基础来

使用,诸如散列函数、消息验证代码、伪随机数生成器,甚至序

列密码。世界上最流行的分组密码是高级加密标准(advanced

encryption standard,AES)11,可以使用128位、192位和256位

的加密强度。● 填充分组密码的挑战之一是处理数据长度小于加密块大小的数据

加密。举个例子,128位的AES需要16字节的输入数据并且产出

相同长度的输出。如果你的数据刚好能归入16字节的块中,那

正好。但如果不足16字节,怎么办?一种方法是追加额外的数

据到明文的尾部。这些额外的数据就被称为填充(padding)。填充不能由任何随机数据构成,它必须遵循某种格式,这样

接收方才可以发现填充并了解需要丢弃多少字节。在TLS中,加

密块的最后1字节包含填充长度,指示填充有多少字节(不包含

填充长度字节)。填充的每字节都被设置成与填充长度字节相同

的值,如图1-3所示。这种方式使得接收方能够检查填充是否正

确。为了在解密后丢弃填充,接收方检查数据块的最后1字节,

删除它。接着,接收方删除指定长度的字节数,同时检查它们是

否都是相同的值。图 1-3 TLS填充示例

9RC4,https://en.wikipedia.org/wiki/RC4(维基百科,检索于2014年6月1日)。

10eSTREAM: the ECRYPT Stream Cipher Project,http://www.ecrypt.eu.org/stream/(European Network of Excellence in Cryptology II,检索于2014年6月1日)。

11Advanced Encryption Standard,https://en.wikipedia.org/wiki/Advanced_Encryption_Standard(维基百科,检索于2014年6月1日)。

2. 散列函数

散列函数(hash function)是将任意长度的输入转化为定长输出的算法。散列函数的结果经常被简称为散列(hash)。编程中普遍使用散列函数,但并非所有散列函数都适用于密码学。密码学散列函数有以下几个额外特性。● 抗原像性(单向性)给定一个散列,计算上无法找到或者构造出生成它的消息。● 抗第二原像性(弱抗碰撞性)给定一条消息和它的散列,计算上无法找到一条不同的消息

具有相同的散列。● 强抗碰撞性计算上无法找到两条散列相同的消息。

散列函数最常用的使用场合是以紧凑的方式表示并比较大量数据。比如,为了避免直接比较两个文件(可能很难,比方说,它们存放于世界上不同的位置),你可以比较它们的散列。散列函数经常被称为指纹、消息摘要,或者简单称为摘要。

现在使用最为广泛的散列函数是SHA1,它的输出是160位。因为SHA1已经变弱,所以建议升级为SHA256的变种。与密码不同,散列函数的强度并不与散列长度对等。因为生日悖论(概率论中的常见问题)12,散列函数的强度最多只是散列长度的一半。

12Birthday problem,https://en.wikipedia.org/wiki/Birthday_problem(维基百科,检索于2014年6月1日)。

3. 消息验证代码

散列函数可以用于验证数据完整性,但仅在数据的散列与数据本身分开传输的条件下如此。否则攻击者可以同时修改数据和散列,从而轻易地避开检测。消息验证代码(message authentication code,MAC)或者使用密钥的散列(keyed-hash)是以身份验证扩展了散列函数的密码学函数。只有拥有散列密钥,才能生成合法的MAC。

MAC通常与加密一起使用。如果没有MAC,即使Mallory无法解码密文,她也能修改传输中的数据;加密提供了机密性但无法确保完整性。如果Mallory聪明到可以修改密文,她就可以诱使Bob接受并相信伪造的消息。当MAC和密文一起发送时,(和Alice共享散列密钥的)Bob就能确认消息并未遭到篡改。

任何散列函数都能用作MAC的基础,另一个基础是基于散列的消息验证代码(hash-based message authentication code,HMAC)13。HMAC本质就是将散列密钥和消息以一种安全的方式交织在一起。

13RFC 2104: HMAC: Keyed-Hashing for Message Authentication,http://tools.ietf.org/html/rfc2104(Krawczyk等,1997年2月)。

4. 分组密码模式

分组密码模式是为了加密任意长度的数据而设计的密码学方案,是对分组密码的扩展。所有分组密码模式都支持机密性,不过有些将其与身份验证联系起来。一些模式会将分组密码转换成序列密码。

它有许多输出模式,通常以首字母缩写来引用:ECB、CBC、CFB、OFB、CTR、GCM,诸如此类(不用担心这些缩写都代表什么)。我在这里只会介绍ECB和CBC:ECB是设计一种分组加密模式的反面例子,而CBC则仍是SSL和TLS的主要模式。GCM是TLS中相对较新的模式,从1.2版本开始才能使用。它提供了机密性和完整性,是当前可用的最好模式。● 电码本模式电码本(electronic codebook,ECB)模式是最简单的分组

密码模式。它只支持数据长度正好是块大小的整数倍的情况,如

果数据长度不满足这个条件,就得事先实施填充。加密就是将数

据按块大小切分,再分别加密每一块。ECB的简单就是它的劣势。因为分组密码是确定的(输入相

同,输出也相同),所以ECB也是如此。这就造成了严重的负面

结果:(1) 密文中出现的模式显示出明文中对应出现的模式;(2)

攻击者可以发现信息是否重复;(3) 攻击者可以观察密文并且提

交任意明文加密(在HTTP中通常是可能的,在一些其他情况下

也可以),如此尝试足够的次数,就能猜出明文。这就是针对

TLS的BEAST攻击的大致思路,7.2节会继续讨论。● 加密块链接模式加密块链接(cipher block chaining,CBC)模式是从ECB发

展而来的下一步。为了解决ECB天生的确定性,CBC引入了初始

向量(initialization vector,IV)的概念。即使输入相同,IV也可

以使每次的输出都不相同,如图1-4所示。整个过程开始于生成一个随机IV(因此不可预测),长度与

加密块相等。加密前,明文第一块内容与IV进行异或操作。这一

步对明文进行了掩饰,并保证密文总是不尽相同。对于下一个加

密块,使用上一块的密文作为IV,以此类推。这样一来,每次加

密操作都是同一个加密链条中的一部分,这也是这种模式名称的

由来。至关重要的是,IV必须通过线路传送到接收端,这个信息

是成功解密所必需的。

5. 非对称加密

对称加密在高速处理大量数据方面做得非常好,然而随着使用它的团体增加,产生了更多的需求,使得对称加密无法满足。● 相同团体的成员必须共享相同的密钥。越多人加入,团体密

钥出现问题的次数就越多。● 为了更好的安全性,你可以在每两个人之间使用不同的密

钥,但是这个方法不可扩展。虽然3个人只需要3个密钥,但10

个人就需要45(9+8+…+1)个密钥,而1000个人需要499 500个

密钥!● 对称加密不能用于访问安全数据的无人系统。因为使用相同

的密钥可以反转整个过程,这样的系统出现任何问题都会影响到

存储在系统中的所有数据。图 1-4 CBC模式加密

非对称加密(asymmetric encryption)又称为公钥加密(public key cryptography),它是另一种方法,使用两个密钥,而不是一个;其中一个密钥是私密的,另一个是公开的。顾名思义,一个密钥用于私人,另一个密钥将会被所有人共享。这两个密钥之间存在一些特殊的数学关系,使得密钥具备一些有用的特性。如果你利用某人的公钥加密数据,那么只有他们对应的私钥能够解密,如图1-5所示。从另一个方面讲,如果某人用私钥加密数据,任何人都可以利用对应的公钥解开消息。后面这种操作不提供机密性,但可以用作数字签名。图 1-5 非对称加密

非对称加密使得大规模团体的安全通信大幅简化。假设你可以广泛并且安全地分享你的公钥(PKI的工作将会在第3章中进行讨论),那么任何人都可以向你发送消息,只有你可以阅读。如果他们使用各自的私钥签名,你还可以精确地知道消息出自何人之手。

虽然公钥密码的属性非常有趣,但它却非常缓慢,不适用于数据量大的场景。因此,它往往被部署于进行身份验证和共享秘密的协商,这些秘密后续将用于快速的对称加密。

RSA(得名于三个人的姓氏首字母:Ron Rivest、Adi Shamir和Leonard Adleman)是目前最普遍部署的非对称加密算法14。现在推荐的RSA强度是2048位,强度等同于112位的对称密钥。我将会在本章稍后更加详细地讨论密码强度。

14RSA,https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29(维基百科,检索于2014年6月2日)。

6. 数字签名

数字签名(digital signature)是一个密码学方案。它使得验证一条电子消息或者一篇电子文档的真实性成为可能。前面描述的MAC就是一种电子签名,它可以利用事先安全交换的散列密钥验证真实性。虽然这种校验非常有用,但仍有不足,因为它仍然依赖于一个私有密钥。

借助公钥密码,数字签名可以与现实生活中的手写签名类似。我们可以利用公钥密码的非对称性设计出一种算法,使用私钥对消息进行签名,并使用对应的公钥验证它。

实际的方式依照选择的公钥密码体系而有所不同。下面以RSA为例。RSA可以用于加密,也可以用于解密。如果使用RSA私钥加密,那么仅能通过对应的公钥解密。我们可以利用这个性质,并且结合散列函数,实现数字签名。

(1) 计算希望签名的文档的散列。不论输入文档的长度如何,输出长度总是固定的。比如,使用SHA256就是256位。

(2) 对结果散列和一些额外的元数据进行编码。比如,接收方需要知道你使用的散列算法,否则不能处理签名。

(3) 使用私钥加密编码过的数据,其结果就是签名,可以追加到文档中作为身份验证的依据。

为了验证签名,接收方接收文档并使用相同的散列算法独立计算文档散列。接着,她使用公钥对消息进行解密,将散列解码出来,再确认使用的散列算法是否正确,解密出的散列是否与本地计算的相同。这个方案的强度取决于加密、散列以及编码组件各自的强度。

注意并非所有的数字签名算法都与RSA的工作方式一致。事

实上,RSA是一个特例,因为它可以同时用于加密和数字签

名。其他流行的公钥密码算法则不能用于加密,比如DSA和

ECDSA,它们依赖其他方式进行签名。

7. 随机数生成

在密码学中,所有的安全性都依赖于生成随机数的质量。在本章中,你已经看到,安全性构建于已知的算法和未知的密钥之上;而密钥最简单的形式就是非常长的随机数。

之所以说随机数不易生成,是因为计算机是十分善于预测的,它们会严格按照指令执行。如果告诉它生成一个随机数,它很可能做不好这项工作15。真正的随机数只能通过观测特定的物理处理器才能得到。没有的话,计算机将关注于收集少量的熵(entropy)。这通常意味着监视按键状态、鼠标移动,以及各种外设(比如硬盘)的交互情况。

15一些新型处理器内建了适于加密使用的随机数产生器。也有一些专业外设(比如,以闪存盘的形式)可以为操作系统提供额外的熵。

通过这种方式收集熵是一种真随机数生成器(true random number generator,TRNG),但是直接使用这种方式并不足够可靠。打个比方,你可能需要生成一个4096位的密钥,但是系统可能只有数百位的熵可用。如果没有可靠的外部事件可以收集到足够的熵,系统就可能会停止。

基于上面的原因,我们在实际使用中依靠的是伪随机数生成器(pseudorandom number generator,PRNG)。当然,PRNG也要利用少量真正的随机数使系统运转起来。这个过程被称为种子设定(seeding)。利用种子,PRNG根据需要构造出无限数量的伪随机数。普通用途的PRNG被常常用于编程,但它们并不适用于密码学,尽管其输出看起来就是随机的。加密安全伪随机数生成器(cryptographically secure pseudorandom number generator,CPRNG)是不可预测的PRNG。这个性质对安全来说非常关键,一定不能让攻击者对观察到的CPRNG输出进行内部状态的逆向工程。1.4.2 协议

加密基元本身其实没什么用,诸如加密和散列算法。我们只有将这些元素组合成方案和协议,才能满足复杂的安全需求。为了说明我们需要怎么做,先来看一个简化的密码协议,这个协议可以使Alice和Bob安全地通信。我们的目标是全部三个重要需求:机密性、完整性和真实性。

我们假设协议允许交换任意数量的消息。因为对称加密擅长对大量数据进行加密,所以选取我们最喜欢的AES算法来进行数据加密。使用AES,Alice和Bob可以安全地交换消息,Mallory看不到他们通信的内容。但是这还不够,因为Mallory还可以干其他事情,比如,神不知鬼不觉地修改消息。为了解决这个问题,我们使用只有Alice和Bob知道的散列密钥计算每个消息的MAC。在发送消息的同时,也发送消息的MAC。

现在,Mallory再也不能修改消息了。然而,她仍然可以丢弃或者重发任意消息。为了解决这个问题,我们扩展协议,为每条消息指定序号。最为重要的是,我们将序号作为MAC计算数据的一部分。如果发现序号出现空缺,就能知道消息丢了。如果我们发现序号出现重复,就检测重放攻击。为了得到最佳结果,我们应使用某个特殊消息来标记会话结束。如果没有这个消息,Mallory能够悄悄地结束(截断)会话。

如果所有措施都已到位,Mallory最多只能做到阻止Alice和Bob与其他人进行通信。我们对此无能为力。

到目前为止,一切都好,但是我们仍然有一大块缺失:Alice和Bob如何协商得到需要的两个密钥(一个用于加密,一个用于完整性验证),同时还要当心Mallory?我们通过为协议增加两个额外的步骤来解决这个问题。

首先,在会话的开始,我们使用公钥密码对会话双方进行身份验证。举个例子,Alice生成一个随机数,并要求Bob对其签名以证明真的是他。Bob也要求Alice做相同的事情。

除了身份验证之外,我们还可以使用密钥交换方案对加密密钥进行秘密协商。继续举例,Alice可以生成所有密钥,用Bob的公钥加密,再发送给Bob,这就是RSA密钥交换的工作方式。我们也可以使用Diffie-Hellman(DH)密钥交换协议作为替代。后者相对速度更慢,但提供了更多的安全特性。

最后,我们的协议完工时的状态是:(1) 以握手阶段开始,包括身份验证和密钥交换;(2) 接下来是数据交换阶段,保证机密性和完整性;(3) 以关闭序列结束。站在宏观的角度来看,我们的协议与SSL和TLS完成的工作相似。1.4.3 攻击密码

复杂系统往往会受到多种方式的攻击,密码系统也不例外。首先,你可以攻击加密基元本身。如果密钥很短,攻击者可以暴力破解。这种攻击通常需要相当多的运算能力和时间。对攻击者来说,如果系统使用的基元存在已知缺陷,他就可以使用解析攻击,从而更简单、更快地达成攻击目标。

人们一般都能很好地理解加密基元,因为它们相对直接,并且只完成一件工作。整体方案往往更容易遭受攻击,因为它们引入了额外的复杂性。在某些场景下,即使是密码学家也会争论执行特定操作的正确方法;但不论是基元还是方案,都比协议更安全。因为协议引入了更多的复杂性,并且攻击界面也大得多。

此外,也存在针对协议实现(implementation)的攻击;换言之,就是利用软件的bug。比如,绝大多数密码库都使用C甚至汇编这样的低级语言编写(出于性能的原因),非常容易引入灾难性的编程错误。即便没有这些bug,要实现基元、方案和协议,保证它们不被滥用,也需要很高的技巧。举个例子,某些算法的本地实现可以被计时攻击(timing attack)所利用,攻击者可以通过观察特定操作执行的时间破解加密。

有一种现象也非常普遍,那就是没有密码经验的程序员企图实现(甚至设计)加密协议和方案,理所应当地造成了不安全的结果。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书

若在网站上没有找合适的书籍,可联系网站客服获取,各类电子版图书资料皆有。

客服微信:xzh432

登入/注册
卧槽~你还有脸回来
没有账号? 忘记密码?