计算机网络——公钥私钥、非对称加密、数字签名与数字摘要、HTTPS和SSL 最容易理解的说明 & RSA+AES加密
问题的提出:
特务互相通过网络或者电话信件传递消息,为了防止情报被其他人看到,为了实现这个想法,要解决很多问题,如:
- 对文件内容使用暗号加密,如再见写成886(相当于对称加密)。
- 但是方案1面临管理上的难题,当特务人数增多时,不可能每两个特务之间约定一个新的加密算法(如果特务人数很多),一旦有一个人泄露了密码,文件就不安全了。且要求提供一条安全的渠道使通讯双方在首次通讯时协商一个共同的密钥。直接的面对面协商可能是不现实而且难于实施的,所以双方可能需要借助于邮件和电话等其它相对不够安全的手段来进行协商;
- 方案2还面临文件完整性的问题,如信息传输中,有的信息受到网络波动等等原因丢失了,比如传输的是明天不打仗的消息是错的,只传输了明天不打仗。
- 同时还要提供更改算法(如忘记、被盗)等机制。
概括来说就是:一个人的密码泄露 全部完蛋 多个密码又不现实 且约定密码的过程不安全 文件完整性也无法保障。
因此,要使用非对称的密匙方案替代对称的密匙方案
吴某凡案

这个诈骗案牛逼在于,中间人刘某有双重身份.
不仅冒充都某竹的身份来向吴某凢索取赔偿,而且又冒充吴某凢的身份骗都某竹把退款的钱转到中间人刘某的银行卡,从而获取利益。
这波操作说实话比电影还精彩,刘某把中间人的角色演技到了极致,它做到了三件事情:
冒充身份,不仅冒充了都某竹的身份,而且冒充了吴某凢的身份;
篡改信息,骗都某竹把退款的钱,退到中间人刘某的银行卡;
窃听信息,因为冒充了身份,所以都某竹和吴某凢双方的信息,刘某都牢牢的掌握在手中。
不知道大家有没有察觉中间人刘某做的这三件事情,正是 HTTP 协议的安全风险?
HTTP 协议不仅传输的信息是明文,而且没有身份认证,所以存在窃听风险、篡改风险、冒充风险。
为了解决 HTTP 协议的安全性,后面就出现了 HTTPS 协议,在 HTTP 层与 TCP 层之间加入了 TLS 协议,来保证安全可靠的信息传输。

非对称加密
在引入之前需要提及哈希算法,哈希算法的特性是加密容易而解密困难,如算出3*4=12容易,而要逆推出12等于哪两个相邻数字相乘则相对困难。
与对称加密算法不同,非对称加密算法需要两个密钥:公钥和私钥是成对的存在,如果对原文使用公钥加密,则只能使用对应的私钥才能解密;因为加密和解密使用的不是同一把密钥,所以这种算法称之为非对称加密算法。
- 公钥,这个是可以公开给所有人的;
- 是私钥,这个必须由本人管理,不可泄露。
需要通指出的是,过私钥经过一系列算法是可以推导出公钥的,也就是说,公钥是基于私钥而存在的。但是无法通过公钥反向推倒出私钥,这个过程的单向的。
但是 这两个密钥可以双向加解密的,比如可以用公钥加密内容,然后用私钥解密,也可以用私钥加密内容,公钥解密内容。
流程的不同,意味着目的也不相同:
- 公钥加密,私钥解密。这个目的是为了保证内容传输的安全,因为被公钥加密的内容,其他人是无法解密的,只有持有私钥的人,才能解密出实际的内容;
- 私钥加密,公钥解密。这个目的是为了保证消息不会被冒充,因为私钥是不可泄露的,如果公钥能正常解密出私钥加密的内容,就能证明这个消息是来源于持有私钥身份的人发送的。
一般我们不会用非对称加密来加密实际的传输内容,因为非对称加密的计算比较耗费性能的。
所以非对称加密的用途主要在于通过「私钥加密,公钥解密」的方式,来确认消息的身份,我们后面常说的数字签名算法,就是用的是这种方式,不过私钥加密内容不是内容本身,而是对内容的哈希值加密。
此时,若A向B发送消息,A先将公钥发给B,然后B使用接收到的公钥加密信息,连同B自己的公钥发给A,之后就实现了安全通信。而这在对称加密中是不可能做到到的,因为传输密码的过程可能会被劫持,从而之后也不可能是安全的了。
但是,非对称加密也存在问题,如果C伪造A同B进行通信,把自己的公钥过去给B,而伪装成A的公钥呢?这样不就避开了之前的环节,可以直接伪造A的身份骗取B的信息。
数字摘要与数字签名
首先是 普通的数据完整性,比如你下载的文件是否有缺失,使用数字摘要的方式。

