数百万的人在用Web进行私人事务处理,访问私有的数据。通过Web可以很方便地访问这些信息,但仅仅方便访问还是不够的。我们要保证只有特定的人能看到我们的敏感信息并且能够执行我们的特权事务。并不是所有的信息都能够公开发布的。
未授权的用户无法查看我们的在线旅游档案,也不能在未经许可情况下向Web站点发布文档,这会让我们感觉舒服一些。我们还要确保,组织中未经授权或不怀好意的成员无法获取那些最敏感的公司计划文档。我们与孩子、配偶以及暗恋对象的私人Web通信都是在带有些许隐私保护的情况下进行的,这样我们才能放心。
服务器需要通过某种方式来了解用户身份。一旦服务器知道了用户身份,就可以判定用户可以访问的事务和资源了。认证就意味着要证明你是谁。通常是通过提供用户名和密码来进行认证的。HTTP为认证提供了一种原生工具。尽管我们可以在HTTP的认证形式和cookie基础之上"运行自己的"认证工具,但在很多情况下,HTTP的原生认证功能就可以很好地满足需求。
HTTP的原生认证形式:
基本认证 basic authentication
缺点:明文传输
摘要认证 digest authentication
缺点:明文传输
缺点:可能遭到重放攻击
什么是摘要?摘要是“对信息主体的浓缩”。摘要是一种单向函数,主要用于将无限的输入值转换为有限的浓缩输出值。常见的摘要函数MD5,会将任意长度的字节序列转换为一个128位的摘要。128位等于2的128次方,最重要的是如果不知道原始密码的话,要想正确地猜出发送给服务器的摘要是非常困难的。同样,如果有摘要,想要判断出它是由无数输入值中的哪一个产生的,也是非常困难的。
MD5输出的128位的摘要通常会被写成32个十六进制的字符,每个字符表示4位。
常用的摘要算法有:
MD(Message Digest):消息摘要
MD2,MD4,
MD5: (了解MD5加盐技术)
SHA(Secure Hash Algorithm):安全散列
SHA-1 ,
SHA-2(SHA-256, SHA-224, SHA-512, SHA-384)
MAC:
MAC(Message Authentication Code):消息认证码
1 安全HTTP
人们会用Web事务来处理一些很重要的事情。如果没有强有力的安全保证,人们就无法安心地进行网络购物或使用银行业务。如果无法严格限制访问权限,公司就不可能将重要的文档放在Web服务器上。Web需要一种安全的HTTP形式。
基本认证和摘要认证,对大规模的购物、银行事务,或者对访问机密数据来说,并不足够强大。这些更为重要的事务需要将HTTP和数字加密技术结合起来使用,才能确保安全。
HTTP的安全版本要高效、可移植且易于管理,不但能够适应不断变化的情况而且还应该能满足社会和政府的各项要求。我们需要一种能够提供下列功能的HTTP安全技术。
1.服务器认证 (客户端知道是与真正服务器通话)
2.客户端认证 (服务器知道是与真正客户端通话)
3.完整性 (客户端与服务器的数据不会被修改)
4.加密(客户端与服务器的对话是私密的,无需担心被窃听)
5.效率
6.普适性 (基本上所有的客户端和服务器都支持这些协议)
…
1.1 HTTPS
HTTPS是最流行的HTTP安全形式,以https://开头,所有主要的浏览器和服务器都支持此协议。
使用HTTPS时,所有的HTTP请求和响应数据在发送到网络之前,都要进行加密。HTTPS在HTTP下面提供了一个传输级的密码安全层--可以使用SSL(或者其后继者传输层安全TLS),SSL和TLS非常类似。
大部分困难的编码和解码工作都是在SSL库完成的,所以Web客户端和服务器在使用安全HTTP时无需过多地修改其协议处理逻辑。在大多数情况下,只需要用SSL的输入/输出调用取代TCP的调用,再增加其他几个调用来配置和管理安全信息就行了。
1.2 数字加密
数字加密的简单介绍和术语:
-
报文/文本
未加密前的原始文本/二进制数据 -
密码(密码机/加密算法, 注意不是我们平时说的登录密码123456之类)
对报文/文本进行编码,使偷窥者无法识别的算法 -
密钥
改变密码行为的数字化参数 -
对称密钥加密系统
编/解码使用相同密钥的算法 -
非对称密钥加密系统
编/解码使用不同密钥的算法 -
公开密钥加密系统
一种能够使数百万计算机便捷地发送机密报文的系统 -
数字签名
用来验证报文未被伪造或篡改的校验和 -
数字证书
由一个可信的组织验证和签发的识别信息。
1.2.1 密码编制的机制和技巧
密码学是对报文进行编/解码的机制和技巧。人们用加密的方式来发送秘密信息已经有数千年的历史了。但密码学所能做的还不仅仅是加密报文以防止好事者的读取,我们还可以用它来防止对报文的篡改,甚至还可以用密码学来证明某条报文或某个事务确实出自你手,就像支票上手写的签名或信封上的压纹封蜡一样。
1.2.2 密码
密码学基于一种名为密码(cipher)的秘密代码。密码是一套编码方案,一种特殊的报文编码方式和一种稍后使用的相应解码方式的结合体。加密之前的原始报文通常被称为明文(plaintext或cleartext)。使用了密码之后的编码报文通常被称作密文(ciphertext)。
用密码来生成保密信息已经有数千年了。传说尤里乌斯.凯撒Julius Caesar曾使用过一种三字符旋转密码,报文中的每个字符都由字母表中三个位置之后的字符来取代。在现代的字母表中,'A’应该由’D’来取代,'B’应该由’E’来取代,以此类推。
比如,下面的图中,用rot3(旋转3字符)密码可以将报文"meet me at the pier at midnight"编码为"phhw ph dw wkh slhu dw plgqljkw"。通过解码,在字母表中旋转 -3个字符,就可以将密文解密回原来的明文报文。
1.2.3 密码机
最初,人们需要自己进行编码和解码,所以起初密码是相当简单的算法。因为密码很简单,所以人们通过纸笔和密码书就可以进行编解码了,但聪明人也可以相当容易地破解这些密码。
随着技术的进步,人们开始制造一些机器,这些机器可以用复杂得多的密码来快速、精确地对报文进行编解码。这些密码机不仅能做一些简单的旋转,它们还可以替换字符、改变字符顺序,将报文切片切块,使代码的破解更加困难。
1.2.4 使用了密钥的密码
编码算法和编码机都可能会落入敌人的手中,所以大部分机器上都有一些号盘,可以将其设置为大量不同的值以改变密码的工作方式,即使机器被盗,没有正确的号盘设置(密钥值),解码器也无法工作。
这些密码参数被称为密钥(key),要在密码机输入正确的密钥,解密过程才能正确进行。密码密钥会让一个密码机看起来好像是多个虚拟密码机一样,每个密码机都有不同的密钥值,因此其行为都会有所不同。
图14-5显示了使用密钥的密码实例。加密算法就是普通的“旋转-N字符”密码。N的值由密钥控制。将同一条输入报文"meet me at the pier at midnight"通过同一台密码机进行传输,会随密钥值的不同产生不同的输出。现在基本上所有的加密算法都会使用密钥。
1.2.4 数字密码
随着数字计算的出现,出现了以下两个主要的进展。
- 从机械设备的速度和功能限制中解放出来,使复杂的编/解码算法成为可能。
- 支持超大密钥成为可能,这样可以从同一个加密算法产生出数万亿的虚拟加密算法,由不同的密钥来区分不同的算法。密钥越长,编码组合就越多,通过随机猜测密钥来破解代码就越困难。
与金属钥匙或机械设备中的号盘设置相比,数字密钥只是一些数字。这些数字密钥值是编/解码算法的输入。编码算法就是一些函数,这些函数会读取一块数据,并根据算法和密钥值对其进行编/解码。
给定一段明文报文P、一个编码函数E和一个数字编码密钥e,就可以生成一段经过编码的密文C(图14-6)。通过解码函数D和解码密钥d,可以将密文C解码为原始的明文P。当然,编/解码函数都是互为反函数的,对P的编码进行解码就会回到原始报文P上去。
1.3 对称密钥加密技术
我们来更详细地看看密钥和密码是怎样配合工作的。很多数字加密算法都被称为*对称密钥(symmetric-key)*加密技术,这是因为它们在编码时使用的密钥值和解码时的一样(e==d)。我们就将其统称为密钥k。
在对称密钥加密技术中,发送端和接收端要共享相同的密钥k才能进行通信。发送端用k来加密报文,并将得到的密文发送给接收端。接收端收到密文,使用解密函数和密钥k,恢复出原始的明文。
以前的对称密钥加密算法有DES, Triple-DES,RC2,RC4, 现在流行的为AES。
1.3.1 密钥长度和枚举攻击
保持密钥的机密状态是很重要的。在很多情况下,编/解码算法都是众所周知的,因此密钥就是唯一保密的东西了。
好的加密算法会迫使攻击者试遍每一个可能的密钥,才能破解代码。用暴力去尝试所有的密钥值称为枚举攻击(enumeration attack),如果只有少量的可能密钥值,居心不良的人通过暴力遍历所有值,就能最终破解代码了。但如果有大量可能的密钥值,他可能要花费数天、数年,甚至无限长的时间来遍历所有的密钥值,取查找能够破解密码的那一个。
可用的密钥值的数量取决于密钥中的位数,以及可能的密钥中有多少是有效的。就对称密钥加密技术来说,通常所有的密钥值都是有效的,128位的密钥可以产生2的128次方数量的密钥。而RSA不是所有的密钥都有效。
1.3.2 建立共享密钥
对称密钥加密技术的缺点之一就是发送者和接收者在互相对话之前,一定要有一个共享的保密密钥。如果Joe提供一个服务器, A, B, C都想与Joe交换数据,Joe就得管理3个密钥,如果有N个人,管理这么多密钥都是一个噩梦。
1.4 公开密钥加密技术
公开密钥加密技术没有为每队主机使用单独的加密/解密密钥,而是使用了两个非对称密钥:一个用来对主机报文编码,另一个用来对主机报文解码。编码密钥是众所周知的,但只有主机才知道私有的解密密钥。这样,每个人都能找到某个特定主机的公开密钥,密钥的建立变得更加简单。但解码密钥是保密的,因此只有接收端才能对发送给它的报文进行解码。
通过公开密钥加密技术,全球所有的计算机用户就都可以使用安全协议了。制定标准化的公开密钥技术包是非常重要的。因此,大规模的公开密钥架构(Public-Key Infrastructure, PKI)标准创建工作已经开展很多年了。
1.4.1 RSA
所有公开密钥非对称加密系统所面临的共同挑战是,要确保即便有人拥有了下面所有的线索,也无法计算出保密的私有密钥:
- 公开密钥 (是公有的,任何都可以获得)
- 一小片拦截下来的密文 (可通过对网络的嗅探获取)
- 一条报文及与之相关的密文 (对任意一段文本运行加密器就可以得到)
RSA算法就是一个满足了所有这些条件的流行的公开密钥加密系统,它是在MIT发明的,后来由RSA数据安全公司将其商业化。即便有了公开密钥、任意一段明文、用公共密钥对明文编码之后得到的相关密文、RSA算法自身,甚至RSA实现的源代码,破解代码找到相应的私有密钥的难度仍相当于对一个极大的数进行质因数分解的困难程度,这种计算被认为是所有计算机科学中最难的问题之一。因此,如果你发现了一种能够快速地将一个极大的数字分解为质因数分解的方法,就不仅能够入侵瑞士银行的账户系统,而且还可以获得图灵奖了。
RSA加密技术的细节中包括很多繁琐的数学问题,我们的介绍不会那么深入。你不需要拥有数论方面的博士学位,有大量的库可以用来执行RSA算法。
1.4.2 混合加密系统和会话密钥
任何人只有知道了其公开密钥,就可以向一台公共服务器发送安全报文,所以非对称的公开密钥加密系统是很好用的。两个节点无需为了进行安全通信而先交换私有密钥。
但公开密钥加密算法的计算可能会很慢。实际上它混合使用了对称和非对称策略。比如,比较常见的做法是在两个节点间通过便捷的公开密钥加密技术建立起安全通信,然后再用那条安全的通道产生并发送临时的随机对称密钥,通过更快的对称加密技术对其余的数据进行加密。
1.5 数字签名
除了加/解密报文之外,还可以用加密系统对报文进行签名(sign),以说明是谁编写的报文,同时证明报文未被篡改过。这种技术称为数字签名(digital signing),对因特网安全证书系统来说非常重要。
1.5.1 签名是加了密的校验和
数字签名是附加在报文上的特殊加密校验码。使用数字签名有以下两个好处:
- 签名可以证明是作者编写了这条报文。只有作者才会有最机密的私有密钥,因此,只有作者才能计算出这些校验和。校验和就像来自作者的“个人签名”一样。
- 签名可以防止报文被篡改。如果有恶意攻击者在报文传输过程中对其进行了修改,校验和就不再匹配了。由于校验和只有作者保密的私有密钥才能产生,所有攻击者无法为篡改了的报文伪造出正确的校验和。
数字签名通常是用非对称公开密钥系统技术产生的。因为只有所有者才知道其私有密钥,所以可以将作者的私有密钥当做一种"指纹"使用。
图14-10显示了一个例子,说明了节点A是如何向节点B发送一条报文,并对其进行签名的。假设初始时,节点A具有私有密钥,节点B具有公开密钥。
- 节点A将报文提取为定长的摘要
- 节点A对摘要应用了一个"签名"函数,这个函数会将用户的私有密钥作为参数。因为只有用户才知道私有密钥,所有正确的签名函数会说明签名者就是其所有者。在图14-10中,由于解码函数D中包含了用户的私有密钥,所有我们将其作为签名函数使用.
- 一旦计算出签名,节点A就将其附加在报文的末尾,并将报文和签名都发送给节点B
- 如果节点B需要确定报文就是节点A写的,而且没有被篡改过,节点B就可以对签名进行检查.节点B将接收到的签名、公开密钥输入反函数,如果反函数输出得到的摘要与节点B自己计算出的摘要不匹配,表明要么就是报文在传输过程中被篡改了,要么就是发送端没有节点A的私有密钥(也就是说它不是节点A)
1.6 数字证书
本节将介绍因特网上的数字证书。数字证书(通常被称作certs)中包含了由某个受信任组织担保的用户或公司的相关信息。
数字证书就是一种证明, 证明拥有这张证书的人的可信程度。举个例子,数字证书跟身份证一样,用来证明某人的身份。如果拿到一张身份证,怎样知道它是不是可信的呢?我们通过扫描它内部由公安机关打进去的防伪信息,这里相当于我们相信了公安机关这个第三方组织。同理,数字证书内部也有第三方认证机构(CA, Certification Authority)的签名,因此也是可信任的。
1.6.1 证书的主要内容
数字证书中还包含一组信息,所有这些信息都是由一个官方的“证书颁发结构CA”以数字方式签发的。基本的数字证书中通常包含一些纸质证明中常见的内容,比如:
- 对象的名称 (人、服务器、组织等)
- 过期时间
- 证书发布者(由谁为证书担保)
- 来自证书发布者的数字签名
而且,数字证书通常还包括对象的公开密钥,以及对象和所用签名算法的描述性信息。任何人都可以创建一个数字证书,但并不是所有人都能够获得受人信任的签发权,从而为证书信息担保,并用其私有密钥签发证书。
典型的证书结构如图14-11所示:
1.6.2 X.509 v3证书
大多数证书都以一种标准格式 X.509 v3格式,来存储它们的信息。X.509 v3证书提供了一种标准方式,将证书信息规范至一些可解析的字段中。不同类型的证书有不同的字段值,但大部分都遵循X.509 v3结构。表14-2介绍了X.509证书中的字段信息。
基于X.509证书的签名有好几种,包括Web服务器证书、客户端电子邮件证书、软件代码签名证书和证书颁发机构证书。
1.6.3 用证书对服务器进行认证
通过HTTPS建立了一个安全Web事务之后,现代的浏览器都会自动获取所连接服务器的数字证书。如果服务器没有证书,安全连接就会失败。服务器证书中包含很多字段,其中包括:
- Web站点的名称和主机名
- Web站点的公开密钥
- 签名颁发结构的名称
- 来自签名颁发结构的签名
浏览器收到证书时会对签名颁发结构进行检查。如果这个结构是个很有权威的公共签名结构,浏览器可能已经知道其公开密钥了(浏览器会预先安装很多签名颁发结构的证书)。这样,就可以像前面那样验证签名了。如果对签名颁发结构一无所知,浏览器就无法确定是否应该信任这个签名颁发结构,它通常会向用户显示一个提示框。图14-12说明了如何通过对其数字签名来验证证书的完整性。
1.7 HTTPS----细节介绍
HTTPS是最常见的HTTP安全版本。它得到了很广泛的应用,所有主要的商业浏览器和服务器上都提供HTTPS。HTTPS将HTTP协议与一组强大的对称、非对称和基于证书的加密技术结合在一起,使得HTTPS不仅很安全,而且很灵活,很容易在处于无序状态的、分散的全球互联网上进行管理。
HTTPS加速了因特网应用程序的成长,已经成为基于Web的电子商务快速成长的主要推动力。在广域网对分布式Web应用程序的安全管理方面,HTTPS也是非常重要的。
1.7.1 HTTPS概述
HTTPS就是在安全的传输层上发送的HTTP。HTTPS没有将未加密的HTTP报文发送给TCP(图14-13a),并通过世界范围内的因特网进行传输,它在HTTP发送给TCP之前,先将其发送给了一个安全层,并对其进行加密(图14-13b)。
现在,HTTP安全层是通过SSL协议及其现代替代协议TLS来实现的。
1.7.2 HTTPS方案
现在,安全HTTP是可选的。因此,对Web服务器发起请求时,我们需要一种方式来告知Web服务器去执行HTTP的安全协议版本。这是在URL的方案中实现的。
普通的HTTP请求,URL前缀为http,如下所示:
http://www.joes-hardware.com/index.html
而在安全HTTPS请求,URL前缀为https,如下所示:
https://www.baidu.com
客户端对某Web资源执行事务时,它会去检查URL的方案。
- 如果URL的方案为http,客户端会打开一条到服务器80端口的连接,并向其发送普通的HTTP协议命令(图14-14a)
- 如果URL的方案为https,客户端会打开一条到服务器443端口的连接,然后与服务器“握手”,以二进制格式与服务器交换一些SSL安全参数,附上加密的HTTP命令(图14-14b)
SSL是个二进制协议,与HTTP完全不同,其流量是承载在另一个端口443上的。如果SSL和HTTP流量都从端口80到达,大部分Web服务器会将二进制SSL理解为错误的HTTP并关闭连接。将安全服务进一步整合到HTTP层中去就无需使用多个目的端口了,在实际中这样不会引发严重的问题。
我们来详细介绍下SSL是如何与安全服务器建立连接的。
1.7.3 建立安全传输
在未加密的HTTP中,客户端会打开一条到Web服务器端口80的TCP连接,发送一条请求报文,接收一条响应报文,关闭连接(图14-15a)。
由于SSL安全层的存在,HTTPS中这个过程会略微复杂一些。在HTTPS中,客户端首先打开一条到Web服务器端口443的连接。一旦建立了TCP连接,客户端和服务器会初始化SSL层,对加密参数进行沟通,并交换密钥。握手完成之后,SSL初始化就完成了,客户端就可以将请求报文发送给安全层了。在将这些报文发送给TCP之前,要先对其进行加密(图14-15b)。
1.7.4 SSL握手
在发送已加密的HTTP报文之前,客户端和服务器要进行一次SSL握手,在这个握手过程中,它们要完成以下工作:
- 交换协议版本号
- 选择一个两端都了解的密码
- 对两端的身份进行认证
- 生成临时的会话密钥,以便加密信道。
通过网络传输任何已加密的HTTP数据之前,SSL已经发送了一组握手数据来建立通信连接了(图14-16)。这是SSL握手的简化版本。根据SSL的使用方式,握手过程可能会复杂一些,但总的思想就是这样。
1.7.5 服务器证书
SSL支持双向认证,将服务器的证书承载会客户端,再将客户端的证书回送给服务器。而现在,浏览时并不经常使用客户端证书。大部分用户甚至都没有自己的客户端证书。服务器可以要求使用客户端证书,但实际中很少出现这种情况(一些高安全场景需要,例如银行事务)。
另一方面,安全HTTPS事务总是要求使用服务器证书的。在一个Web服务器上执行安全事务,比如提交银行账号信息时,你总是希望是在与你所认为的那个组织对话。由知名权威机构签发的服务器证书可以帮助你在发送私人信息之前评估你对服务器的信任度。
服务器证书是一个显示了组织的名称、地址、服务器DNS域名以及其他信息的X.509 v3派生证书(图14-17)。你和你所用的客户端软件可以检查证书,以确保所有的信息都是可信的。
1.7.6 服务器证书的有效性
SSL自身不要求用户检查Web服务器证书,但大部分现代浏览器都会对证书进行简单的完整性检查,并为用户提供进一步彻查的手段。网景公司提出的一种Web服务器证书有效性算法是大部分浏览器有效性验证技术的基础。验证步骤如下:
- 日期检测
首先,浏览器检查证书的起始日期和结束日期,以确保证书仍然有效。如果是证书过期了,或者还未被激活,则证书有效性验证失败,浏览器显示一条错误信息。 - 签名颁发者可信度检测
每个证书都是由某些证书颁发机构(CA), 它们负责为服务器保证。证书有不同的等级,每种证书都要求不同级别的背景验证。比如,如果申请某个电子商务服务器证书,通常需要提供一个营业的合法证明。
任何人都可以生成证书,但有些CA是非常著名的组织,它们通过非常清晰的流程来验证申请人的身份及商业行为的合法性。因此,浏览器会内置一个签名颁发结构的信任列表。如果浏览器收到了某个未知(可能是恶意的)颁发机构签发的证书,那它通常会显示一条警告信息。有些证书会携带到受信CA的有效签名路径,浏览器会选择接受所有此类证书。换句话说,如果某受信CA为"Sam的签名商店"签发了一个证书,而Sam的签名商店也签发了一个站点证书,浏览器可能会将其作为从有效CA路径导出的证书接受。 - 签名检测
一旦判定签名授权是可信的,浏览器就要对签名使用签名颁发结构的公开密钥,并将其与校验码进行比较,以查看证书的完整性。 - 站点身份检测
为防止服务器复制其他人的证书,或拦截其他人的流量,大部分浏览器都会试着去验证证书中的域名与它们所对话的服务器的域名是否匹配。服务器证书中通常都包含一个域名,但有效CA会为一组或一群服务器创建一些包含了服务器名称列表或通配符域名的证书。如果主机名与证书中的标识符不匹配,客户端要么通知用户,要么终止连接并返回证书不正确的信息。
1.7.7 简单的HTTPS客户端
OpenSSL开源库, http://www.openssl.org