SSL 如何工作
SSL 是有效的原因之一是,它使用几种不同的加密过程。SSL 使用公开密匙加密方式来提供身份验证和密钥加密技术与数字签名来提供隐私和数据的完整性。在你能理解 SSL 之前,它有助于理解这些加密过程。
加密过程
密码学的主要目的是让一个未经授权的第三方难以访问和理解双方私人之间的通信。虽然并不总是限制所有未经授权的访问数据,但私人数据应可以通过加密的过程的对于未授权方来说应该是隐蔽的。加密使用复杂的算法将原始消息(明文)编码为加密信息(密文)。加密和解密的算法在网络上传输的数据,通常有两类:密钥加密和公开密钥加密。下面将详细介绍这些形式的加密。
密钥加密和公开密钥加密依赖达成一致的密钥的使用或密钥对。一个密钥是一个字符串使用的密码算法或算法过程中加密和解密的数据。密钥就像锁的钥匙,只有正确的钥匙可以打开锁。
交际双方之间安全地传输的密钥并不是一件小事。公钥证书使一方能够安全地传输它的公钥,同时确保接收者的公钥的真实性。公钥证书在后面一节中描述。
加密过程的描述,使用安全社区广泛使用的约定:交际双方都贴上名字 Alice 和 Bob 。未经授权的第三方,即攻击者,叫 Charlie。
密钥加密技术
在密钥加密技术中,交流的双发 Alice 和 Bob,使用相同的密钥来加密和解密消息。在加密的数据可以通过网络发送之前,Alice 和 Bob 都必须拥有密码,并且他们将用于加密和解密的密码算法必须是一致的。
密钥加密技术的一个主要问题是如何保证密钥是从一方传递到另一个,且中间确保不允许攻击者访问。如果是用密钥加密技术保护他们的数据,如果 Charlie 获得访问他们的密钥,那么 Charlie 就能理解从 Alice 和 Bob 之间拦截的任何秘密信息。Charlie 不仅可以解密 Alice 和 Bob 的消息,而且他也可以假装他是 Alice 来向 Bob 发送加密数据。Bob 将不知道该消息来自 Charlie,不是 Alice。
一旦解决了密钥分配的问题,密钥加密技术还是一个有价值的工具。算法提供优秀的安全性并且加密数据的速度相对迅速。 大多数时候在一个 SSL 会话发送使用密钥加密技术发送敏感数据。
密钥加密技术也称为对称加密,因为使用相同的密钥来加密和解密数据。众所周知的秘密密钥加密算法包括 Data Encryption Standard (DES), Triple DES (3DES), Rivest Cipher 2 (RC2), 和 Rivest Cipher 4 (RC4)
公开密钥加密
公开密钥加密的使用一个公钥和一个私钥来解决密钥分发问题。公钥可以通过公开网络发送,而私钥是由通信一方的保管。公钥和私钥的作用是相反的,一个用于加密,另一个用于解密。
假设 Bob 想发送一个秘密消息 Alice ,则他使用公钥加密。Alice 有一个公钥和一个私钥,所以她把她的私钥在一个安全的地方,然后把公钥传给 Bob。Bob 用 Alice 的公钥来加密给 Alice 消息。Alice 稍后就能用她的私钥来解密该消息。
如果 Alice 使用自己的私钥加密消息并发送加密消息给 Bob,Bob 可以确保他收到的数据来自 Alice;如果 Bob 可以用 Alice 的公钥解密数据,则说明该消息一定是被 Alice 用她的私钥加密,并且只有 Alice 有 Alice 的私钥。问题是,任何人都可以读取这个消息,因为 Alice 的公钥是公开的。尽管这个场景不允许安全的数据通信,但它提供了数字签名的基础。数字签名是公钥证书的一个组成部分,用于 SSL 对客户机或服务器进行身份验证。在后面部分会介绍了公钥证书和数字签名。
公开密钥加密也被称为 asymmetric cryptography(非对称加密),因为不同的密钥用于加密和解密数据。常用与 SSL 的一个著名的使用公钥加密算法是 Rivest Shamir Adleman (RSA) 算法。另一个 Diffie-Hellman (DH) 算法常用于 SSL 的密钥交换。公开密钥加密需要大量的计算,所以会非常缓慢。因此通常仅用于加密小块的数据,如密钥,而不是批量加密数据通信。
比较密钥加密和公开密钥加密
密钥加密和公开密钥加密各有优点和缺点。密钥加密技术,可以快速加密和解密数据,但由于通信双方都必须共享相同的密钥信息,密钥的交换可能是一个问题。公开密钥加密,密钥交换并不是一个问题,因为不需要公钥保密的,但是算法用于加密和解密数据需要大量的计算,因此非常缓慢。
公钥证书
公钥证书提供了一个安全的方法,在非对称加密中传递公开密钥。公钥证书,避免了以下情况:如果 Charlie 创造了他自己的公钥和私钥,他可以伪装他是 Alice 并发送公钥给 Bob。Bob 将能够与 Charlie 通讯,但Bob 会认为他是把他的数据传给了 Alice。
一个公钥证书可以被认为是一个数字相当于一个护照。它是由一个值得信任的组织 Certificate Authority (CA,证书颁发机构)发出,并提供身份的识别。CA 的一个值得信赖的组织。可以比作一个公证人。为了从 CA 中获得一个证书,必须提供身份证明。一旦 CA 确认了申请人就是代表它所述的组表,则 CA 就能签署包含了有效的信息的证书。
公钥证书包含以下字段:
- Issuer (发行者):
CA 是发行证书的。如果用户信任 CA 发行的证书,并且证书是有效的,那么用户可以信任证书 - Period of validity(有效期):
证书是有失效日期的。当验证证书的有效性时,需检查这个日期。 - Subject:
包括证书代表的实体信息。 - Subject’s public key (Subject 的公钥):
证书提供的主要信息是 Subject 的公钥。提供所有其他字段,是为了确保这个密钥的有效性。 - Signature(签名):
证书由 CA 进行数字签名后颁发。证书签名是使用 CA 私钥创建的,并确保证书的有效性。因为只有证书是签名的,而在 SSL 中传输的数据并没有,所以 SSL 不提供 nonrepudiation (不可抵赖性)。
因为 Bob 只接受 Alice 发送在公钥证书的有效的公钥,因此当 Charlie 伪装成 Alice时, Bob 不会被欺骗而发送秘密信息给 Charlie 。
证书链中可链接多个证书。当使用证书链时,第一个证书始终是发送者的。下一个是实体证书颁发的发布者的证书。如果有更多的证书在链中,那么每个是颁发前一个证书的权限。链中的最后一个证书是一个 CA 的证书。根 CA 是一个被广泛信任的公共证书颁发机构。一般的,根 CA 的信息是存储在客户端的互联网浏览器。此信息包括 CA 的公钥。众所周知的 CA 包括VeriSign, Entrust, 和 GTE CyberTrust。
加密散列函数
发送加密数据时,SSL 通常使用加密散列函数来确保数据的完整性。散列函数阻止 Charlie 篡改 Alice 发送给 Bob 的数据。
密码散列函数类似于一个校验和。主要的区别在于,一个校验和的目的是检测意外改变数据,而加散列函数是用来检测刻意改变。当数据是由加密散列函数处理,将会生成一小串字符串,称为一个散列。一个微小的改变通常会使生成的散列发生大的改变。加码散列函数不需要密钥。SSL 经常使用的两个散列函数是 Message Digest 5 (MD5) 和 Secure Hash Algorithm (SHA)。SHA 是由 U.S. National Institute of Standards and Technology (NIST) 提出。
消息验证码
消息验证码(MAC)是类似于加密散列,除了它是基于一个密钥。当密钥信息被包含密码散列函数处理的数据,然后得到的散列被称为一个 HMAC。
如果 Alice 希望确保 Charlie 没有篡改 她发送给 Bob 的消息,那么她就可以计算一个她消息的 HMAC,并追加 HMAC 到她的原始消息中。然后,她可以使用共享给 Bob 密钥加密附加了 HMAC 的消息。当 Bob 解密该消息,并计算 HMAC,他就能被告知消息在传输过程中是否被修改。在使用SSL 时,HMAC 是用于加密数据的传输。
数字签名
一旦加密散列创建一个消息,这个散列是用发送者的私钥加密的。这个加密的散列称为数字签名。
SSL 握手
使用 SSL 通信始于一个客户端和服务器之间的信息交换。这种信息交流被称为 SSL 握手。SSL 握手包括以下几个阶段:
1.协商密码套件
SSL 会话开始于一个客户端与服务器之间的协商,他们将使用的密码套件。密码套件是一组加密算法和密钥大小,可以用来加密数据。该密码套件包括公共密钥交换算法或密钥协商算法的信息,以及加密散列函数。客户端告诉服务器哪些是可用的密码套件,服务器选择最可接受的密码套件。
2.认证服务器的身份(可选)
在 SSL,认证步骤是可选的,但在电子商务交易的例子,在网上,客户一般会想验证服务器。认证服务器允许客户端确认服务器代表实体就是客户认为的那个。
为了证明一个服务器属于它声称的组织,服务器向客户端提供其公钥证书。如果这个证书是有效的,那么客户端可以确定服务器的身份。
客户端和服务器交换信息,允许他们在相同的密钥上达成一致。例如,与RSA,客户端使用从公钥证书的取得服务器的公钥,来加密密钥信息。客户端向服务器发送加密的密匙信息。只有服务器才能解密该消息,因为该解密所需的服务器私钥是加密该消息的。
3.同意加密机制
客户端和服务器都可以访问同一个密钥。每一个消息,他们都使用的加密散列函数和在握手的第一步选择和加密散列算法以及共享的秘密信息,来计算附加到消息 HMAC。然后他们使用密钥和在握手的第一步秘协商的密钥算法来对安全数据和 HMAC 加密。客户端和服务器就可以安全的使用他们的加密和散列数据进行交互了。
SSL 协议
前一节中提供的 SSL 握手的一个高层次的描述,这是发送加密信息之前,客户端和服务器之间的信息交换。本节提供更多细节。
图1显示的是在SSL握手交换消息的序列。仅在某些情况下被发送的消息是 optional (可选的)。每个 SSL 信息如下图。
Figure 1: Sequence of Messages Exchanged in SSL Handshake
The SSL messages are sent in the following order:
1.Client hello
客户端发送服务器的信息,包括最高版本的SSL,它支持一个密码套件列表,它支持(如 TLS 1.0 代表 SSL 3.1)。密码套件的信息包括加密算法和密钥大小。
2.Server hello
服务器选择SSL最高版本和最好的密码套件,客户端和服务器都支持并将此信息发送到客户端。
3.Certificate (optional) 证书
服务器给发送客户端证书或证书链。证书链通常从服务器的公钥证书开始,并以证书颁发机构的根证书结束。此消息是可选的,但在需要服务器身份验证时使用。
4.Certificate request (optional) 证书请求
如果服务器必须对客户端进行身份验证,那么它就会向客户端发送证书请求。在互联网应用中,这一消息很少被发送。
5.Server key exchange (optional) 服务器密钥交换
如果证书的公钥信息不足以用于密钥交换,服务器向客户端发送一个服务器密钥交换信息。例如,在基于 Diffie-Hellman (DH)密码套件,该消息包含服务器的 DH 公钥。
6.Server hello done
服务器告诉客户端已经完成了初步协商消息。
7.Certificate (optional) 证书
如果服务器请求来自客户端的证书,那么客户端发送它的证书链给服务器,正如服务器之前做的一样。
注:只有少数几个互联网服务器应用程序要求客户端的证书。
8.Client key exchange 客户密钥交换
该客户端生成用于创建一个密钥以用于对称加密的信息。对于 RSA 来说,然后客户机用服务器的公钥加密密钥信息并将其发送给服务器。密码套件基于DH,该消息包含客户机的 DH 公钥。
9.Certificate verify (optional) 证书验证
该消息由客户端发送,客户端提供如前所述证书。其目的是允许服务器以完成认证所述客户端。当使用此消息时,客户端发送的信息将使用加密散列函数进行数字签名。当服务器用客户端的公钥解密该信息时,该服务器就能够验证客户端。
10.Change cipher spec 更改加密规范
客户端发送消息告诉服务器更改为加密模式。
11.Finished 完成
客户端告诉服务器它准备好可以进行安全的数据通信。
12.Change cipher spec 更改加密规范
服务器发送消息告诉客户端更改为加密模式。
13.Finished 完成
服务器告诉客户端它准备好可以进行安全的数据通信了。这个就是 SSL 握手的截至。
14.Encrypted data 加密数据
客户端和服务器使用对称加密算法和在 client hello 与 server hello 过程中使用加密散列函数协商,并使用客户端在客户端密钥交换过程中发送到服务器的密钥。握手可以在这个时候重新协商。详情见下节。
15.Close Messages 关闭消息
在连接的最后,每个侧发送一个 close_notify 消息来通知对等端连接被关闭了。
如果 SSL 会话期间生成的参数被保存,然后这些参数有时可以再用于将来的SSL 会话。保存 SSL 会话参数允许加密通信开始的更加迅速。
再次握手(重新协商)
一旦初始握手完成,应用程序数据流转,任何一方都可以随时启动新的握手。一个应用程序可能需要使用一个更强大的加密套件,特别是关键操作,或者一个服务器应用程序可能需要验证客户端身份。
不管原因,新的握手是在现有的加密会话中进行的,并且在一个新的会话建立之前,应用数据和握手信息是交错的。
您的应用程序可以使用下列方法之一启动一个新的握手:
- SSLSocket.startHandshake()
- SSLEngine.beginHandshake()
请注意,相关谈判协议的缺陷在 2009 年被发现。协议和 Java SE 的实现都是修正过的。更多信息,查看Transport Layer Security (TLS) Renegotiation Issue
密码套件选择与远程实体验证
SSL/TLS 协议定义了一系列具体的措施以保证受保护的连接。然而,密码套件的选择直接影响到连接所享有的安全类型。例如,如果选择一个匿名密码套件,则该应用程序无法验证远程对等端的身份。如果一个没有加密的套件被选中,那么数据的隐私就不能被保护。此外,SSL/TLS 协议不指定凭据接收到的必须匹配所期望发送的。如果连接被某种方式重定向到一个恶意的对等端,但该流氓的凭据基于目前的信任材料是可以接受的基础上,那么该连接将被认为是有效的。
利用原生 SSLSocket 和 SSLEngine 类的时候,你应该总是在发送任何数据前校验凭据。SSLSocket 和 SSLEngine 类不自动验证 URL 中的主机名和凭证中的的主机名是否匹配。如果注解名未被检验,则一个应用程序可以被伪装的 URL 所恶意利用。
协议如 HTTPS(HTTP Over TLS) 需要主机名验证。应用程序可以使用 HostnameVerifier 覆盖默认 HTTPS 主机名称规则。更多信息见 HttpsURLConnection 。