- 数据完整性:非故意的 主要是网络传输可能丢包等原因
- 数据防篡改 :故意的,人为,篡改者会同时修改内容和哈希结果
而数字签名还要解决防篡改的问题:
- 为了保证信息的完整性,A可以先使用Hash函数对将要发送的正文内容生成一段唯一的128位数的摘要。
- 为了保证未被篡改性。A通过自己的私钥对数字摘要加密,生成了一段数字签名。之后,A将这一段数字签名连同信息内容一起发送过去。
- B收到信件后,通过公钥对数字签名和文章内容单独进行解密,之后通过同样的算法对接受到的正文生成摘要,同接收到的摘要进行对比。
- 如果一致代表文件完整,不一致则不完整。
当然,安全通信需要一定的性能为代价,然而,这不能保证信息是完全的,因而需要引入数字签名。

数字证书——如何获取安全的公钥,信任链
上面数字签名有个问题,在于你如何安全的获取公钥呢?
要解决的问题是保证客户端收到的公钥是真正的服务端给予的!
证书颁发机构,即认证中心CA (Certification Authority),来将公钥与其对应的实体(人或机器)进行绑定(binding);即给公司或个人颁发证书。
数字证书是由权威机构(如CA)颁发的电子文件,包含公钥和身份信息,用于验证实体身份并建立通信信任链。
把用户A的公钥和私钥假设为身份证。如果是用户A自己造的身份证别人会信吗?反之,用户A拿着真正的身份证去住宾馆,老板一开始也不相信身份证是用户A的,但是老板相信给用户A发身份证的公安局,老板通过比对公安网上对应身份证号码的信息就可以判断这个身份证是不是用户A的,由此可以确认用户A的身份。
CA就是这个第三方信任的机构。
1 如何保证客户端所持有的公钥就是服务器声明的公钥?
即服务器端如何安全地把它的公钥下发给客户端(这里的客户端一般指的是浏览器)。
如果不能保证这一点,那么客户端发送的信息就有可能存在被窃听的风险,因为客户端用此公钥加密的数据可以被其对应的私钥拥有者获取,而该私钥并不在客户端所认为的服务器上。 相当于攻击者给了客户端一个它自己的公钥,让客户端认为这个公钥是某合法服务器的公钥,于是客户端用此公钥对数据进行加密传送,攻击者将此加密数据截获并用自己的私钥进行解密。由于客户端用来加密的公钥就是攻击者给客户端的,因此攻击者能够获取解密之后的明文,从而窃取客户端的信息。
所以,可采用一个权威机构进行证书的颁发,所谓证书就是包含了服务器声明的公钥以及组织名称等信息,这里我们只考虑最关键的公钥信息。该权威机构会对申请证书的组织进行审核,确保其身份合法,然后将服务器公钥信息发布给客户端,客户端可利用该公钥与对应的服务器进行通信。整个过程可归纳为以下几步:
- 1.服务器生成一对密钥,私钥自己留着,公钥交给数字证书认证机构(CA)
- 2.CA进行审核,并用CA自己的私钥对服务器提供的公钥进行签名(参照下文RSA签名)
- 3.客户端从CA获取证书(即获取服务器端公钥),并通过签名判断真实性。最后拿到了服务器端的公钥。

