- s是安全的意思,https并不是一种单独的协议
- http是一种协议,https不是一种单独的协议,他只是http建立在ssl上面。
1.定义
- HTTP over SSL/TLS/Secure
- SSL:Secure Socket Layer(早期)
- TLS:Transport Layer Secure(现在)
- 都是同一个东西,都是建立在http下面的安全层,他实际就是把你的http消息在发送之前加密,收到之后解密。
- 他如果要分类的话,他是在http层的下面,tcp层的上面。相对更靠近应用层一点。
2.本质
- 在客户端和服务器之间协商出一个对称密钥,每次发送之前加密,收到之后解密,达到内容的加密传输。
- 先用非对称加密传输对称加密的密钥,然后用对称加密传输通信的内容。
3.为什么不直接用非对称加密?
- 因为非对称加密太慢了,数学上的原理导致他只能很慢。他计算很复杂。所以能用对称,就用对称。
- 可是对称密钥又不能传,怎么办?我先用非对称式的把这个密钥给商讨好了,给确认了,双方都拿到了密钥,就用对称加密传输。
- 这是在安全性和效率上做了一个整合。
4.流程
大致流程:
- 一,你的客户端去请求一个TLS连接,这个过程是通过tcp,不是通过http。
- 二,服务器把他的证书发给你。
- 三,客户端去验证这个服务器证书是不是真的。
- 四,验证通过,客户端信任服务器,和服务器协商对称密钥。
- 五,使用对称密钥开始通讯。 只有最后一步才是http通讯,前面都是tcp
具体过程:
-
首先我的客户端会跟服务器说,我要建立连接(Client Hello),发一个非常简单的消息告诉服务器我要建立连接。
-
同时客户端会附加一个信息,包含我可以用什么方式沟通,我可以接受的是TLS版本(因为TLS早期还有SSL,他们下层的加密方式都是有版本的),这个是一大堆信息,好几个,是一个序列,比如我支持TLS 1.0/1.1/1.2,我还支持SSL 3.0,我都给你发过去,你自己选。
-
同时还会发一个Cipher Suite(加密套件),实际上就是我可以接受的对称加密的方式和非对称加密的方式,以及hash算法。他是一个加密套件,为什么要附加hash算法呢?
- hash本身不能做加密,但是他会参与到加密过程,他是可以做验证的。
-
同时,还扔了一个随机数,这个随机数是稍后用来计算机密密钥的。
-
-
服务器说,好的(Server Hello)什么叫hello呢?他只是发了一个字节,比如client hello好像是1还是几。他是一个具体的字节。
-
同时,服务器收到之后就会挑,你支持的TLS有哪些,我选一个我最喜欢的,包括后面的算法。实际上后面的三个算法都是打包的,你只能选一组。服务器选好以后就会跟着Server Hello一起发回去。然后双方都持有这个东西。
-
同时,服务器也会附加一个他的随机数给到客户端,那么双方各有一个随机数。
-
-
接着服务器会附送一个东西,服务器证书
-
他发的证书的核心是他的公钥,他的非对称加密的公钥。
-
客户端需要对这个公钥做验证,因为前面这些都是明文的,他可能会被人截取,那么他需要验证,这个服务器到底是不是我所想访问的服务器,所以服务器发过来的不仅仅是一个公钥,而是一个证书,这个证书里面包含服务器的公钥。
-
他还包含服务器的地址,也就是域名,然后客户端就会去验证这个域名比如我访问的是hencoder.com,我要确认你返回的信息到底是不是我要的信息,还有服务器名称之类的信息。那凭什么你说服务器地址是你的我就相信?我访问hencoder.com,然后中间有个什么坏人把消息给截取了,截完以后他给我发回有个证书,这个证书是属于hencoder.com的,那么我就信了吗?我肯定是不信的,我要是这么容易信了就太容易被人黑了。所以这一步还是不够的,那么需要什么呢?
-
他还需要提供一个能证明这个东西是真实的东西。他能够证明我的服务器信息是真实的。那需要什么呢?他需要提供一个签名。我能够验证这个签名对了,那么我就能够确认服务器发过来的信息确实是真实的。而且这个签名是对签名所有的信息签名的。所以服务器地址,公钥什么的都可以被证明。
-
-
我怎么去验证这个签名呢?
- 服务器会给我发会这个证书签名方的信息,也就是证书机构。我拿着证书机构的公钥,可以对证书签名进行验证的话,可以证明这个服务器的信息确实是真实的。
- 可是这个真实他是有前提的,就是蓝色部分的信息他确实是被黄色证书机构签名的,确实是被这个公钥的私钥持有者签名的。确实被这个公钥的主人签名的,到这你还是不能证明你就是真实的,不然我也造一个证书机构的公钥,证书机构的信息也是我造的,然后蓝色的证书信息也是我造的,都可以,我造一个公钥私钥对不就完了吗?
- 这个时候只能证明蓝色的信息是黄色的主人签发的。
-
这个时候还需要最后一步,也就是你的证书机构也需要提供证明信息。他需要提供他是被谁签的。他的签发方信息(循环了?),他的签发方信息,到此为止了。为什么到此为止呢?
-
我们通过一个网站证书说明一下。我们点开一个https连接的网站,点这个锁,这个锁是他的签名相关的信息,是https相关的信息,然后我点这个证书。
-
选中部分就是蓝色,中间就是二级的签发机构,也就是黄色部分,最上面这个就是最里面的证书机构的签发方,就是根证书机构,叫做root证书机构,到这就结束了。
-
那么我怎么知道根证书机构就是真的呢?万一这个也是假的怎么办?你给我嵌套三层就安全了?
-
根证书的认证可以找到可靠来源的。来自哪里?
- 来自操作系统内部。我们的每一个操作系统,不管是ios、android、mac、windows,我们都能找到这个东西。我们电脑或者手机上都存有一个根证书列表。看我机器——钥匙串——系统根证书,然后找到上面网站同类的跟证书。我的系统里面有这个根证书,就可以证明他确实是被这个根证书签的。因为这个根证书里面是有他的公钥的。那么就可以证明黄色部分的证书机构信息确实是被根证书签名的。
- 来自操作系统内部。我们的每一个操作系统,不管是ios、android、mac、windows,我们都能找到这个东西。我们电脑或者手机上都存有一个根证书列表。看我机器——钥匙串——系统根证书,然后找到上面网站同类的跟证书。我的系统里面有这个根证书,就可以证明他确实是被这个根证书签的。因为这个根证书里面是有他的公钥的。那么就可以证明黄色部分的证书机构信息确实是被根证书签名的。
-
那么还有一个问题?你这个根证书怎么就值得被信任呢?根证书是怎么来的?
-
根证书是随着我们的操作系统一起被创进来的。这些根证书列表在当初操作系统被打包的时候,被发放的时候就已经存在了,他是被我们操作系统的研发方所验证了的。也就是微软官方,苹果官方,谷歌官方或者各种浏览器的官方,对这些机构进行了验证,然后把它放到了我们的操作系统,或者浏览器的根证书列表里面,他们的身份,他们的安全,是被浏览器或者操作系统所保证的。那么只要我们的操作系统不被干掉,我们浏览器不被干掉,这个东西就是安全的。
-
前些年不是有一个事情,就是支付宝要求用户安装根证书,然后这样就能保证安全,有这样一种说法,然后媒体说,其实这样很不安全。安全不安全我觉得还是安全的,因为支付宝他们没必要干这坏事,但是,我只是从事实上分析他不会干坏事,可是如果他想干坏事,我们是阻拦不了的。他想给什么机构去签发,他随便签。他签完这个机构就是安全的,这个网站就是安全的。
-
另外最近一段时间不是根证书机构直接被加黑名单了吗?其实这个东西怎么说呢?一个信任链总归是有一个地方是不需要任何证明,你需要无条件信任的。这是一个事实,不可能你有一个完整的,单纯靠证明的方式百分百证明他可靠的。总会有一个深处你需要无条件信任。那么我们的根证书列表就是需要我们无条件信任的地方。
-
回顾一下:证书就是这样子,我证书里面有我的服务器地址,你可以去验证,你验证可以得到我要访问的服务器确实是我要的对象,他确实是hencoder.com,而不是别人拿自己的合法证书来欺骗我,不是这样的,他一定是我的目标对象,然后我怎么保证他确实是真正合法性的呢?他有一个他的签发机构(黄色),你们这个签发机构怎么确认就是真的呢?这个签发机构会去指定他的签发方,而这个签发方他的公钥不是在这,而是在我的系统里面。在系统根证书里面。这个时候我的服务器验证就结束了。中间这个机构其实可以去掉,你直接让签发方给服务器签也行,但是现在大多数方案都是有一个中间机构的,因为根证书机构都很忙。这是服务器证书的验证过程。
-
-
接下来客户端拿到服务器公钥了,然后他就会去做这个加密过程中唯一一次非对称加密。
- 他会使用这个公钥去加密一个信息,然后发给服务器去。加密什么呢?
- 加密一个叫做Per-master Secret(准主秘密信息)的东西,他也是一个随机数,现在就有三个随机数,他们的名字不一样,他们的身份也不一样。Per-master Secret是通过唯一一次非对称加密传过去的。也是第一次加密。
-
现在双方拿到三个随机信息了。那么这个时候双方都拿到足够多的信息去生产他们的对称密钥了。
-
这个是标志性的一步,他把这个Per-master Secret发过去了,这个时候他们就可以去生产一个叫做Master Secret的东西,这个Master Secret将直接生产他们的密钥。他并不是密钥,因为密钥相关的东西有好几个。Per-master Secret会跟客户端随机数和服务端随机数三个东西一起来作用,通过一个算法,得到一个新的值,这个值叫做Master Secret。
-
那么这里有个问题,你为什么要拿那两个随机数去算呢?
- 这到底有啥用呢?你在路上是明文传的,大家都能看见,你拿他们来算干啥用?这个就是跟安全有关的东西,他们从数学上考虑,虽然大家都能看见,但是我加上这两个确实能让我的密钥更安全。(这个知道就行)。
-
现在他们得到这个Master Secret,就可以用它去计算他们的密钥了。不过这个密钥是四个东西,实际上是6个,不过另外两个没有用。是什么呢?
- 客户端加密密钥,
- 服务端加密密钥,
- 客户端做hash的key,
- 服务端做hash的key,一共是四个。
-
-
为什么客户端和服务端用两个东西加密?
- 还是为了防贼,你给我发消息,我给你发消息,用不同的密钥,就能更安全一点。比如,我从客户端给服务器发了一个消息,别人截到他是看不懂,没关系我看不懂我给你捣乱,我不发给服务器,我原封不动地给你发回去,让你以为这是服务器给你响应的消息。那客户端就会觉得懵了,你给我发这个什么意思?而且能解压确实看着没问题。
-
什么是MAC Secret?
- 先说一下什么叫HMAC,MAC Secret就是HMAC的secret。
- HMAC:Hash-based Message Authenticate Code
- 他是一个改良版的hash,他是怎么算的?
- 我们做md5,
- MD5(a)=b
- HMAC(a)=MD5(fun(a))=c
- hmac里面具体做的事会复杂一点,他会对你的原消息加工之后再去做。他会对你的a做一些操作,来保证hash不容易被破解。其中一个重要的点是他往里面掺东西了,就像我们讲的那个hash他会加盐。这个盐只有通讯两方知道,其他人不知道。我的发送方知道,我的接受方也知道,其他人不知道。
- 他们有什么区别呢?我能造出这个hash,其他人造不出这个hash,因为你没我的密码,没我那个Secret。我把这个hash做出来了,就能证明这确实是我发的消息。
- 那么怎么验证呢?就是你有这消息,你是客户端你发消息了,我是服务端,我接收到这个消息以后,我也对这个消息进行有个HMAC,然后我得到这个HMAC,我可以去验证一下客户端连同这个消息一起发过来的HMAC,他们两个是不是一致。如果一致,我就可以确定消息确实是客户端发给我的。
- 加密密钥是用来加密,MAC Secret是用来验证身份的。
- 你看我们做非对称加密,你用公钥加密,私钥解密来加密,用私钥加密,公钥解密来做签名和验证。
- 而对称加密是用加密密钥来加密,用HMAC做签名和验证,相当于是一个签名和验证,实际上不是,但是他们的目的是一样的。都可以用来验证身份。这个Secret不是签名,只是一个用来验证身份的工具。
- 先说一下什么叫HMAC,MAC Secret就是HMAC的secret。
-
说这么多,这四个密钥就是用来加密和验证身份的。
-
这个时候客户端可以发加密消息了。这个时候他们需要验证一下加密算法到底能不能用。
- 客户端说:我要使用加密通讯了。
-
客户端发送:Finished
- 这个并不是这么一个字母,而且也不想上面的Clinet Hello是一个字节,这个是一大堆消息。
- 他要把前面的内容全都包起来,然后使用加密密钥加密,
- 用HMAC相当于签名的操作,进行一个hash,然后把整个信息发到服务器去。
- 服务器收到以后,他会看一下这个东西是什么,然后我要验证这个签名是否合适。
- 如果他既能看懂,而且签名也对,你们服务器对客户端就可以足够信任了。没有人骗我,没有人捣鬼。客户端是可以给我发消息的。
-
同样的,服务器接下来也会发。服务器说:我要使用加密通讯了。
-
服务器说:Finished,他发这个消息跟客户端那一大堆是比较相近的。只是他包的内容更多一点。然后发给客户端去,然后客户同样的验证方式。我要做一些HMAC。看看我做的HMAC跟你做的是不是同一个值。是的话证明你就是你。另外我要用你的加密密钥,看看这个结果是不是可用。这个时候证明我的加密也可用。
-
这个时候双方验证完全结束,这个时候客户端就会给服务器发https请求了。这是第一个https请求。然后他是长这个样子的。
-
从tcp来看,他写的就是这个东西,而从http根本无法解析,就是别人看来,他只知道这是tcp发的一个应用层的消息,但具体是什么我不知道。我甚至不知道这是不是一个http消息。因为他完全被https使用密钥加密了。同理,服务端收到以后,他能看懂,他回消息也是长这样子的。别人只能看到这样子,他连是不是http都不知道,完全看不懂,但他知道这是个tcp消息。因为加密是在tcp的上面加密的。所以你在tcp层面能够读懂。但是也就仅此而已了。
总结:
- 1.客户端发支持的加密套件,以及一个随机数
- 2.服务端选一个发送,然后发送一个随机数,后面随上证书
- 3.客户端证书认证,系统根证书,唯一一次非对称加密,发送,加密准主密信息,也是一个随机数
- 4.三个随机数,两边生成两对密钥和hash的key
- 5.客户端说发送加密消息
- 6.客户端说finished
- 7.服务端是发送加密消息
- 8.服务端说finished
在android中的使用
-
一般正常使用就可以了。
-
有些时候会不行:
-
自签名证书,证书都挂在网站上的,怎么挂你不需要懂,就像你不需要知道怎么开发一个服务器。挂在网站上,有的时候这个证书他不会附加机构信息,就只放一个自己的公钥什么的就不管了,这是为什么?因为有的时候网页是自签名的。自签名就是你的客户端来验证你的消息,而不是用你的本地的根证书机构。那么这个一般都是用于内网。比如校园网什么的,他们会要求,每个同学请装上我们的证书。然后就可以访问内网了,就是这种工作方式。
-
证书信息不全。你证书没调好,也是有可能的,因为他们说复杂了太复杂,总之就是由于他们一些东西可以省略,所以他们就省略了,但是这个可以省略的内容没有可以从外部提供,完蛋,证书的机构信息缺了,就依然认为不可行。
-
手机操作系统比较旧。比如你用一个12年的操作系统,这些年一直没更新过根证书,然后来了一个比较新的证书机构,18年成立的,他签署的这些证书你的旧手机是无法看懂的,他认为你这个东西就是不合法,因为我系统里面的所有的根证书都没有对他进行签名,那么我认为你不合法。
-
-
怎么办?
- 自己写证书验证过程。google搜索android https。这个网站里面都有developer.android.com/training/ar…
-
如果搞清楚了上面的内容,应该是可以看懂的。可能只是需要点时间而已。