Java高级——网络安全Https系列(之一)

  • 时间:2018-06-20 22:29 作者:Java高并发框架 来源:Java高并发框架 阅读:189
  • 扫一扫,手机访问
摘要:笔者曾就职于华为,三星,腾讯等一线IT企业,多年来一直先整理一下关于HTTPs相关的知识,但是苦于没有时间,最近终于抽出时间来完成这一件事情,希望大家喜欢。更多java知识,请大家关注我的发布,欢迎大家转发。本系列的内容主要有四个方面:HTTPS趋势、HTTPS基础、HTTPS实践、HTTPS调试。

笔者曾就职于华为,三星,腾讯等一线IT企业,多年来一直先整理一下关于HTTPs相关的知识,但是苦于没有时间,最近终于抽出时间来完成这一件事情,希望大家喜欢。更多java知识,请大家关注我的发布,欢迎大家转发。

本系列的内容主要有四个方面:HTTPS趋势、HTTPS基础、HTTPS实践、HTTPS调试。

HTTPS趋势

这一章节主要详情近几年和未来HTTPS的趋势,包括两大浏览器chrome和firefox对HTTPS的态度,以及淘宝天猫和阿里云CDN的HTTPS实践情况。

Java高级——网络安全Https系列(之一)

上图是 chrome 统计的HTTPS网页占比的趋势,2015年的时候,大多数国家的HTTPS网页加载次数只占了不到 50%,2016年美国这个占比到了将近60%,去年就已经超过 70%,目前已经超过 80%。最下面是日本,目前是60%左右,这里面没有统计到中国的数据,我预计中国的占比会更少,空间还有很大,但未来HTTPS趋势是显著的。

同样,Firefox 浏览器加载HTTPS网页的统计跟 chrome 差不多,全球 HTTPS网页加载占比在 70% 左右,上升趋势也很显著。

Java高级——网络安全Https系列(之一)

更值得关注的是,Google 在今年年初的时候在其安全博客上表明,在今年7月份左右发布的 chrome68 浏览器会将所有HTTP网站标记为不安全,现在是5月份底了,离这个时间也就一个多月的时间了。右边的截图能看出原本是绿色的小锁变成了不安全,这种网页在输入密码时就很不安全了。

早期天猫淘宝只是在关键的登录和交易的环节上了HTTPS,但随着互联网的发展,劫持、篡改等等问题也越来越严重,试想在天猫淘宝上看的商品图片被恶意人替换了或者者价格被篡改了会怎样样?这样使用户、商家和平台都受到伤害,只有上了 HTTPS才可以从根本上处理这些问题。所以,天猫和淘宝在2015年7月份的时候已经完成了全站HTTPS。

更多java知识,请大家关注我的发布,欢迎大家转发。

二、HTTPS基础

本章节主要详情HTTPS为什么安全,包括对称加密、非对称加密、签名、证书&证书链、SSL是怎样握手的、以及私钥密钥在HTTPS中发挥什么样的作使用、keyless又是处理什么样的问题等等。

HTTPS的定义

简单来讲,HTTPS就是安全的HTTP,我们知道HTTP是运行在TCP层之上的,HTTPS在HTTP层和TCP层之间加了一个SSL层,SSL向上提供加密和解密的服务,对HTTP比较透明,这样也便于服务器和用户端的实现以及更新。

Java高级——网络安全Https系列(之一)

HTTPS为什么安全?

HTTPS安全是由一套安全机制来保证的,主要包含这4个特性:机密性、完整性、真实性和不可否认性。

  • 机密性是指传输的数据是采使用Session Key(会话密钥)加密的,在网络上是看不到明文的。
  • 完整性是指为了避免网络中传输的数据被非法篡改,用MAC算法来保证消息的完整性。
  • 真实性是指通信的对方是可信的,利使用了PKI(Public Key Infrastructure 即『公钥基础设备』)来保证公钥的真实性。
  • 不可否认性是这个消息就是你给

对称加密和非对称加密

HTTPS有对称加密和非对称加密两种算法,目的都是把明文加密成密文,区别是密钥的个数不一样,对称加密是一把密钥,这把密钥能加密明文,也能解密加密后的密文,常见的对称加密算法有AES、DES、RC4,目前最常使用的是AES。

Java高级——网络安全Https系列(之一)

