Skip to content

Latest commit

 

History

History
323 lines (202 loc) · 28.9 KB

Https相对Http更安全的原理探秘.md

File metadata and controls

323 lines (202 loc) · 28.9 KB

白菜Java自习室 涵盖核心知识

1. HTTPS

HTTPS(全称:Hypertext Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。 即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。

https:它是一个URI scheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。URL表明它使用了HTTPS,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。这个系统的最初研发由网景公司进行,提供了身份验证与加密通讯方法,现在它被广泛用于万维网上安全敏感的通讯,例如交易支付方面。

2. SSL 简介

SSL,(Secure Socket Layer 安全套接字层),为Netscape(网景公司)所研发,用以保障在Internet上数据传输之安全。SSL目前有三个版本,SSL1.0、SSL2.0、SSL3.0。它已被广泛地用于Web浏览器与服务器之间的身份认证和加密数据传输。

SSL利用数据加密、身份验证和消息完整性验证机制,为网络上数据的传输提供安全性保证。SSL支持各种应用层协议。由于SSL位于应用层和传输层之间,所以可以为任何基于TCP等可靠连接的应用层协议提供安全性保证。

SSL协议可分为两层:

  • SSL记录协议(SSL Record Protocol):它建立在可靠的传输协议(如TCP)之上,为高层协议提供数据封装、压缩、加密等基本功能的支持。
  • SSL握手协议(SSL Handshake Protocol):它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。

SSL安全机制有三种:

  • 身份验证机制: 基于证书利用数字签名方法对服务器和客户端进行身份验证,其中客户端的身份验证是可选的。
  • 数据传输的机密性: 利用对称密钥算法对传输的数据进行加密。
  • 消息完整性验证: 消息传输过程中使用MAC算法来检验消息的完整性。

3. TLS 简介

(Transport Layer Security,传输层安全协议),用于两个应用程序之间提供保密性和数据完整性。

TLS 1.0是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本,可以理解为SSL 3.1,它是写入了 RFC的。该协议由两层组成: TLS 记录协议(TLS Record)和 TLS 握手协议(TLS Handshake)。较低的层为 TLS 记录协议,位于某个可靠的传输协议(例如 TCP)上面。

4. HMAC 简介

HMAC(Keyed-hash message authentication code),即密钥散列消息认证码,又称散列消息认证码。

是一种通过特别计算方式之后产生的消息认证码(MAC),使用密码散列函数,同时结合一个加密密钥,它可以用来保证数据的完整性,同时可以用来做某个消息的身份验证,由RFC2104定义,数学公式为:

其中:

  1. H为密码散列函数(如MD5或SHA-1)
  2. K为密钥(secret key)
  3. m是要认证的消息
  4. K'是从原始密钥K导出的另一个秘密密钥(如果K短于散列函数的输入块大小,则向右填充(Padding)零;如果比该块大小更长,则对K进行散列)
  5. ||代表串接
  6. ⊕代表异或(XOR)
  7. opad是外部填充(0x5c5c5c…5c5c,一段十六进制常量)
  8. ipad是内部填充(0x363636…3636,一段十六进制常量)

5. TLS与SSL的异同

5.1. SSL/TLS协议提供的主要服务

  1. 认证用户和服务器,确保数据发送到正确的客户机和服务器;
  2. 加密数据以防止数据中途被窃取;
  3. 维护数据的完整性,确保数据在传输过程中不被改变。

5.2. SSL与TLS协议的主要差异

  1. 版本号:TLS记录格式与SSL记录格式相同,但版本号的值不同,TLS的版本1.0使用的版本号为SSLv3.1。
  2. 报文鉴别码:SSLv3.0和TLS的MAC算法及MAC计算的范围不同。TLS使用了RFC-2104定义的HMAC算法。SSLv3.0使用了相似的算法,两者差别在于SSLv3.0中,填充字节与密钥之间采用的是连接运算,而HMAC算法采用的是异或运算。但是两者的安全程度是相同的。
  3. 伪随机函数:TLS使用了称为PRF的伪随机函数来将密钥扩展成数据块,是更安全的方式。
  4. 报警代码:TLS支持几乎所有的SSLv3.0报警代码,而且TLS还补充定义了很多报警代码,如解密失败(decryption_failed)、记录溢出(record_overflow)、未知CA(unknown_ca)、拒绝访问(access_denied)等。
  5. 密文族和客户证书:SSLv3.0和TLS存在少量差别,即TLS不支持Fortezza密钥交换、加密算法和客户证书。
  6. certificate_verify和finished消息:SSLv3.0和TLS在用certificate_verify和finished消息计算MD5和SHA-1散列码时,计算的输入有少许差别,但安全性相当。
  7. 加密计算:TLS与SSLv3.0在计算主密值(master secret)时采用的方式不同。
  8. 填充:用户数据加密之前需要增加的填充字节。在SSL中,填充后的数据长度要达到密文块长度的最小整数倍。而在TLS中,填充后的数据长度可以是密文块长度的任意整数倍(但填充的最大长度为255字节),这种方式可以防止基于对报文长度进行分析的攻击。

5.3. TLS的主要增强内容

TLS的主要目标是使SSL更安全,并使协议的规范更精确和完善。TLS 在SSL v3.0 的基础上,提供了以下增强内容:

  1. 更安全的MAC算法
  2. 更严密的警报
  3. “灰色区域”规范的更明确的定义

5.4. TLS对于安全性的改进

  1. 对于消息认证使用密钥散列法:TLS 使用“消息认证代码的密钥散列法”(HMAC),当记录在开放的网络(如因特网)上传送时,该代码确保记录不会被变更。SSLv3.0还提供键控消息认证,但HMAC比SSLv3.0使用的(消息认证代码)MAC 功能更安全。
  2. 增强的伪随机功能(PRF):PRF生成密钥数据。在TLS中,HMAC定义PRF。PRF使用两种散列算法保证其安全性。如果任一算法暴露了,只要第二种算法未暴露,则数据仍然是安全的。
  3. 改进的已完成消息验证:TLS和SSLv3.0都对两个端点提供已完成的消息,该消息认证交换的消息没有被变更。然而,TLS将此已完成消息基于PRF和HMAC值之上,这也比SSLv3.0更安全。
  4. 一致证书处理:与SSLv3.0不同,TLS试图指定必须在TLS之间实现交换的证书类型。
  5. 特定警报消息:TLS提供更多的特定和附加警报,以指示任一会话端点检测到的问题。TLS还对何时应该发送某些警报进行记录。

6. SSL协议基本运行过程

SSL位于应用层和传输层之间,它可以为任何基于TCP等可靠连接的应用层协议提供安全性保证。

SSL协议本身分为两层

  1. 上层为SSL握手协议(SSL handshake protocol)、SSL密码变化协议(SSL change cipher spec protocol)和SSL警告协议(SSL alert protocol);
  2. 底层为SSL记录协议(SSL record protocol)。

  • SSL握手协议:是SSL协议非常重要的组成部分,用来协商通信过程中使用的加密套件(加密算法、密钥交换算法和MAC算法等)、在服务器和客户端之间安全地交换密钥、实现服务器和客户端的身份验证。
  • SSL密码变化协议:客户端和服务器端通过密码变化协议通知对端,随后的报文都将使用新协商的加密套件和密钥进行保护和传输。
  • SSL警告协议:用来向通信对端报告告警信息,消息中包含告警的严重级别和描述。
  • SSL记录协议:主要负责对上层的数据(SSL握手协议、SSL密码变化协议、SSL警告协议和应用层协议报文)进行分块、计算并添加MAC值、加密,并把处理后的记录块传输给对端。

6.1. 基本运行过程

  1. 客户端向服务器端索要并验证公钥。
  2. 双方协商生成"对话密钥"。
  3. 双方采用"对话密钥"进行加密通信。

其中,前两个阶段,被称为“握手阶段”。

6.2. 握手阶段详细过程

"握手阶段"涉及四次通信,该阶段的所有通信都是明文的。

由于非对称加密的速度比较慢,所以它一般用于密钥交换,双方通过公钥算法协商出一份密钥,然后通过对称加密来通信,当然,为了保证数据的完整性,在加密前要先经过HMAC的处理。

TLS握手阶段是发生在TCP建连之后开始进行的,握手其实就是在协商,协商加解密协议所需要的一些参数信息等内容。 TLS握手过程有单向验证和双向验证之分,简单解释一下,单向验证就是server端将证书发送给客户端,客户端验证server端证书的合法性等,例如百度、新浪、google等普通的https网站,双向验证则是不仅客户端会验证server端的合法性,同时server端也会验证客户端的合法性,例如银行网银登陆,支付宝登陆交易等。

SSL缺省只进行server端的认证,客户端的认证是可选的。以下是其流程图:

6.2.1. 客户端发出请求(Client Hello)

由于客户端(如浏览器)对一些加解密算法的支持程度不一样,但是在TLS协议传输过程中必须使用同一套加解密算法才能保证数据能够正常的加解密。在TLS握手阶段,客户端首先要告知服务端,自己支持哪些加密算法,所以客户端需要将本地支持的加密套件(Cipher Suite)的列表传送给服务端。除此之外,客户端还要产生一个随机数,这个随机数一方面需要在客户端保存,另一方面需要传送给服务端,客户端的随机数需要跟服务端产生的随机数结合起来产生后面要讲到的 Master Secret 。

综上,在这一步,客户端主要向服务器提供以下信息:

  1. 支持的协议版本号(SSL Version),比如TLS 1.0版。
  2. 一个客户端生成的随机数(Client Random1),稍后用于生成"对话密钥"。
  3. 客户端支持的加密套件(Support Ciphers)比如:RSA公钥加密算法、DH加密算法。
  4. 支持的压缩算法。
  5. 支持的一些SSL/TLS扩展 (sever_name等)。
  • 非对称加密算法RSA:RSA是1977年由罗纳德·李维斯特(Ron Riverst)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的,当时三人都在麻省理工学院工作,RSA就是他们三人姓氏开头字母的缩写拼在一起组成的。 RSA算法的安全性基于大数分解质因子的困难性,由于人们一直未找到对大数进行因子分解的有效方法,所以RSA在目前看来依然是安全的,RSA算法既可用于加密,也可用于签名,是目前应用最广的公钥算法。

  • DH(Diffie-Hellman):是一种安全的密钥交换协议,它可以让双方在完全没有对方任何预先信息的条件下通过不安全通道创建一个密钥,这个密钥可以在后续的通信中做为对称密钥来加密通讯内容。

  • SNI(Server Name Indication):即服务器名称指示,是一个扩展的TLS协议,在该协议下,在握手过程开始时就可以通过客户端告诉它正在连接的服务器的主机名称,这就允许了服务器在相同的IP地址和TCP端口号上绑定多个证书了,并且因此允许在相同的IP地址上提供多个安全的https网站,它与虚拟主机概念相同。

6.2.2. 服务器回应(Sever Hello)

从Server Hello到Server Done,有些服务端的实现是每条单独发送,有服务端实现是合并到一起发送。Sever Hello和Server Done都是只有头没有内容的数据。

服务端在接收到客户端的Client Hello之后,服务端需要将自己的证书发送给客户端。这个证书是对于服务端的一种认证。例如,客户端收到了一个来自于称自己是 www.alipay.com 的数据,但是如何证明对方是合法的alipay支付宝呢?这就是证书的作用,支付宝的证书可以证明它是alipay,而不是财付通。证书是需要申请,并由专门的数字证书认证机构(CA)通过非常严格的审核之后颁发的电子证书。颁发证书的同时会产生一个私钥和公钥。私钥由服务端自己保存,不可泄漏。公钥则是附带在证书的信息中,可以公开的。证书本身也附带一个证书电子签名,这个签名用来验证证书的完整性和真实性,可以防止证书被串改。另外,证书还有个有效期。

在服务端向客户端发送的证书中没有提供足够的信息(证书公钥)的时候,还可以向客户端发送一个 Server Key Exchange, 此外,对于非常重要的保密数据,服务端还需要对客户端进行验证,以保证数据传送给了安全的合法的客户端。服务端可以向客户端发出 Cerficate Request 消息,要求客户端发送证书对客户端的合法性进行验证。比如,金融机构往往只允许认证客户连入自己的网络,就会向正式客户提供USB密钥,里面就包含了一张客户端证书。

跟客户端一样,服务端也需要产生一个随机数发送给客户端。客户端和服务端都需要使用这两个随机数来产生Master Secret。

最后服务端会发送一个Server Hello Done消息给客户端,表示Server Hello消息结束了。

综上,在这一步,服务器的回应包含以下内容:

  1. 确认使用的加密通信协议版本,比如TLS 1.0版本。如果浏览器与服务器支持的版本不一致,服务器关闭加密通信。
  2. 一个服务器生成的随机数(Sever Random),稍后用于生成"对话密钥"。
  3. 确认使用的加密方法,比如RSA公钥加密。
  4. 服务器证书(Certificate)。
  5. 支持的一些SSL/TLS扩展。

此为单向验证,若是双向验证,需要在Sever Hello Done之前发送Certificate Request,表示需要客户端提供证书,内容为:

  1. 客户端应当提供的证书类型
  2. 服务端可以接受的证书列表

6.2.3. 客户端回应(Client Key Exchange)

Client Key Exchange

生成一个随机数,如果采用的是RSA加密方式则取出证书中的公钥,生成随机数。如果采用的是DH算法则使用双发的DH加密参数和规则生成随机数。

客户端key交换,并且客户端使用change cipher spec通知server端开始使用加密报文传输数据,在此之前的信息都是明文的,因此我可以通过wireshark看到。 在此阶段,客户端将通过RSA算法生成一个48字节的premaster secret,即预主密钥,这个密钥中包含了客户端tls的版本号信息,如果有中间人共计,有意降低tls版本的话,则会马上终止发送数据。

这个premaster secret是一个保密的key,只要被截获就可以结合之前明文传输的伪随机数计算出最终的master secret即主密钥。因此该密钥会通过公钥证书加密传送至server端,server端通过私钥进行解密获取预主密钥,此时客户端和server端都有了相同的伪随机数及预主密钥。

Certificate Verify

如果服务端需要对客户端进行验证,在客户端收到服务端的 Server Hello 消息之后,首先需要向服务端发送客户端的证书,让服务端来验证客户端的合法性。

接着,客户端需要对服务端的证书进行检查,如果证书不是可信机构颁布、或者证书中的域名与实际域名不一致、或者证书已经过期,就会向访问者显示一个警告,由其选择是否还要继续通信。如果证书没有问题,客户端就会从服务器证书中取出服务器的公钥。然后,向服务器发送下面三项信息:

  1. 一个随机数(Pre Master Secret)。该随机数用服务器公钥加密,防止被窃听。
  2. 编码改变通知(Change Chiper Spec),表示随后的信息都将用双方商定的加密方法和密钥发送。
  3. 客户端握手结束通知,表示客户端的握手阶段已经结束。这一项同时也是前面发送的所有内容的hash值,用来供服务器校验。

上面第一项的随机数,是整个握手阶段出现的第三个随机数,它是客户端使用一些加密算法(例如:RSA, Diffie-Hellman)产生一个48个字节的Key,这个Key叫 PreMaster Secret,很多材料上也被称作 PreMaster Key。

至于为什么一定要用三个随机数,来生成"会话密钥",dog250解释得很好: "不管是客户端还是服务器,都需要随机数,这样生成的密钥才不会每次都一样。由于SSL协议中证书是静态的,因此十分有必要引入一种随机因素来保证协商出来的密钥的随机性。 对于RSA密钥交换算法来说,pre-master-key本身就是一个随机数,再加上hello消息中的随机,三个随机数通过一个密钥导出器最终导出一个对称密钥。 pre master的存在在于SSL协议不信任每个主机都能产生完全随机的随机数,如果随机数不随机,那么pre master secret就有可能被猜出来,那么仅适用pre master secret作为密钥就不合适了,因此必须引入新的随机因素,那么客户端和服务器加上pre master secret三个随机数一同生成的密钥就不容易被猜出了,一个伪随机可能完全不随机,可是是三个伪随机就十分接近随机了,每增加一个自由度,随机性增加的可不是一。"

Change Cipher Spec

Change Cipher Spec是一个独立的协议,体现在数据包中就是一个字节的数据,用于告知服务端,客户端已经切换到之前协商好的加密套件(Cipher Suite)的状态,准备使用之前协商好的加密套件加密数据并传输了。

在Change Chiper Spec传输完毕之后,客户端会使用之前协商好的加密套件和Session Secret加密一段 Finish 的数据传送给服务端,此数据是为了在正式传输应用数据之前对刚刚握手建立起来的加解密通道进行验证。

Encrypted Handshake Message

Encrypted Handshake Message,通过前两次的随机数以及最后一次的随机数(Pre Master Secret)使用确定的加密算法生成对话密钥 (Session Secret),使用对话密钥加密报文。

如果是双向认证,客户端还会Certificate和Certificate Verify报文。Certificate是客户端的证书,Certificate Verify是客户端拥有的所有握手过程中的签名信息。服务端对证书以及信息进行确认,如果发现证书和信息有误则终止SSL/TLS连接。

6.2.4. 服务器的最后回应(New Session Ticket)

New Session Ticket

该数据包主要是server端向客户端发送新的session ticket,因为最开始并没有这个信息,并通知客户端开始使用加密方式传输数据。

session ticket就相当于普通网站中的session,当浏览器在次发送请求或者中间网络原因连接被断开之后,client hello阶段携带该session id,则认为是同一个人访问,不在进行证书交互阶段,该session id的复用也是优化的一点,最后会提到。同样的这个数据也是被加密的,server端得到后进行解密即可快速完成握手。其中该字段不仅包含session ticket,还包含ticket的寿命,即过期时间,长度等。

服务端在接收到客户端传过来的 PreMaster 加密数据之后,使用私钥对这段加密数据进行解密,并对数据进行验证,也会使用跟客户端同样的方式生成 Session Secret,一切准备好之后,会给客户端发送一个 ChangeCipherSpec,告知客户端已经切换到协商过的加密套件状态,准备使用加密套件和 Session Secret加密数据了。之后,服务端也会使用 Session Secret 加密一段 Finish 消息发送给客户端,以验证之前通过握手建立起来的加解密通道是否成功。

根据之前的握手信息,如果客户端和服务端都能对Finish信息进行正常加解密且消息正确的被验证,则说明握手通道已经建立成功,接下来,双方可以使用上面产生的Session Secret对数据进行加密传输了。

服务端收到客户端的加密报文之后进行解密和校验,若成功生成一个session ticket(解释见下文)。然后作出回应:

  1. 服务端传输改变通知(Change Chiper Spec)
  2. 服务端第一个加密报文(Encrypted Handshake Message)

Change Chiper Spec

Change Chiper Spec与客户端发送的含义一致,通知客户端。

Encrypted Handshake Message

Encrypted Handshake Message与客户端发送的第一报文含义一致,用于客户端进行报文验证。

6.3. 运行过程总结

SSL客户端(也是TCP的客户端)在TCP链接建立之后,发出一个ClientHello来发起握手,这个消息里面包含了自己可实现的算法列表和其它一些需要的消息,SSL的服务器端会回应一个ServerHello,这里面确定了这次通信所需要的算法,然后发过去自己的证书(里面包含了身份和自己的公钥)。Client在收到这个消息后会生成一个秘密消息,用SSL服务器的公钥加密后传过去,SSL服务器端用自己的私钥解密后,会话密钥协商成功,双方可以用同一份会话密钥来通信了。

客户端确定密钥以及验证成功之后,整个握手过程就基本完成,以后的报文都是通过协商好的密钥进行加密。

HTTPS通信的步骤

  1. 客户端发送报文进行SSL通信。报文中包含客户端支持的SSL的指定版本、加密组件列表(加密算法及密钥长度等)。
  2. 服务器应答,并在应答报文中包含SSL版本以及加密组件。服务器的加密组件内容是从接受到的客户端加密组件内筛选出来的。
  3. 服务器发送报文,报文中包含公开密钥证书。
  4. 服务器发送报文通知客户端,最初阶段SSL握手协商部分结束。
  5. SSL第一次握手结束之后,客户端发送一个报文作为回应。报文中包含通信加密中使用的一种被称Pre-master secret的随机密码串。该密码串已经使用服务器的公钥加密。
  6. 客户端发送报文,并提示服务器,此后的报文通信会采用Pre-master secret密钥加密。
  7. 客户端发送Finished报文。该报文包含连接至今全部报文的整体校验值。这次握手协商是否能够完成成功,要以服务器是否能够正确解密该报文作为判定标准。
  8. 服务器同样发送Change Cipher Spec报文。
  9. 服务器同样发送Finished报文。
  10. 服务器和客户端的Finished报文交换完毕之后,SSL连接就算建立完成。
  11. 应用层协议通信,即发送HTTP响应。
  12. 最后由客户端断开链接。断开链接时,发送close_nofify报文。

7. 会话保持(Session ID 和 Session Ticket)

不得不提详细提一下session ticket和session id这两个角色,简单的理解就是session id就是一个session会话标识,当下次访问时携带该标识则认为是同一个人访问,但是假如轮询到集群中其它服务器,则可能无法识别该session id,因为是初次建连服务器给的,而session id是由服务器存储的主要信息,是需要占用服务器内存资源的,且不易扩展。Session id的存储及复用共享需要使用redis或memcache来实现。

也因此session ticket应运而生了,该字串中包含了当时会话所使用的一些信息,解密出来即可快速重用(RFC5077对此有详细释义),session ticket存储在客户端,新会话后,服务器通过一个自己知道的密钥ticket key将本次会话状态加密,发送给客户端,客户端保存该ticket,下次建连时候发送给server端,该方式的问题是集群中所有server设备使用相同的ticket key,因此也需要考虑该key的轮转及轮转时新旧key兼容的问题。

nginx会话缓存配置:ssl_session_cachessl_session_ticket_key

session ID

Session Identifier(会话标识符),是 TLS 握手中生成的 Session ID。服务端可以将 Session ID 协商后的信息存起来,浏览器也可以保存 Session ID,并在后续的 ClientHello 握手中带上它,如果服务端能找到与之匹配的信息,就可以完成一次快速握手。

session ticket

Session Identifier 机制有一些弊端:

  1. 负载均衡中,多机之间往往没有同步 Session 信息,如果客户端两次请求没有落在同一台机器上就无法找到匹配的信息;
  2. 服务端存储 Session ID 对应的信息不好控制失效时间,太短起不到作用,太长又占用服务端大量资源。

Session Ticket(会话记录单)可以解决这些问题,Session Ticket 是用只有服务端知道的安全密钥加密过的会话信息,最终保存在浏览器端。浏览器如果在 ClientHello 时带上了 Session Ticket,只要服务器能成功解密就可以完成快速握手。

8. CA认证机构和证书

认证机构CA(Certificate Authority)在https中是一个很重要的角色,CA是PKI的核心执行机构,是PKI(Public key Infrastructure 公钥基础设施)的主要组成部分,通常称之为认证中心,从广义上讲,认证中心还应该包括证书申请注册机构RA(Registration Authority),它是数字证书的申请注册、证书签发的管理机构。客户端是怎么验证该证书的颁发机构即CA中心是合法有效的呢,其实在系统浏览器中有预埋CA中心的根证书,在其中的根证书为可信任机构,如图:

8.1. CA的主要职责

CA是保证电子商务、网上银行、互联网环境健康等的权威性、可信任和公正的第三方机构。

  1. 笼统的说CA中心负责证书的签发和管理等;
  2. 验证并标识证书申请者的身份,对证书申请者的信用度、申请证书的目的、身份的真实可靠性等问题进行审查,确保证书与身份绑定的准确性;
  3. 确保CA用于签名证书的非对称密钥的质量和安全性;
  4. 管理证书信息资料,管理证书序号和CA标识,确保证书主体标识的唯一性,防止证书主 体名字的重复。在证书使用中确定并检查证书的有效期,保证不使用过期或已作废的证书, 确保网上交易安全,发布和维护作废证书列表(CRL)。

8.2. 认证机构的工作

认证机构会生成一对秘钥, 公钥和私钥。

  • 公钥(Public-key):即所谓的公共证书,由CA中心颁发的合法文件,可以在互联网传播,谁都可以轻易获取到。公钥证书文件的扩展名实际上只是一种使用习惯上的区别,后缀包括但不仅限于crt、cer、key、der、pem,pem可能包含了公钥和私钥文件,通常可以从pem文件中导出公钥和私钥。公钥中包含颁发给哪个域名,公司名,加密算法,组织机构,有效期等等信息。

  • 私钥(private-key):即通常就叫所谓的私钥,私钥在生成CSR文件的时候同时生产,后缀通常为.key,由使用者自己保管,不可在互联网传播,极其重要。

  • CSR(Cerificate Signing Request)文件:即证书请求文件,用于发送给CA中心用来生产公钥,该文件在生成的时候会填写一些基本信息,诸如国家代码、公司名、省份城市、管理员邮箱等等信息,可以在线生成也可以通过openssl生成,例如:

openssl req -new -nodes -newkey rsa:2048 -keyout xxx.key-out xxx.csr

公钥证书的生成包括了两部分内容:

  • 数字签名
  • 服务器公钥

其中数字签名的生成过程是:

  1. 服务器公钥, 经过数字摘要算法, 生成数字指纹;
  2. 把生成的数字指纹, 用认证机构的私钥加密, 生成数字签名。

8.3. 客户端如何校验 CA 证书的步骤

服务器将公钥证书发送给客户端, 客户端验证公钥证书从而确保公钥的合法性。

  1. 客户端取出提前内置在手机内部的认证机构的公钥;
  2. 用认证机构的公钥去解密公钥证书里的数字签名 从而得到数字指纹;
  3. 客户端对公钥证书的服务器公钥进行数字摘要算法 从而生成数字指纹;
  4. 对比客户端自己生成的数字指纹(第3步)和解密得到的数字指纹(第2步)是否一致 如果一致则公钥证书验证通过,服务端是可以被信任的;如果不相等,那么就说明该证书是错误的,可能被篡改了,浏览器会给出相关提示,无法建立起 HTTPS 连接。除此之外,还会校验 CA 证书的有效时间和域名匹配等。