前言

早期的tcp/IP定位的直接就是能够更好的实现主机之间的通信,并没有过多的考虑安全问题。随着互联网规模的扩大以及鸟大了什么林子都有的原则,ftp、http、smtp、telnet这些协议都是明文传输的,很容易被不法分子利用,安全问题逐渐被人们重视,在互联网领域当中密码学是

安全的重要保障,密码学不是一项技术,而是科学,并且做为国家军事战略高度的科学,对于我们普通人来讲,密码学就是数据加密的机制。

加密的本质是一种转换规则。

常见的加密方式有三种:对称加密,非对称加密,单向加密

总结:因为应用的某些协议不安全,所以在应用层在传输层又加了半层,这半层以被称为TLS某种SSL,无论是TLS还是SSL,主要都是利用密码学来实现的,而密码学对我们这些使用者来讲就是一种转换规则,常见的加密方式又被分为三种:对称加密,非对称加密,单向加密。

补充:image.png

SM3中国首个hash算法

所谓的破解并不是通过密文推导出明文,而是找到了两个hash一样的数据。

所谓的数字签名就是CA用自己的私钥加密从数据中提取出来的特征码,实现了身份验证和数据的完整性。

算法并不依赖于算法的本身,而是依赖于密钥,算法本身很多都是公开的


对称加密和非对称加密

数据加密:公钥加密很少用到数据的加密的,因为太慢,密钥太长,对称加密比非对称加密快1000倍左右,公钥的主要舞台用于身体验证。加密数据的话一般要使用对称加密,加密完成之后的对称密钥再用非对称密钥加密。

数字签名:数字签名的主要目的是让接收方知道数据的确是发送方发送的,用于用户身份验证,发送方生成一段数据,用自己的私钥加密这段数据然后发给接收方,接收方通过发送方事先公开的公钥就是确认发送方的身份。

密钥交换:所谓的密钥交换我认为是在SSL的基础上理解上,比如bob把自己的证书发送给alice,而alice会生成一个对称密钥,通过bob给的证书当中的公钥加密这个对称密钥之后发送给bob.,密钥交换可以这样理解,通过非对称密钥来完成对对称密钥的交换.

小结

发送方用自己的私钥加密数据(数字签名),能够实现数据的身份验证,但是不能实现数据的机密性。

发送方用对方的公钥加密数据(密钥交换),可以保证的数据所机密性,但不可以身体验证。


举例

A给B发送一段数据,B要确认是这A发的(身份验证),数据没有被修改过(完整性),并不用保证数据的机密性。

A--------------->>------------B

答:A通过单向加密对数据提取一段特征码附加在文件的尾部,然后A通过自己的私钥仅仅加密最后一段特征码即可(数字签名),当B收到之后通过A事先公开的公钥实现对身份的验证,解开被加密后的特征码之后可以得到真正的特征码,然后B通过同样的单向加密算法,对数据进行单向提取特征码,通过与发送方发过来的特征码做比较来完成数据完整性的较验。

A--------->-----C-------->--------B

这个过程有没有可能被人破坏呢?是有可能,还是使用上述方式:“A对数据提取特征码附加在数据的尾部,然后通过自己的私钥加密发送给B。“  B想要解密A加密的特性码,肯定在加密A发送的数据前获取A的公钥,那么问题来了,B怎样才能获得A的公钥呢?一般就是A主动把自己的公钥发送给B,但是路上还是有C在拦截,C完全有可能把A发送给B的公钥给截获了,然后自己生成一对密钥,C把自己的公钥发送给B并说明自己就是A,然后B就相信了。当A给B发送真正的数据时,又被C给截获了,C即使不用A的公钥加密也完全能够看到A发送给B的内容,当然C的野心不仅仅是查看内容这么简单,C通常会把A给B发送的数据扔掉,然后自己生成一段数据(当然这段数据可能是辱骂B的数据)然后自己用单向加密提取特性码附加到数据的尾部,C再通过自己的私钥加密特性码之后发送给B,这时B还会拿着自己认为的A的公钥去解密特性码,然后对数据做一次单向提取之后与“A”发来的的特性码对照,经过对照发现这个辱骂自己的数据就是A发送的,于是C与A绝交。

 

三种算法放到一块,让A与B通信一次,并且保证不让C破坏

A-------------->>-------------B

还是A给B发送一个数据,并且要保证这个数据只能是B收到,并且不能被人篡改伪造。

  

第一步通过单向加密对数据提取特征码附加在数据的尾部,这是在原有的公钥上面附加了信息,原有的公钥没有变化。