非对称加密是两把密钥,分别是公钥和私钥,公钥加密的密文只有相对应的私钥才可以解密,私钥加密的内容也只有相对应的公钥才可以解密,其中公钥是公开的,私钥是自己保存,不可以公开,常见的非对称加密算法有RSA和ECC(椭圆曲线算法)。

SSL结合了这两种加密算法的优点,通过非对称加密来协商对称加密的密钥,握手成功之后便可用对称加密来做加密通信,对于RSA来说,用户端是使用RSA的公钥把预主密钥加密后传给服务器,服务器再使用私钥来解密,双方再通过相同的算法来生成会话密钥,之后的应使用层数据即可以通过会话密钥来加密通信。

签名

SSL中还有一个用非对称加密的地方就是签名,签名的目的是让对方相信这个数据是我发送的,而不是其余人发送的。

Java高级——网络安全Https系列(之一)

密钥安全强度与性可以比照

加密之后的数据破解难度就表现在密钥的长度上,密钥越长,破解难度也越大,但是运算的时间也越长,性可以也就越差。相同安全强度下,对称密钥长度在最短,ECC次之,RSA密钥长度则最长。

目前比较常使用的密钥长度是:对称密钥128位、ECC 256位、RSA 2048位。

Java高级——网络安全Https系列(之一)

RSA和ECC在SSL中更多的是使用来签名,通过测试发现,ECC 的签名性可以比RSA好很多,但是RSA的验签性可以比ECC更好,所以RSA更适合于验证签名频繁而签名频度较低的场景,ECC更适合于签名频繁的场景,在SSL场景中,ECC算法性可以更好。

Java高级——网络安全Https系列(之一)

公钥基础设备(PKI)

简单的说,PKI就是浏览器和CA,CA是整个安全机制的重要保障,我们平常使用的证书就是由CA机构颁发,其实就是使用CA的私钥给使用户的证书签名,而后在证书的签名字段中填充这个签名值,浏览器在验证这个证书的时候就是用CA的公钥进行验签。

Java高级——网络安全Https系列(之一)

更多java知识,请大家关注我的发布,欢迎大家转发。

证书

那CA在PKI中又是怎么发挥作使用的呢,首先,CA的作使用就是颁发证书,颁发证书其实就是用CA的私钥对证书请求签名文件进行签名,其次,CA颁发的证书浏览器要信任,浏览器只要要使用CA的公钥进行验签成功就表示这个证书是合法可信的,这就需要浏览器内置CA的公钥,也就是内置CA的证书。一般来说,操作系统都会内置权威CA的证书,有的浏览器会用操作系统内置的CA证书列表,有的浏览器则自己维护的CA证书列表,比方Firefox。

Java高级——网络安全Https系列(之一)

CA分为根CA,二级CA,三级CA,三级CA证书由二级CA的私钥签名,二级CA证书由根CA的私钥签名,根CA是自签名的,不会给使用户证书签名,我们平常使用的证书都是由二级CA或者者三级CA签名的,这样就形成了一个证书链,浏览器在验签的时侯一层层往上验证,直到使用内置的根CA证书的公钥来验签成功即可以表示使用户证书是合法的证书。 根证书已经内置在浏览器或者者操作系统里了,在SSL握手时就不需要发根CA证书了,只要要提供中间二级三级CA证书和使用户证书即可以。

交叉证书

交叉证书的应使用场景是这样的:如果现在阿里云成为一个新的根CA机构,那阿里云签发的证书想要浏览器信任的话,阿里云的根证书就需要内置在各大操作系统和浏览器中,这需要较长时间的部署,那在没有完一律署完成之前,阿里云签发的证书怎样才可以让浏览器信任呢,这就需要使用到交叉证书了。

Java高级——网络安全Https系列(之一)

上图中,根证书A是一个所有浏览器都内置了的根证书,B是一个新的根证书,使用户证书D是由根证书 B的二级CA B1来签发的,但是根证书B并没有在浏览器中内置,所以浏览器不会信任使用户证书D,这是由于浏览器在验签时只验证到B1这一层而后找不到根证书B就无法验证下去了。 假如二级CA B1证书是由根证书A来签名,那这个问题就解了,所以新的根证书机构B会将二级CA证书(精确地讲是二级CA的证书签名请求文件)给老的根证书A来签名,而后得到一个新的中间证书就是交叉证书。 浏览器在验证的时侯使用了新的信任链,这样即可以处理使用户证书的信任问题。

