前言
不知道大家发现没有(你肯定发现了),最近几年绝大多数的网站首页URL中的协议都变成了https了。作为用户,给人的感觉并有没有什么特别的,依然是输入baidu.com就可以搜索了,输入zhihu.com就可以提问了,输入juejin.cn就可以看技术文章了,无非就是偶尔会遇到浏览器提示此网站不安全,需要下载并导入一个证书什么的;作为一名网站开发者,如果你没有负责过配置https,也不会影响你正常开发业务功能,对你来说依然可以使用浏览器的F12打开浏览器的调试模式,所有的http请求和响应查看方式和之前一样,但是如果让你去把公司所有的项目都升级到https,你就必须要了解https中的那些事儿,如下:
- https到底安全在哪里?在浏览器中通过F12查看请求和响应数据,也都能看见呀,感知不强?
- 什么是对称加密和非对称加密?非对称加密在https中的作用是什么?
- 什么是CA证书,为什么要申请或者自己制作一个CA证书?
- https只有加密作用吗?
什么是HTTPS?
既生瑜,何生亮,有了HTTP协议,为何又搞个HTTPS?不用想,肯定是让人痛苦了,就像咱们公司的代码和架构一样,随着业务发展,不能满足业务需求了,就必须要进行重构和升级了。在HTTPS之前,HTTP协议传输的信息都是明文,直接裸露在整个网络中,很容易被黑客拦截、篡改,信息安全得不到保障,因此为了解决这个问题,HTTPS诞生了。
那么,问题来了,我用http协议传输数据,不管什么请求都用post方法提交不就好啦?
小编曾经就职过的一家公司就是这样规范的,不管查询还是修改,post一把梭!主要原因可能还是考虑到大家的编码水平不一,为了防止一些意外结果发生,才这样要求的;或者说架构师架构设计得不太合理。其实后面想想,post只是相对于get来说把数据放在了请求体中,并没有改变http协议明文传输的本质,黑客要搞你,分分钟的事情。
如果要想数据安全传输,非用https不可吗?
当然也不是非https不可,我们可以自己对业务数据进行加密后传输,服务端收到数据后再进行解密。但是采用什么加解密算法,需要评估,对称加密:密钥如何传输才能不被窃取?非对称加密:同样需要考虑公钥/私钥如何交换才能不被窃取?更重要的是非对称加密的性能问题;最重要的是,加解密操作和业务逻辑处理严重耦合,所以专业的事情交给专业的人去做,这个专业的人就是https了
HTTPS(全称为Hypertext Transfer Protocol Secure)是一种安全的通信协议,用于在计算机网络上进行数据传输。它对HTTP协议进行了扩展,通过使用SSL(Secure Sockets Layer)或TLS(Transport Layer Security)协议来保护数据的传输过程,即HTTPS=HTTP+SSL/TLS,HTTP就不用多说了,本文要说的事儿就是SSL/TLS中的事儿!说到安全,肯定就逃不开加解密啦。
必须要了解的加解密原理
什么是加密、解密?
加密:是指将原始数据(明文)通过一种特定的算法进行转换,生成一段不可读的密文。加密过程使用密钥作为参数,决定了加密的方式和结果,不同的密钥会产生不同的密文结果。
解密:是指将密文通过使用相同的密钥和相应的解密算法进行逆向操作,还原成原始的明文数据。只有拥有正确的密钥才能进行解密操作,解密的过程是加密的逆过程。
根据加密与解密是否使用同一个密钥,把加密又分为对称加密、非对称加密。
什么是对称加密?
对称加密: 即通信双方一起协商一个密钥,同时用这个密钥进行加密和解密。常见的对称加密算法有:AES、DES。
对称加密示例
加密过程如下图:
小兰通过邮件的方式将密钥告诉了小明(假设其他人都不知道),小明收到邮件后,知道密钥为“123”,这样双方都知道密钥后,就可以愉快的交流啦。小兰想告诉小明:“I love you”,用“123”加密后变成"ASD",小明收到“ASD”后用“123”解密就能知道小兰说的:“I love you”(小明暗喜),反过来也是一样的。看似没啥问题,只能说他俩太年轻,忽略了江湖中的人心险恶!
对称加密主要的特点:简单,高效,随着密钥越长,安全性就越高。
如何安全的把密钥告诉对方?
如上图,小兰和小明约定一个密钥为“123”,不管小兰是通过邮件告诉小明,还是通过写信的方式告诉小明,都存在被窃取的风险,前者需要通过网络,很可能就被黑客(黑客小王,看不惯他俩搞暧昧)拦截了,后者在邮寄路上也可能被邮递员拆封(此时小王化身快递员)了,此时小兰发送消息给小明就可能被小王拦截并篡改(同样使用123加密原文“I hate you”),小明最后解密后的消息为“I hate you”(小明开始郁闷);或者小兰把密钥存在U盘里面,然后当面拿给小明,这样就不会被其他人知道了(多此一举,不如直接表白来得快),但是很多情况下都是各在一地,这样当面给的话,不太现实。或者说小兰是班长,要通知全班同学暑假作业的内容,不能拿着U盘,每个同学家里都跑一趟吧,有没有一种方式即可以保证密钥安全的给到对方还能不被别人窃取呢?那就要用到非对称加密的数字签名功能了。
什么是非对称加密?
非对称加密:即对同一明文地加密和解密使用不同的密钥。这两个密钥其中一个可以公开让所有人知道,称为公钥;另一个不能被公开,称为私钥,两个合起来称为密钥对儿。用公钥加密的消息,必须使用私钥解密;用私钥加密的消息,必须用公钥解密。常见的有RSA、DSA。
非对称加密示例(RSA为例):
- 使用单方的密钥对儿
如上图,小兰和小明为了防止他们的聊天信息被小王知道,决定采用非对称加密,具体流程如下:
- 小兰生成自己的密钥对(公钥AAA,私钥aaa),然后通过邮件把公钥AAA发送给小明
- 小明拿到后,使用小兰的公钥AAA加密消息发送给小兰
- 小兰收到消息后使用自己的私钥aaa解密,即可得到消息
- 小兰用自己的私钥加密需要回复的消息,小明收到后用小兰的公钥解密消息。
此方式有个最大的问题就是,公钥是公开的,除了小明知道,小王也可能知道,全地球的人都可能知道。虽然小明给小兰发的消息,只有小兰可以用私钥解开,但是在小兰用私钥加密消息回复小明时,秘密就被公开了,所以一般不会直接使用非对称加密来通信,如果一定要使用也必须是通信双方的密钥对儿。
非对称加密:由于其算法实现的复杂性,整体加解密的效率相对对称加密来说要低很多,一般只会使用非对称加密的数字签名功能
- 使用双方的密钥对儿
如上图,为了对付小王,继续加码,小兰、小明决定采用双方的公私钥对儿。具体流程如下:
- 小兰(公:AAA,私:aaa)、小明(公:BBB,私:bbb)分别生成自己的公私钥对儿
- 小兰、小明分别通过邮件发送自己的公钥给对方
- 小兰使用小明的公钥BBB进行加密“I love you”发送给小明
- 小明收到消息后,使用自己的私钥bbb解密即可得到“I love you”
- 小明同样使用小兰的公钥AAA加密“我知道啦”回复给小兰
- 小兰使用自己的私钥aaa解密消息
因为用公钥加密消息后,必须使用私钥解密,所以整个过程中,即使小王知道了小兰和小明的公钥,他也不能解密。按照小王的性格,他岂能善罢甘休,此时小王又出招了!
非对称加密的漏洞:
如上图,化身黑客的小王出招了,具体流程如下:
- 通过拦截小兰、小明的邮箱得到他们的公钥AAA、BBB,同时把自己的公钥CCC传给他们
- 小兰、小明拿到小王的公钥CCC(都以为是对方的公钥),小兰用CCC加密消息发送给小明(小兰期待)
- 小王拦截小兰发送的消息,使用自己的私钥ccc解密,得到“I love you”(小王很生气)
- 小王拦截后,篡改消息为“I hate you”,同时用小明的公钥BBB加密发送给小明
- 小明收到消息后,用自己的私钥bbb解密,得到消息“I hate you”,(小明懵逼了)
- 小明需要回复消息给小兰,使用自己收到的小王的公钥CCC加密消息“哦,我知道了”发送出去
- 小王又拦截小明的消息,用自己的私钥ccc解密,得到消息“哦,我知道了”,(小王阴笑)
- 小王篡改消息为“I hate you too”,同时用小兰的公钥AAA加密,发送给小兰
- 小兰用自己的私钥aaa解密消息,得到“I hate you too”, (小兰哭了)
整个过程中,小兰与小明的通信都被小王给拦截掉包了,他们还不知道。在此过程中,同样存在最大的问题在于,小明如何确保收到的公钥就一定是小兰的?
对称加密+非对称加密
如上图,小兰和小明拿出绝招,结合对称加密和非对称加密来阻挡小王,大体流程如下:
- 小兰生成自己公钥:AAA, 私钥:aaa, 并把公钥发给小明
- 小明生成对称加密的密钥123,同时使用AAA对123加密得到ASD,并发送给小兰
- 小兰得到消息后,用私钥aaa解密ASD,得到对称加密密钥123
- 小兰用123加密"I love you"消息为QWE,发送给小明
- 小明用123解密消息QWE,得到"I love you"
- 小明使用123加密“我知道啦”得到ERT,发送给小兰
- 小兰使用123解密ERT得到“我知道啦”
整个过程看起来无懈可击了,因为小明使用小兰的公钥AAA加密“对称加密的密钥123”,只有小兰的私钥aaa才可以解开,所以即使小王拦截了邮件信息知道了小兰的公钥AAA也无妨,或者小王拦截了小明的公钥加密后的消息,因为没有私钥也无法解开。但是,黑客出身的小王,见招拆招:①拦截小兰的公钥AAA,把自己的公钥CCC发给小明 ②小明用公钥CCC加密123为ASD,发送给小兰 ③小王拦截之,使用私钥ccc解密ASD,得到对称加密密钥123 ④此后他们俩的聊天对于小王来说就是透明的了。还是老问题:小明如何确保收到的公钥就一定是小兰的?
故事的最后,小兰还是飞到小明家,当面儿把他俩的事说清楚了!其实不用飞,使用数据签名就能解决。
什么是数字签名、数字证书?
如上图左,小兰和小明之前还是债主关系,小明向小兰借了钱,小兰怕小明不还,于是叫小明写下欠条,签名并按手印,此时这个欠条就具有法律效应了。这里的签名就是数字签名的原型,这个欠条就能证明钱是小明借的,这里的欠条就是数字证书的原型。其实去掉数字两个字,不管是签名还是证书都是和现实社会中的签名和证书一样一样的。
再看上图右,小兰为了证明公钥是自己的,为自己的公钥进行签名,通过对公钥先进行MD5,然后再用私钥加密得到的一串字符串,就个字符串就称为数字签名;把数字签名附属到公钥明文信息后面,再加上小兰的一些基本信息,把这样的一个单据就称为数字证书,把这个数字证书发送给小明,小明拿到验证,验证成功后,即可确定是小兰的公钥。
像这种用自己的私钥去签名自己的公钥,称为根证书,就像陈欧为自己代言一样
数字签名: 是一种用于验证消息真实性和完整性的技术手段。结合加密算法和非对称加密技术,用于确认发送者身份并防止消息被篡改。一般使用发送者的私钥对消息进行加密,如果签名验证成功,可以确定消息没有被修改过,并且可以确实是由发送者生成和发送的。
数字证书: 数字证书是一种用于在互联网上验证身份和确保信息安全的电子文件。基于非对称加密技术,由认证机构(CA)颁发,用于确认某个实体的身份。一个数字证书主要包含了:网站域名、证书持有者、证书颁发机构、服务器的公钥、数字签名。这个数字签名就是使用颁发证书机构的私钥来加密生成的,以确保证书的完整性和真实性。
数字签名和验证流程,如下图:
数字签名过程:
- 通过散列算法(如MD5)把数据转换成固定长度的值,得到摘要信息(一般数据比较长,通过散列后可以大幅提高性能)
- 然后通过签名者的私钥加密摘要,即得到数字签名
- 把数字签名附属到数据后面,即形成数字证书
签名验证过程:
- 从数字证书中分别获取数据和签名信息
- 对数据进行MD5得到新摘要,同时对签名用签名者的公钥解密得到原来的摘要
- 对比新旧两个摘要是否一致,如果一致,说明这个数据签名就是来自这个签名者的,其次说明数据在网络传输过程中没有被篡改
又回到之前三角恋的故事,只要解决:“小明收到的公钥一定来自于小兰”的问题,他们就能在一起了。现在有了数字签名和证书,就一定能解决了吗?因为通过网络发送的,还是可以被小王拦截掉,小王用自己的公私钥对生成一个证书,把publicKey=CCC&sign=SDF12D34D56J发给小明,小明用CCC验证后,也能成功,这个时候证书不能随便自己生成了,需要去一个权威机构申请,证明你就是你!
什么是CA机构?
上面提到了一个问题,去一个权威机构申请一个证书,证明小兰就是小兰。以身份证为例,作为一个合法公民,每个人都有自己的身份证,有了身份证就可以走遍全国了。比如去住酒店,酒店前台要求你出示身份证,你出示后,酒店前台在一个机器上扫一下,发现没问题,随后说道:“先生/女士,这是你的房卡,请拿好,这边请!”。因为我们的身份证一般都是在户口所在地的镇级派出所办理的,派出所就是大家公认比较权威的一个机构,镇派出所给我们的办理身份证时,加上一个防伪标识(类似数字签名),这样身份证就能证明我就是我了。这样类似派出所的机构,在计算机领域中就称为CA机构。
CA是Certificate Authority(证书颁发机构)的缩写,主要是负责颁发和管理数字证书。主要任务是对申请者的身份进行严格的验证,一旦验证通过,CA将会生成一个含有申请者公钥和其他相关信息的数字证书,同时数字证书本身会由CA的私钥 进行签名,以确保证书的完整性和真实性。
还是以身份证为例,镇地方办理的身份证一定就是真的吗?谁来证明这个镇派出所身份的合法性,万一是一个假的派出所呢?换句话说,谁来证明镇派出所的私钥是合法的?这时就需要区县的公安局来证明了,同理区县的公安局由省市的公安局来证明,省市的公安局由国家公安局(假如有的话)来证明,那国家公安局由谁来证明呢?此时就需要相信国家、相信党了,国家公安局由它自己来证明,即用自己的私钥来签名自己的公钥(这里的证书就是根证书),这样形成的一个验证链,称为数字证书链。如下图:
什么是数字证书链?
数字证书链是由多个数字证书构成的链表,用于验证数字证书的有效性和信任问题。建立了一个从最底层证书到最顶层证书的层次结构。
-
数字证书链的顶层通常是由根证书颁发机构(Root CA)签发的根证书。根证书是最高级别的证书,它是信任链的根源(无条件信任),顶级CA机构将自己的根证书内置在操作系统或浏览器中,以便被信任。
-
根证书下面通常是中间证书颁发机构(Intermediate CA)签发的中间证书。这些中间证书由根证书颁发机构签发,并用于进一步颁发数字证书。中间证书的目的是将根证书与最终用户证书之间建立信任链。
-
最终用户证书是由中间证书颁发机构签发的实体的证书。这可以是网站、服务器、个人或组织的证书。最终用户证书包含了持有人的公钥、身份信息以及与该证书相关的其他数据。
数字证书链的验证过程是逐级进行的。当客户端收到一个数字证书时,它会检查证书上的签名,并通过查找证书链来验证证书的有效性。客户端会逐级验证证书链中的每个证书,直到达到根证书,并检查根证书是否能够与已知的根证书匹配。
最后看三人的故事,终于要迎来大结局了。小兰去CA机构B申请了证书,证书中包含了自己的公钥AAA,同时签名使用的是这个机构B的私钥,这个机构B的私钥,又由机构C的公钥去验证,机构C的私钥,又由根证书的公钥验证,根证书的公钥由自己的私钥验证。而此时小明的浏览器或操作系统已经内置了根证书,整个问题迎刃而解了!此时,作为黑客的小王不甘心呐,继续搞事情:
小明收到后对证书的签名进行验证,使用证书B的公钥对签名解密(浏览器会自动下载整个证书链的证书),得到ASD,再对明文CCC进行MD5后得到ASF,ASF不等于ASD, 说明证书被篡改了,小王失败
小明收到后对证书的签名进行验证,使用证书B的公钥对签名解密,签名被改了,解析乱码或错误,说明证书被篡改了,小王继续失败
如果伪造的证书域名也改成小王自己的,那小明访问的是小兰的域名,浏览器首先发现访问的域名和证书中的域名不一致,直接不响应,说明证书被篡改过;如果不修改域名,机构需要小王证明这个域名是小王的,让小王登录一个验证邮箱什么的,然后获取验证码等一系列操作,显然很麻烦,还是失败
这种情况下,只能给小王竖一个大拇哥,因为浏览器认为导入到信任列表的证书都是可信的。这种情况下,其实就不属于https的安全范畴了,说明了客户端电脑有漏洞被黑进去了
HTTPS实现原理
概述
https对比http,在http基础上新增了SSL层。服务端的http报文在SSL被加密发送到客户端,客户端在SSL层解密,然后到达应用层明文展示。
回答文章开头的问题:为什么通过HTTPS方式访问网址,浏览器F12还是能看到明文, 感知不强?
因为https加密是在SSL开始的,也就是说从TCP->IP->电缆->IP->TCP都是密文,到达客户端的SSL层开始解密,然后应用层就是解密后的明文信息,所以在通过F12查看时看到的就是解密后的明文信息
握手过程
SSL到底是先TCP握手,还是先交换密钥握手?
在cmd中,执行curl www.baidu.com, 通过wireshark工具抓包验证如下:
如上图:https先进行TCP三次握手后,才会进行加密握手,证书验证,加密传输数据。具体步骤如下:
先进行TCP三次握手,建立连接
客户端发送Cilent Hello信息,告诉服务端支持的TLS版本,随机数,及支持的加密套件集合
- Server Hello
- Certificate
- Server key Exchange
- Server Hello Done
总结