第二步通过自己的私钥对特征码进行加密,这是把hash通过私钥(转换规则)进行了转换,并没有附加信息。

第三步然后把公钥+被私钥加密后的hash这两部分进行一次对称加密,此次加密遗留了一个对称密钥没处存放。

第四步然后通过对方的公钥对对称密钥再加加密一次。

image.png


1.    当B收到之后,首先通过自己的私钥打开对称密码,这里可以实现机密性,这个数据只有自己可以打开。

2.    用对称密钥,再打开被加密后的内容(公钥+被自己私钥加密后的HASH),这里什么也没实现,如果硬说实现了什么的话,那就是实现了效率,其实在这里就可以看到,是哪个CA给A发的证书。

3.    如果自己本地没有此CA的数字证书的话,就显示不信任的证书颁发机构,如果本地有此CA的数字证书会进一步进行验证,尝试是否能打开“被CA私钥加密后的hash”,如果能打开就实现了身份验证,说明此公钥的确是CA给颁发的。

4.    别急,还没完呢!再把A的公钥和附加信息hash一遍,然后与A发来的HASH进行对比,这一步可以实现完整性的校验。B(通常是客户端浏览器)应该还要检查此证书是否在证书颁发机构的吊销列表里面,还要再查看客户端访问的URL是否与公钥里面的信息一模一样,不一样也不行。

image.png

一次通信,三次加密算法都用上了。

这种通信机制当中还是存在了一个问题,依然存在着传输密钥时被C给截获的风险,依然是不安全



 PKI(Public Key Infrastructure)公钥基础设施

本小节主要介绍了:

l  公钥基础设施的概念和x509证书的格式

l  CA数据签名的过程以及客户端验证CA证书的过程

l  QQ是怎样实现加密的 

PKI的全称为public key infrastructure公钥基础设施,这是一个统称,就像新华电脑学院是多个专业的统称一样,其实公钥基础设施由四个部分组成,如下图:

image.png

   证书存取库:将来我们向CA申请证书的时候就是向证书存取库里面申请的。现在证书存取库发放的证书都是X.509的格式,X.509不仅仅是一种证书格式还是证书的规范,有三个版本,我们现在使用的都是它的第三版证书,它定义了一个规范的证书里面应该包括:

image.png

CA是怎样给某个主机进行发证的呢?

第一步:CA想要给别人发证,首先自己得有私钥和公钥。私钥用来给来申请的主机进行数字签名,公钥是要发给客户端的,用来实现对CA的身份验证,我们讲过的:“使用自己的私钥加密,让别人通过公钥打开,可以实现身份验证而不能实现数据的机密性”。

第二步:CA仅有私钥和公钥还不成,还要有自己的数字证书。为什么要自己有证书呢?一个CA为了方便用户的验证是要把自己的公钥公布于众的,但是并不是直接把自己的公钥直接公布出去,而是把自己的数字证书公布出去(数字证书里面有自己的公钥),为什么要这么做呢?直接公布公钥不成吗?直接公布公钥是很有可能被中间人伪造的,所以要公布自己的数字证书,这样方便用户的验证。实际上用户导入CA数字证书的机会很少,因为一般主流的操作系统在发行时都已经把最常见的CA机构的数字证书内置到了操作系统内部了,但是也有没有导入的CA,比如12306网站使用的CA。CA是给别人发证的,那么CA自己的证书是谁给它发的呢?答案是自己给自己发的,那么怎样才能自己给自己发证呢?是这样的,过程是很简单的,CA把自己的公钥和一些必需要填报的信息:比如主体名称,国家,城市,等等通过一个文件自己提交给自己,核实无误然后再用自己的私钥对这个请求文件进行数字签名,签过名之后就会生成一个数字证书。那么签名的过程是怎样的呢?由于CA是自己给自己发证,所以提交请求之后并没有进行验证,如果在真实的环境某主机给CA提交请求的话,CA机构会派人到该公司里内部核对申请的信息是否真实,有营业执照、公网IP,责任人等等确认无误之后,CA会通过单向加密,把主机提交的请求文件提取一个特征码附加在文件的尾部,然后通过自己的私钥仅对特征码进行加密,注意签名的过程并没有对数据进行加密,加密的只是文件尾部的特征码,被加密过的文件特征码申请信息就组成一个数字证书,生成数字证书的过程就是数字签名。从CA给企业颁发证书的这个过程来看,仅仅实现了一个完整性的校验,对于机密性和身份认证都不能实现 ,因为在这个阶段,企业还没有数字证书,最好的方式就是企业拿着U盘去CA把CA的数字证书拿过了,这样最为保险,当然也可以让CA把自己的数字证书送过来,其实这一步,一般是用不着用户做的,系统一般都会把常用CA的数字证书给安装好了。