当B的根证书一律部署完成后,再替换成自己的二级CA即可以了。

证书分类

Java高级——网络安全Https系列(之一)

证书分有三类:DV、OV、EV

DV证书只校验域名的所有权,所以我们在申请DV证书的时候CA会提供几种验证域名所有权的方法:比方文件校验、DNS校验、邮件校验,DV证书支持单域名、多域名和泛域名,但不支持多个泛域名,只支持一个泛域名,一般价格比较便宜,具体价格跟域名的数量有关,域名越多价格越高。

OV证书要验证组织机构,在申请证书时CA会打电话确认这个域名能否真的属于相应的公司或者者机构,OV证书是单域名、多域名、泛域名和多个泛域名都支持,价格一般比DV证书要贵。

EV证书的校验就更细了,比方组织机构的地址之类的,EV证书会在地址栏上显示组织机构的名称,EV证书只支持单域名或者者多个域名,不支持泛域名,而且更贵,所以普通使用户一般不会使用EV证书。

证书吊销

证书是有生命周期的,假如证书的私钥泄漏了那这个证书就得吊销,一般有两种吊销方式:CRL和OCSP。

Java高级——网络安全Https系列(之一)

CRL是CA机构维护的一个已经被吊销的证书序列号列表,浏览器需要定时升级这个列表,浏览器在验证证书合法性的时候也会在证书吊销列表中查询能否已经被吊销,假如被吊销了那这个证书也是不可信的。能看出,这个列表随着被吊销证书的添加而添加,列表会越来越大,浏览器还需要定时升级,实时性也比较差。

所以,后来就有了 OCSP 在线证书状态协议,这个协议就是处理了 CRL 列表越来越大和实时性差的问题而生的。有了这个协议,浏览器即可以不使用定期升级CRL了,在验证证书的时候直接去CA服务器实时校验一下证书有没有被吊销即可以,是处理了CRL的问题,但是每次都要去CA服务器上校验也会很慢,在网络环境较差的时候或者者跨国访问的时候,体验就非常差了,OCSP尽管处理了CRL的问题但是性可以却很差。所以后来就有了OCSP stapling。

OCSP stapling主要处理浏览器OCSP查询性可以差的问题,原本由浏览器去CA的OCSP服务器查询证书状态的,现在改由域名的服务器去查询,将OCSP的结果告诉浏览器就可,一般服务器的网络性可以要好于使用户电脑的网络,所以OCSP stapling的性可以是最好的。但是并不是所有的服务器都支持OCSP stapling,所以目前浏览器还是比较依赖CRL,证书吊销的实时性要求也不是特别高,所以定期升级问题也不大。

更多java知识,请大家关注我的发布,欢迎大家转发。

HTTPS工作模式

对于用户端和服务器来讲,应使用层协议还是HTTP,只是加了一个SSL层来做加密解密的逻辑,对应使用层来说是透明的,在网络上传输的都是加密的请求和加密的响应,从而达到安全传输的目的。

Java高级——网络安全Https系列(之一)

这是SSL层在网络模型的位置,SSL属于应使用层协议。接管应使用层的数据加解密,并通过网络层发送给对方。

Java高级——网络安全Https系列(之一)

更细地分,SSL协议分握手协议和记录协议,握手协议使用来协商会话参数(比方会话密钥、应使用层协议等等),记录协议主要使用来传输应使用层数据和握手协议消息数据,以及做加解密解决。我们应使用层的的消息数据在SSL记录协议会给分成很多段,而后再对这个片段进行加密,最后在加上记录头后就发送出去。

更多java知识,请大家关注我的发布,欢迎大家转发。

TLS握手协议

SSL/TLS 握手协议又细分为四个子协议,分别是握手协议、密码规格变更协议、警告协议和应使用数据协议。

Java高级——网络安全Https系列(之一)

完整的握手流程

Java高级——网络安全Https系列(之一)

首先是TCP握手,TCP三次完成之后才进入SSL握手,SSL握手总是以ClientHello消息开始,就跟TCP握手总是以SYN包开始一样;

ClientHello主要包含用户端支持的协议、密钥套件、session id、用户端随机数、sni、应使用层协议列表(http/1.1、h2)、签名算法等等; 服务器收到ClientHello之后会从中选取本次通信的协议版本、密钥套件、应使用层协议、签名算法,以及服务器随机数,而后通过ServerHello消息响应,假如没有session复使用,那将服务器的证书通过Certificate消息响应,假如是选使用了ECC算法来做密钥交换的话,那还会将椭圆曲线参数以及签名值通过ServerKeyExchange消息发送给对方,最后通过ServerHelloDone消息来结束本次协商过程;