2、如何保证客户端拿到的证书(服务器公钥)确实是权威机构(CA)颁发的证书?
要保证这一点,上面第2步中的CA用自己的私钥对服务器提供的公钥进行签名就起到了作用。为确保该证书确实是CA颁发的,因此需要用到上面论述的RSA签名防篡改的功能。客户端需要用CA的公钥对签名(签名见下文介绍)的证书进行验证,比对一致,说明该服务器公钥确实是CA颁发的。(不知道此时读者是否能想到CA发给客户端的证书信息不只有服务器的公钥,还有CA对此公钥进行的签名。)而CA又作为权威机构保证该公钥的确是服务器端提供的,从而可以确认该证书中的公钥确实是合法服务器端提供的。
那么问题又来了:
3、如何保证客户端所持有的CA公钥确实是CA的私钥所对应的公钥?
也就是说CA的公钥必须要安全地转交给客户端,这真是一个先有鸡还是先有蛋的问题。幸运的是,CA的公钥一般来说由浏览器开发商内置在浏览器的内部。于是,CA的公钥就安全地转交给了客户端(浏览器)。
也许你又要问了,万一我的浏览器就有问题呢?那我只能说:兄弟,少用盗版,实在不行,卸载重装吧。好吧,开个玩笑_
由此可见:所谓的安全的HTTP,其实也是要建立在信任的机制上。
数字证书签发流程与客户端验证流程以及证书信任链

CA 签发证书的过程,如上图左边部分:
首先 CA 会把持有者的公钥、用途、颁发者、有效时间等信息打成一个包,然后对这些信息进行 Hash 计算,得到一个 Hash 值;
然后 CA 会使用自己的私钥将该 Hash 值加密,生成 Certificate Signature,也就是 CA 对证书做了签名;
最后将 Certificate Signature 添加在文件证书上,形成数字证书;
客户端校验服务端的数字证书的过程,如上图右边部分:
首先客户端会使用同样的 Hash 算法获取该证书的 Hash 值 H1;
通常浏览器和操作系统中集成了 CA 的公钥信息,浏览器收到证书后可以使用 CA 的公钥解密 Certificate Signature 内容,得到一个 Hash 值 H2 ;
最后比较 H1 和 H2,如果值相同,则为可信赖的证书,否则则认为证书不可信。
但事实上,证书的验证过程中还存在一个证书信任链的问题,因为我们向 CA 申请的证书一般不是根证书签发的,而是由中间证书签发的,比如百度的证书,从下图你可以看到,证书的层级有三级:

对于这种三级层级关系的证书的验证过程如下:
- 客户端收到 baidu.com 的证书后,发现这个证书的签发者不是根证书,就无法根据本地已有的根证书中的公钥去验证 baidu.com 证书是否可信。于是,客户端根据 baidu.com 证书中的签发者,找到该证书的颁发机构是 “GlobalSign Organization Validation CA - SHA256 - G2”,然后向 CA 请求该中间证书。
- 请求到证书后发现 “GlobalSign Organization Validation CA - SHA256 - G2” 证书是由 “GlobalSign Root CA” 签发的,由于 “GlobalSign Root CA” 没有再上级签发机构,说明它是根证书,也就是自签证书。应用软件会检查此证书有否已预载于根证书清单上,如果有,则可以利用根证书中的公钥去验证 “GlobalSign Organization Validation CA - SHA256 - G2” 证书,如果发现验证通过,就认为该中间证书是可信的。
- “GlobalSign Organization Validation CA - SHA256 - G2” 证书被信任后,可以使用 “GlobalSign Organization Validation CA - SHA256 - G2” 证书中的公钥去验证 baidu.com 证书的可信性,如果验证通过,就可以信任 baidu.com 证书。
在这几个步骤中,最开始客户端只信任根证书 GlobalSign Root CA 证书的,然后 “GlobalSign Root CA” 证书信任 “GlobalSign Organization Validation CA - SHA256 - G2” 证书,而 “GlobalSign Organization Validation CA - SHA256 - G2” 证书又信任 baidu.com 证书,于是客户端也信任 baidu.com 证书。
总括来说,由于用户信任 GlobalSign,所以由 GlobalSign 所担保的 baidu.com 可以被信任,另外由于用户信任操作系统或浏览器的软件商,所以由软件商预载了根证书的 GlobalSign 都可被信任。
总结
整个过程涉及2对公私密钥对:
- 一对由服务器产生,用于加密
- 一对由CA产生,用于签名。
整个过程还涉及2个信任:
- 客户端信任CA颁发的证书中的公钥就是合法服务器的公钥
- 客户端信任浏览器内置的CA公钥就是与CA私钥对应的公钥
最后要说明的是,由于非对称加密算法的效率不高,非对称加密在HTTPS中只是用来对对称加密密钥进行协商的过程才使用,在两端协商完对称加密的密钥之后,数据的加密传输均采用对称加密的方式。
(数字证书部分转自:https://blog.csdn.net/abinge317/article/details/51791856)

RSA+AES加密
RSA属于非对称加密算法,它虽然解决了“在不安全的信道上安全地传递密钥”这一问题,但缺点在于运算量太大,造成加/解速度太慢,所以在具体的工程应用上是混合使用了对称和和非对称加密算法,比如SSL/TLS协议是混合使用了RSA和AES算法。具体的过程是,用RSA算法加密对称密码再传递给对方,然后双方使用对称加密算法通信;另外,RSA还起到CA认证的作用(其实就是验证由CA的私钥签名的,对方的公钥)。
由此可见,RSA的作用已经由“加密数据”减弱为“验证CA证书”和“共享对称密钥”,如果第二个作用由DH算法代替,那么,RSA就仅用于验证CA证书了。
A用户要把数据加密传输给B用户,步骤如下:
1、B生成公钥/私钥对,并把其中的公钥导出,通过公开信道传递给A;
2、A生成对称密码;
3、A用对称加密算法对文件进行AES加密;
4、A用B的公钥加密对称密码(形成数字信封);
5、A将数字信封和密文通过网络等渠道传送B;
6、B用自己的私钥解密对称密码;
7、B用解密后的对称密码解密密文;
具体的操作步骤:



- 建立连接时候:https 比 http多了 TLS 的握手过程;
- 传输内容的时候:https 会把数据进行加密,通常是对称加密数据;
https就一定完全可靠么?
中间人的原理

这个问题的场景是这样的:客户端通过浏览器向服务端发起 HTTPS 请求时,被「假基站」转发到了一个「中间人服务器」,于是客户端是和「中间人服务器」完成了 TLS 握手,然后这个「中间人服务器」再与真正的服务端完成 TLS 握手。
具体过程如下:
- 客户端向服务端发起 HTTPS 建立连接请求时,然后被「假基站」转发到了一个「中间人服务器」,接着中间人向服务端发起 HTTPS 建立连接请求,此时客户端与中间人进行 TLS 握手,中间人与服务端进行 TLS 握手;
- 在客户端与中间人进行 TLS 握手过程中,中间人会发送自己的公钥证书给客户端,客户端验证证书的真伪,然后从证书拿到公钥,并生成一个随机数,用公钥加密随机数发送给中间人,中间人使用私钥解密,得到随机数,此时双方都有随机数,然后通过算法生成对称加密密钥(A),后续客户端与中间人通信就用这个对称加密密钥来加密数据了。
- 在中间人与服务端进行 TLS 握手过程中,服务端会发送从 CA 机构签发的公钥证书给中间人,从证书拿到公钥,并生成一个随机数,用公钥加密随机数发送给服务端,服务端使用私钥解密,得到随机数,此时双方都有随机数,然后通过算法生成对称加密密钥(B),后续中间人与服务端通信就用这个对称加密密钥来加密数据了。
- 后续的通信过程中,中间人用对称加密密钥(A)解密客户端的 HTTPS 请求的数据,然后用对称加密密钥(B)加密 HTTPS 请求后,转发给服务端,接着服务端发送 HTTPS 响应数据给中间人,中间人用对称加密密钥(B)解密 HTTPS 响应数据,然后再用对称加密密钥(A)加密后,转发给客户端。
从客户端的角度看,其实并不知道网络中存在中间人服务器这个角色。那么中间人就可以解开浏览器发起的 HTTPS 请求里的数据,也可以解开服务端响应给浏览器的 HTTPS 响应数据。相当于,中间人能够 “偷看” 浏览器与服务端之间的 HTTPS 请求和响应的数据。
但是要发生这种场景是有前提的,前提是用户点击接受了中间人服务器的证书。
中间人服务器与客户端在 TLS 握手过程中,实际上发送了自己伪造的证书给浏览器,而这个伪造的证书是能被浏览器(客户端)识别出是非法的,于是就会提醒用户该证书存在问题。

如果用户执意点击「继续浏览此网站」,相当于用户接受了中间人伪造的证书,那么后续整个 HTTPS 通信都能被中间人监听了。
所以,这其实并不能说 HTTPS 不够安全,毕竟浏览器都已经提示证书有问题了,如果用户坚决要访问,那不能怪 HTTPS ,得怪自己手贱。
另外,如果你的电脑中毒了,被恶意导入了中间人的根证书,那么在验证中间人的证书的时候,由于你操作系统信任了中间人的根证书,那么等同于中间人的证书是合法的,这种情况下,浏览器是不会弹出证书存在问题的风险提醒的。
这其实也不关 HTTPS 的事情,是你电脑中毒了才导致 HTTPS 数据被中间人劫持的。
所以,HTTPS 协议本身到目前为止还是没有任何漏洞的,即使你成功进行中间人攻击,本质上是利用了客户端的漏洞(用户点击继续访问或者被恶意导入伪造的根证书),并不是 HTTPS 不够安全。
抓包工具的原理
为什么抓包工具能截取 HTTPS 数据?
很多抓包工具 之所以可以明文看到 HTTPS 数据,工作原理与中间人一致的。
对于 HTTPS 连接来说,中间人要满足以下两点,才能实现真正的明文代理:
- 中间人,作为客户端与真实服务端建立连接这一步不会有问题,因为服务端不会校验客户端的身份;
- 中间人,作为服务端与真实客户端建立连接,这里会有客户端信任服务端的问题,也就是服务端必须有对应域名的私钥;
中间人要拿到私钥只能通过如下方式:
- 去网站服务端拿到私钥;
- 去CA处拿这个域名签发私钥;
- 自己签发证书,切要被浏览器信任;
不用解释,抓包工具只能使用第三种方式取得中间人的身份。
使用抓包工具进行 HTTPS 抓包的时候,需要在客户端安装 Fiddler 的根证书,这里实际上起认证中心(CA)的作用。
抓包工具能够抓包的关键是客户端会往系统受信任的根证书列表中导入抓包工具生成的证书,而这个证书会被浏览器信任,也就是抓包工具给自己创建了一个认证中心 CA,客户端拿着中间人签发的证书去中间人自己的 CA 去认证,当然认为这个证书是有效的。
如何避免被中间人抓取数据?
我们要保证自己电脑的安全,不要被病毒乘虚而入,而且也不要点击任何证书非法的网站,这样 HTTPS 数据就不会被中间人截取到了。
当然,我们还可以通过 HTTPS 双向认证来避免这种问题。
一般我们的 HTTPS 是单向认证,客户端只会验证了服务端的身份,但是服务端并不会验证客户端的身份。

如果用了双向认证方式,不仅客户端会验证服务端的身份,而且服务端也会验证客户端的身份。服务端一旦验证到请求自己的客户端为不可信任的,服务端就拒绝继续通信,客户端如果发现服务端为不可信任的,那么也中止通信。
其他
tls和ssl有什么区别
这两实际上是一个东西。
SSL 是洋文 “Secure Sockets Layer” 的缩写,中文叫做「安全套接层」。它是在上世纪 90 年代中期,由网景公司设计的。
到了1999年,SSL 因为应用广泛,已经成为互联网上的事实标准。IETF 就在那年把 SSL 标准化。标准化之后的名称改为 TLS(是 “Transport Layer Security” 的缩写),中文叫做 「传输层安全协议」。
很多相关的文章都把这两者并列称呼(SSL/TLS),因为这两者可以视作同一个东西的不同阶段。
为啥 SSL 的握手是 4 次?”
SSL/TLS 1.2 需要 4 握手,需要 2 个 RTT 的时延,我文中的图是把每个交互分开画了,实际上把他们合在一起发送,就是 4 次握手:

另外, SSL/TLS 1.3 优化了过程,只需要 1 个 RTT 往返时延,也就是只需要 3 次握手:

更多推荐


所有评论(0)