第三步: CA将做签名的证书然后送回给申请的公司,申请的公司将把这个数字证书导入到需要使用的此证书的应用程序的主目录当中,比如,httpd会放到/etc/httpd/当中

NOTE:这个过程在下面的实验当中有演示。

用户怎样验证对方发来的证书是可信的呢?在描述验证以前我们应该明确一点,操作系统在发行时一般都会将市面上最常见,最权威的CA机构的公钥内置到操作系统的内部以方便用户的验证。

第一步:当alice把自己的证书(当然此证书一定要是某CA机构签署颁布的)发送给bob时,bob为了验证alice就是alice而不第三方伪装的,就要先打开alice给的数字证书,首先查看发行者(CA)的名称,如果此CA的名称与系统内置的某一个CA的名称重合,重合意味着系统内置了此CA的公钥,反之,就认为此CA机构不可信任。

第二步:bob通过系统内置的CA公钥去验证发行者(CA)的签名,怎样验证呢?我们在上面讲过,CA给alice签名就是“CA用自己的私钥对alice申请文件的特征码做加密”,所以bob只要用CA的公钥能够打开CA对alice的私钥签名就证明alice是确认是这个CA颁布的证书,我们在前面提过:”用自己的私钥加密可以实现身体验证,所以在这里bob能够用CA的公钥打开CA的签名就表示alice的证书就是信任的CA颁发的证书,到了这一步仅仅能说明证书里面的数据可能是正确的,为什么?因为证书里面的版本号、序列号、主体公钥等等都没有加密,仅仅是提取的特征码被加密而已,里面的信息还是有可能被中间人修改的。

第三步:第三步解开的是证书内部的:”版本号,序列号,主体公钥,主体名称等等“这些信息的特征码,bob还要通过单身加密计算出这些信息的特征码,然后通过自己的计算出的特征码与CA公钥打开的特征码做比较,如果一样,就表示证书内所有的信息都是完整的,可靠的。

第四步:客户端检查证书是否位于证书吊销列表当中,大部分浏览器都没有做最后一步,为了保险期间我们最好人工去查看一下。

现在互联网的证书主要有两种,一种是个人证书,一种是主机证书。银行给的U盾,U盾里面存放的就是用户自己的数字证书,当我们需要用电脑在网上转账的时候,服务器会把我们的http请求自动转换为https,转换为https的过程就是用户去验证服务器的数据证书的过程,这是单向的验证,我们在淘宝上付款时也是这样的,但是银行转账客户端不仅要验证服务器的数字证书,银行还要验证用户的数字证书,而用户的数字证书就在银行给的U盾里面,这个U盾里保存的数字证书就是个人证书,个人证书与主机证书最大的不同是主机证书的主体名字上写的是主机的名字,比如www.taobao.com而用户的数字证书上的主体名称是用户的姓名,比如马云。当然最为常用的还是主机证书,在这里需要注意的是证书里面的主体名一定要与真正主机的主机名要一致,不然的话,业务会失败.

CA

1.         生成一对密钥。

2.         利用公钥和申请信息产生一份申请文件提交给自己(此文件当中包括自己的公钥)。

3.         自己生成自己的数字签名证书:CA先利用hash提取出这个文件的特征码附加到文件的尾部,然后自己的私钥对此特征码加密,注意,文件并没有加密。

4.         将此数字签名证书公布于众,各大操作系统的发行商会将其集成到自己的操作系统当中。

HTTPS

1.         生成一对密钥

2.         利用公钥和申请信息产生一份申请文件提交给CA(此文件当中包括自己的公钥)。

3.         CA对申请信息核实无误之后,会生成数字签名证书:CA先利用hash提取出这个文件的特征码附加到文件的尾部,然后自己的私钥对此特征码加密,注意,文件并没有加密。

4.         CA将此数字证书给HTTPHTTP会将其放置到自己的工作目录的。

Client

Client默认就是有CA自己的数字签名的,也就是说用户有CA的公钥,发行商集成的嘛!

1.         当客户端访问网站时,当然先建立虚链路、然后附加TLS通道,服务器会把CA签名过的数字证书发送给客户端。