用户端收到这些消息之后,会生成预主密钥、主密钥和会话密钥,而后将椭圆曲线参数通过ClientKeyExchange发送给服务器,服务器拿到用户端的椭圆曲线参数也会生成预主密钥,假如是RSA的话ClientKeyExchange使用来发送公钥加密的预主密钥,服务器使用私钥来解密一下即可以得到预主密钥,再由预主密钥生成主密钥和会话密钥。最后双方都以ChangeCipherSpce和Finished消息来告知对方,自己已经准备好了能进行加密通信了,而后握手完成。

能看出,完整的SSL握手需要2个RTT,而且每次握手都使用到了非对称加密算法签名或者者解密的操作,比较耗CPU,所以后来就有了session复使用的优化手段,后面会做详情。

SSL的握手消息尽管比较多,但很多消息都是放在一个TCP包中发送的,从抓包能看出完整的SSL握手需要2个RTT。

Java高级——网络安全Https系列(之一)

更多java知识,请大家关注我的发布,欢迎大家转发。

刚才通过完整的SSL握手能看出几个缺点: 1、2个RTT,首包时间较长 2、每次都要做非对称加密,比较耗CPU,影响性可以 3、每次都要传证书,证书一般都比较大,白费带宽

SSL握手的目的是协商会话密钥以及参数,假如可以把这些会话参数缓存那即可以没有必要每次都传证书和做非对称加密计算,这样即可以提高握手性可以,而且能将RTT减到1个,提高使用户体验。

Java高级——网络安全Https系列(之一)

所以就有了session id的复使用方式,每次完整握手之后都将协商好的会话参数缓存在服务器中,用户端下次握手时会将上次握手的session id带上,服务器通过session id查询能否有会话缓存,有的话就直接复使用,没有的话就重新走完整握手流程。但是session id这种方式也有缺点,比较难支持分布式缓存以及消耗服务器的内存。

而session ticket 方案,其原理能了解为跟 http cookie 一样,服务器将协商好的会话参数加密成 session ticket,而后发送给用户端,用户端下次握手时会将这个session ticket带上,服务器解密成功就复使用上次的会话参数,否则就重新走完整握手流程。能看出session ticket这种方式不需要服务器缓存什么,支持分布式环境,有很大的优势。这种方式有一个缺点是并不是所有用户端都支持,支持率比较低,但随着用户端版本的升级迭代,以后各种用户端会都支持。由于session id用户端支持率比较高,所以目前这两种方式都在用。

这是 session ticket 的复使用,跟 session id 的区别是 client hello 会带上 Session ticket ,将近200个字节的加密数据,服务器会使用session ticket 密钥来解密,解密成功则直接复使用,也简化了握手流程,提升效率和性可以。

Java高级——网络安全Https系列(之一)

更多java知识,请大家关注我的发布,欢迎大家转发。

这是我们上了分布式 Session id 复使用的效果,session id复使用的比例在没有开启分布式缓存时只占了3%左右,复使用率很低,上了分布式session缓存之后,这个比例提升到20%多。握手时间也从75ms左右降低到65ms左右,性可以提升效果还是很显著的。

Java高级——网络安全Https系列(之一)

SSL/TLS握手时的私钥使用途(RSA、ECDHE)

我们知道私钥是整个SSL中最重要的东西,那私钥在SSL握手里面又是怎样用的呢?两种用方式分别是:用RSA来做密钥交换和用ECDHE来做密钥交换。对于RSA来说,用户端生成预主密钥,而后使用公钥加密再发给服务器,服务器使用私钥来解密得到预主密钥,而后由预主密钥生成主密钥,再由主密钥生会话密钥,最后使用会话密钥来通信。

Java高级——网络安全Https系列(之一)

对于ECDHE来说,用户端和服务器双方是交换椭圆曲线参数,私钥只是使用来签名,这是为了保证这个消息是持有私钥的人给我发的,而不是冒充的。双方交换完参数之后生成预主密钥,再生成主密钥和会话密钥。这就跟刚才RSA后面的流程一样了。

Java高级——网络安全Https系列(之一)