2.         客户端验证,怎样验证呢?用CA的公钥尝试打开网站给的数字证书当中被加密后的特征码,如果打开了就实现了身体验证,打开之后利用hash进一步验证完整性。

3.         客户端拿到网站的公钥之后会随机生成对称密钥,通过公钥加密之后发送给网站,然后后面它们加密的数据都是用对称密钥处理之后再发送。

QQ的加密通信:

当数据从资源子网交给通信子网之后,数据会被封装,但是封装并没有改变资源子网的数据,如果有人可以获取到这些包的话就可以看到通信子网当中的内容。可能有人说不会呀?我用QQ发送的数据即被抓到包也看不到里面发送的明文,这是怎么回事呢?其实“资源子网把数据给通信子网之后数据并没有改变”这个原则并没有改变,只不过是QQ这个软件本身实现了数据加密的功能(有的资源子网的协议或者软件可自行实现数据的加密,而有的协议或者软件本身是不支持加密的,像早期的QQ就不支持加密),像这样的案例还有,比如ftp,当我们使用ftp的时候就可以抓住ftp要传输的内容包括密码,如果我们在网上转账呢?这岂不是太不安全了,其实这是有解决办法的。像ftp这种资源子网当中的协议本身不能加密,而通信子网又不能改变数据的内容,只要在资源子网在通信子网之间加上半层,让这半层专门实现加密功能来加密数据。


TLS和SSL

SSl(安全的套接字层)和TLS(transport layer security)传输层安全

PKI是公共密钥基础设施,是为了数据能够安全可靠的传输,实质上这种设施是为了应用程序准备的,比如http(超文本传输协议)这个协议原本只能传输明文没有加密的机制,非常的不安全可靠,但是现在不同的了,有了公共密钥基础设施,我们就可以在http的基础上使用公共密钥基础设施,怎样使用呢?
OSI参考模型在之所以是七层很大原因就是某一层的调整并不会影响到其他层,我们在应用层和传输层中间再放半层,用这半层专门来实现对PKI的应用,凭什么这半层能够实现加密,就是因为这半层的主要任务就是协商加密方式,对数据进行加密,验证对方的数字证书,讲到这里,我们知道了,协商加密方式,对要传输的数据加密,验证对方的证书并不是计算机完成的,而是由这半个中间层完成的,那么这半个层就是TLS或者是SSL.

那么到底是TLS还是SSL呢?它们两个是什么关系呢? SSL(安全的套接字层)是网警一个公司为自己的浏览器的研制出的协议,后来微软打败的IE打败.后来国际标准化组织也搞了出了一个协议就叫TLS(传输层安全协议),TLS现在是第一版,相当于SSL的第三版,原理和机制差不多,那么我们下面再讲的时候是不加以区分的。有的软件仅支持SSL,有的仅支持TLS,有的两种协议都支持.

半层?一层?


那么为什么说这个中间层只有半层而不是一层呢?是这样的,如下图:

image.png

当http不使用TLS或者是SSL层的时候传输的都是明文,当http使用TLS或者SSL的时候就变成了https,传输的不同进明文而是密文,所以我们可以使用tls也可以不使用,这一层并不是必需存在的,所以这是说这是半个层而不是一个整层.

SSL只能基于IP地址的访问,而不能根据主机名来实现,因为SSL它终究不是应用层的的应用或者协议,它是位于应用层与传输层之间的库,SSL握手的时候只能基于IP,而不能基于主机名,是因为在使用基于主机名的访问的时候主机名是封装在应用层的,SSL可以读取到网络层的但是读取不到应用层的信息,所以无论是哪个虚拟主机,只要是IP一样,SSL都会当成一个会话来看待,一个IP地址基于一个应用层协议只能建立一个会话.

http VS https


本小节主要介绍了http和https的会话过程:

http的会话过程:

1.    客户端把请求发送到服务器上,服务器上的内核根据请求包当中的目标端×××给http服务

2.    http根据请求到的内容让内核去硬件当中调用数据,交给http进程

3.    http构建响应报文根据套接字回复到客户端并记录日志

https的会话过程:

1.    客户端向服务器发起请求

2.    服务器先要跟客户端协商到底使用SSL还有sls协议的哪个版本,这是双向的过程 。

3.    服务器会把自己的证书发给客户端(客户端一般没有证书),客户端是看签署的CA是不是自己信任的,信息是否完整,拿到服务器的公钥。

4.    客户端会生成一个随机会话对称秘钥,通过服务器端的公钥加密之后发送给服务器

5.    服务器端就可以这个对称秘钥进行使用了