能看出RSA和椭圆曲线密钥交换算法的私钥使用途是不一样的,RSA密钥交换时是使用来做加解密的,椭圆曲线密钥交换时是使用来做签名的。

更多java知识,请大家关注我的发布,欢迎大家转发。

SSL/TLS中的密钥

预主密钥、主密钥和会话密钥,这几个密钥都是有联络的。

对于RSA来说,预主密钥是用户端生成,加密之后发给服务器,服务器使用私钥来解密。对于ECDHE来说,预主密钥是双方通过椭圆曲线算法来生成。

主密钥是由预主密钥、用户端随机数和服务器随机数通过PRF函数来生成;会话密钥是由主密钥、用户端随机数和服务器随机数通过PRF函数来生成,会话密钥里面包含对称加密密钥、消息认证和CBC模式的初始化向量,但对于非CBC模式的加密算法来说,就没有使用到这个初始化向量。

session 缓存和session ticket里面保存的是主密钥,而不是会话密钥,这是为了保证每次会话都是独立的,这样才安全,即便一个主密钥泄漏了也不影响其余会话。

Java高级——网络安全Https系列(之一)

Keyless

刚才提到RSA和ECDHE的私钥使用途,对于服务器来说,密钥交换算法是RSA时,私钥是使用来做解密的,ECDHE时,私钥是使用来签名的。

Keyless就是将私钥参加运算的部分分离远程服务器,这样能处理两个问题: 1,公私钥分离,使用户不需要将私钥给第三方,减少私钥泄露的风险。 2,将非对称加密运算这种cpu密集型运算剥离到keyserver,能在keyserver中安装ssl加速卡做硬件加速,提高性可以。

Java高级——网络安全Https系列(之一)

HTTP/2

HTTP/2主要有这几个特性:

一、二进制协议,能做更多的优化; 二、多路复使用,肯定程度上处理了队头阻塞的问题,提高并发和总的加载时间 三、头部压缩,很多请求头或者者响应头都没有必要重复传输白费带宽,比方user-agent、cookie还有其余没有必要每次都传的头部在http2中都做了优化 四、安全,尽管RFC规定HTTP/2能运行在明文之上,但目前所有浏览器都只支持https之上的http/2,所以是安全的。

开启HTTP/2会有这几个收益:

Java高级——网络安全Https系列(之一)

更多java知识,请大家关注我的发布,欢迎大家转发。

一、加载时间的提升,我们做了这么一个测试,一张大图片分割成几百个小图片,而后使用http/1.1和http/2打开,http/1.1加载完所有小图片使用了五六秒,但http/2加载完所有小图片只要要不到1s的时间,有5倍左右的提升,效果还是很显著的,具体提升百分之多少这得具体看具体的业务类型。

二、头部压缩有95%左右的提升,http/1.1的平均响应头大小有500个字节左右,而http/2的平均响应头大小只有20多个字节,提升非常大,所以http/2非常适合小图片小文件的业务类型,由于小文件的http头部比重较大,而http/2对头部的压缩做了非常好的优化。

三、服务器QPS的性可以有60%多的提升,这是由于http/2的连接复使用和多路复使用机制,能解决更多的并发请求。

HTTPS实践、HTTPS调试 相关知识请看我的下一篇文章

  • 全部评论(0)
最新发布的资讯信息
【系统环境|软件环境】如何成为一名大数据工程师?(2019-05-20 12:11)
【系统环境|Linux】大数据四大常识,不会你敢说自己在做大数据?(2019-05-19 11:39)
【系统环境|】需要同时掌握AVA和Linux,才可以继续大数据课程的学习(2019-05-18 10:28)
【系统环境|软件环境】学习大数据,一定要了解大数据的这些用途(2019-05-16 10:49)
【系统环境|Linux】bt宝塔控制面板mysql频繁自动停止详细解决办法(2019-05-16 08:52)
【系统环境|】大数据零基础学习路线,新人记得保存收藏哦(2019-05-15 10:54)
【系统环境|】全网最全最新的大数据系统学习路径(2019-05-14 15:38)
【系统环境|Linux】毕业设计:音乐分享系统(2019-05-14 07:48)
【系统环境|】教你零基础如何快速入门大数据技巧(2019-05-12 11:25)
【系统环境|】想学习大数据?这才是完整的大数据学习体系(2019-05-11 11:33)
手机二维码手机访问领取大礼包
返回顶部