HTTP协议简单介绍HTTP协议简单介绍-CSDN博客
目录
一、对称加密和非对称加密
对称加密
非对称加密
总结
二、HTTPS协议
定义
关键特点
工作原理
详细通信过程
1. 客户端请求连接
2. 服务器响应
3. 密钥交换
4. 加密通信
5. 关闭连接
编辑
优势
缺点
1. 性能开销
2. 配置复杂性
3. 成本
4. 兼容性问题
5. 不可避免的警告
6. 安全误区
对于HTTPS的通信过程中的问题思考
1. 为什么需要加密?
2. 用对称加密可行吗?
3. 用非对称加密可行吗?
4. 改良的非对称加密方案,似乎可以?
5. 非对称加密+对称加密?
6. 中间人攻击
7. 如何证明浏览器收到的公钥一定是该网站的公钥?
8. 如何放防止数字证书被篡改?
9. 中间人有可能篡改该证书吗?
10. 中间人有可能把证书掉包吗?
10. 为什么制作数字签名时需要hash一次?
11. 怎么证明CA机构的公钥是可信的?
12. 每次进行HTTPS请求时都必须在SSL/TLS层进行握手传输密钥吗?
一、对称加密和非对称加密
对称加密和非对称加密是两种主要的加密方法,分别用于保护数据的机密性和安全性。它们的工作原理、用途和优缺点各不相同。
对称加密
定义:对称加密是指加密和解密使用相同的密钥。这意味着发送方和接收方必须共享一个秘密密钥,才能进行安全通信。
工作原理:
- 加密:使用密钥对明文数据进行加密,生成密文。
- 解密:使用相同的密钥对密文进行解密,恢复出原始明文。
简单说就是有一个密钥,它可以加密一段信息,也可以对加密后的信息进行解密,和我们日常生活中用的钥匙作用差不多。
常见算法:
- AES(高级加密标准)
- DES(数据加密标准)
- 3DES(三重数据加密标准)
- RC4(流加密算法)
优点:
- 速度快:对称加密算法通常比非对称加密快,适合加密大量数据。
- 计算效率高:对称加密算法的计算复杂度相对较低。
缺点:
- 密钥分发问题:安全地共享密钥是一个挑战,尤其是在大规模系统中。
- 密钥管理:如果密钥泄露,任何人都可以解密数据。
非对称加密
定义:非对称加密是指使用一对密钥进行加密和解密,其中一个是公钥,另一个是私钥。公钥可以公开,而私钥必须保密。
工作原理:
- 加密:发送方使用接收方的公钥对明文数据进行加密,生成密文。
- 解密:接收方使用其私钥对密文进行解密,恢复出原始明文。
简单说就是有两把密钥,通常一把叫做公钥、一把叫私钥,用公钥加密的内容必须用私钥才能解开,同样,私钥加密的内容只有公钥能解开。
常见算法:
- RSA(Rivest-Shamir-Adleman)
- DSA(数字签名算法)
- ECC(椭圆曲线加密)
优点:
- 密钥分发安全:公钥可以公开,无需安全传输,从而简化了密钥管理。
- 数字签名:可以使用私钥进行数字签名,确保数据的完整性和真实性。
缺点:
- 速度慢:非对称加密的计算复杂度高,速度较慢,不适合加密大量数据。
- 资源消耗大:由于复杂性,使用时需要更多的计算资源。
总结
- 用途:对称加密适合于加密大量数据,而非对称加密适合于密钥交换和身份验证。
- 组合使用:在实际应用中,通常将两者结合使用。例如,使用非对称加密安全地交换对称密钥,然后使用对称加密进行数据传输。这种方式既保证了安全性,又提高了传输效率。
这种组合的典型应用就是HTTPS协议,利用非对称加密来交换对称密钥,之后使用对称加密保护数据传输的安全性。
二、HTTPS协议
定义
HTTPS(HyperText Transfer Protocol Secure)是一个安全的通信协议,主要用于在计算机网络中传输超文本数据。它是HTTP是超文本传输协议的安全版本,通过在HTTP协议上添加SSL/TLS(安全套接层/传输层安全性)来实现数据加密和安全验证。它结合了HTTP(超文本传输协议)和SSL/TLS(安全套接层/传输层安全性)技术,以确保数据在客户端和服务器之间传输时的机密性、完整性和身份验证。
关键特点
-
安全性:HTTPS通过对数据进行加密,确保在传输过程中不被窃听或篡改。即使数据被拦截,攻击者也无法读取内容。
-
身份验证:通过数字证书,HTTPS验证服务器的身份,确保用户连接到正确的网站,防止中间人攻击(MITM)。
-
数据完整性:HTTPS确保数据在传输过程中未被修改或损坏。通过使用消息认证码(MAC),接收方可以验证数据的完整性。
工作原理
-
握手过程:当用户在浏览器中输入HTTPS网址时,浏览器与服务器之间会进行一系列的握手,以建立安全连接。握手过程包括证书验证、密钥交换等步骤。
-
加密通信:一旦建立连接,客户端和服务器会使用对称加密技术对数据进行加密和解密。对称加密使用的是在握手过程中交换的会话密钥。
-
关闭连接:数据传输完成后,连接可以选择关闭,或者保持以便后续请求。
详细通信过程
1. 客户端请求连接
用户在浏览器中输入HTTPS网址,浏览器向目标服务器发送请求,要求建立安全连接。浏览器通过TCP连接向服务器的特定端口(通常是443)发送请求。
客户端通过发送一个 “ClientHello” 消息开始 TLS 握手。此消息包含客户端支持的 TLS 版本、一个客户端生成的随机数(client_random第一个随机数)、加密套件列表(cipher suites)、压缩算法列表,以及其他 TLS 扩展。
2. 服务器响应
服务器接收 “ClientHello” 消息后,回复一个 “ServerHello” 消息。此消息包含服务端确认支持的 TLS 版本、一个服务器生成的随机数(server_random第二个随机数)、选择的加密套件和压缩算法以及数字证书、证书链,证书链包括服务器的公钥证书和任何中间 CA 证书(但不含根 CA 证书),这个证书包含服务器的公钥及其身份信息(由权威认证机构CA签发)。
服务器还可能发送一个 “ServerKeyExchange” 消息(如果需要),包含服务器的公钥或 Diffie-Hellman 参数。
客户端收到服务器的证书后,验证证书的有效性,确认其是否由受信任的CA签发,以及证书中的域名是否与请求的域名匹配。
3. 密钥交换
如果证书验证成功,客户端会生成随机数(client_random第三个随机数/预主秘钥),这个预主秘钥不会直接发送出去,而是用刚刚收到的服务器的公钥进行加密后再发送出去。然后客户端这边的TSL协商已经没问题了,加密开始。
客户端将加密后的预主秘钥发送到服务端,服务端收到加密后的预主秘钥之后,会使用自己的私钥进行解密,成功后,这样服务器就知道预主秘钥了,而且只有客户端和服务端知道这个预主秘钥。因为没有进行直接传输,没有其他人知道这个预主秘钥是什么,除非私钥被泄露了。
最后,客户端用预主秘钥、第一随机数、第二随机数计算出会话密钥,服务端也用预主秘钥、第一随机数、第二随机数计算出会话密钥,各自得到的会话密钥是相同的。
也就是说前面的步骤为了得到这个会话密钥,都是非对称加密。后面的会话大家都只使用这个会话密钥对数据进行加密,也就是说后面的步骤使用的是对称加密,大家都使用同一个私钥,会话后面不使用非对称加密是因为大家都能看到消耗资源非常大,而日得到会适密钼以后就没人知道密银是什么了,因此后面使用对称加密。
如果与其它服务器沟通就是建立新的会话,会话密钥也不相同。会话密钥只应用在当前会话,更加提高了安全性。
4. 加密通信
后续的数据传输(如HTTP请求和响应)都使用该会话密钥进行加密。这样,即使数据在传输过程中被拦截,攻击者也无法解密数据。
完整性校验:为了确保数据在传输过程中没有被篡改,HTTPS还使用消息认证码(MAC)来验证数据完整性。
5. 关闭连接
在数据传输完成后,浏览器和服务器可以选择关闭连接,或者保持连接以便后续的请求。
优势
- 用户信任:通过HTTPS,网站可以向用户展示安全性,增强用户信任。许多浏览器会在地址栏中显示锁形图标,以指示该网站是安全的。
- SEO优势:搜索引擎(如Google)会优先考虑使用HTTPS的网站,认为其更安全,从而提升排名。
- 保护敏感数据:HTTPS非常适合处理敏感信息,例如登录凭证、信用卡信息和个人资料等。
HTTPS是现代网络通信中不可或缺的一部分。它不仅保护用户的隐私和安全,而且在用户信任和搜索引擎优化方面发挥了重要作用。随着网络安全威胁的增加,越来越多的网站开始采用HTTPS,以保护其用户和数据的安全。
缺点
尽管HTTPS提供了许多安全优势,但也存在一些缺点和挑战。以下是HTTPS的一些主要缺点:
1. 性能开销
计算资源:HTTPS的加密和解密过程需要更多的计算资源,相比HTTP会增加服务器和客户端的CPU负担。
握手延迟:HTTPS连接的建立需要进行握手过程,这涉及多次往返通信(RTT),可能导致连接建立的延迟,尤其是在高延迟网络环境中。
2. 配置复杂性
证书管理:部署HTTPS需要获取和安装SSL/TLS证书,这可能会涉及到复杂的配置过程。管理证书的有效性和更新也是一个挑战。
多域名支持:对于需要支持多个子域名的网站,使用通配符证书或多域名证书可能会增加复杂性和成本。
3. 成本
证书费用:虽然许多证书颁发机构(CA)提供免费证书(如Let’s Encrypt),但一些企业级证书可能需要支付高额费用。
服务器性能:由于HTTPS增加了服务器的负担,可能需要更强大的硬件来维持相同的性能水平。
4. 兼容性问题
老旧设备和浏览器:一些老旧的浏览器或设备可能不支持最新的加密协议和加密算法,这可能导致访问问题。
中间人攻击:尽管HTTPS可以防止许多类型的攻击,但如果用户连接到不受信任的Wi-Fi网络,仍然可能受到中间人攻击。
5. 不可避免的警告
证书错误:如果SSL/TLS证书出现错误(如过期或域名不匹配),浏览器会显示警告,这可能会影响用户体验和信任度。
6. 安全误区
过度信任:某些用户可能误认为使用HTTPS就意味着完全安全,而实际上,HTTPS只保护数据在传输过程中的安全,并不能保证服务器本身的安全性或应用程序的安全性。
尽管HTTPS有其缺点,但它仍然是现代互联网中保护数据和用户隐私的标准方法。通过适当的配置和管理,可以减轻这些缺点带来的影响。因此,网站在实现HTTPS时需要考虑其带来的优势与挑战,确保以最佳方式保护用户的安全和隐私。
对于HTTPS的通信过程中的问题思考
1. 为什么需要加密?
因为http的内容是明文传输的,明文数据会经过中间代理服务器、路由器、wifi热点、通信服务运营商等多个物理节点,如果信息在传输过程中被劫持,传输的内容就完全暴露了。劫持者还可以篡改传输的信息且不被双方察觉,这就是中间人攻击
。所以我们才需要对信息进行加密。最容易理解的就是对称加密
。
2. 用对称加密可行吗?
如果通信双方都各自持有同一个密钥,且没有别人知道,这两方的通信安全当然是可以被保证的(除非密钥被破解)。
然而最大的问题就是这个密钥怎么让传输的双方知晓,同时不被别人知道。如果由服务器生成一个密钥并传输给浏览器,那在这个传输过程中密钥被别人劫持到手了怎么办?之后他就能用密钥解开双方传输的任何内容了,所以这么做当然不行。
换种思路?试想一下,如果浏览器内部就预存了网站A的密钥,且可以确保除了浏览器和网站A,不会有任何外人知道该密钥,那理论上用对称加密是可以的,这样浏览器只要预存好世界上所有HTTPS网站的密钥就行了!这么做显然不现实。
怎么办?所以我们就需要非对称加密
。
3. 用非对称加密可行吗?
鉴于非对称加密的机制,我们可能会有这种思路:服务器先把公钥以明文方式传输给浏览器,之后浏览器向服务器传数据前都先用这个公钥加密好再传,这条数据的安全似乎可以保障了!因为只有服务器有相应的私钥能解开公钥加密的数据。
然而反过来由服务器到浏览器的这条路怎么保障安全?如果服务器用它的私钥加密数据传给浏览器,那么浏览器用公钥可以解密它,而这个公钥是一开始通过明文传输给浏览器的,若这个公钥被中间人劫持到了,那他也能用该公钥解密服务器传来的信息了。所以目前似乎只能保证由浏览器向服务器传输数据的安全性(其实仍有漏洞,下文会说),那利用这点你能想到什么解决方案吗?
4. 改良的非对称加密方案,似乎可以?
我们已经理解通过一组公钥私钥,可以保证单个方向传输的安全性,那用两组公钥私钥,是否就能保证双向传输都安全了?请看下面的过程:
- 某网站服务器拥有公钥A与对应的私钥A’;浏览器拥有公钥B与对应的私钥B’。
- 浏览器把公钥B明文传输给服务器。服务器把公钥A明文给传输浏览器。
- 之后浏览器向服务器传输的内容都用公钥A加密,服务器收到后用私钥A’解密。由于只有服务器拥有私钥A’,所以能保证这条数据的安全。
- 同理,服务器向浏览器传输的内容都用公钥B加密,浏览器收到后用私钥B’解密。同上也可以保证这条数据的安全。
的确可以!抛开这里面仍有的漏洞不谈(下文会讲),HTTPS的加密却没使用这种方案,为什么?很重要的原因是非对称加密算法非常耗时,而对称加密快很多。那我们能不能运用非对称加密的特性解决前面提到的对称加密的漏洞?
5. 非对称加密+对称加密?
既然非对称加密耗时,那非对称加密+对称加密结合可以吗?而且得尽量减少非对称加密的次数。当然是可以的,且非对称加密、解密各只需用一次即可。
请看一下这个过程:
- 某网站拥有用于非对称加密的公钥A、私钥A’。
- 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
- 浏览器随机生成一个用于对称加密的密钥X,用公钥A加密后传给服务器。
- 服务器拿到后用私钥A’解密得到密钥X。
- 这样双方就都拥有密钥X了,且别人无法知道它。之后双方所有数据都通过密钥X加密解密即可。
完美!HTTPS基本就是采用了这种方案。完美?还是有漏洞的。
6. 中间人攻击
如果在数据传输过程中,中间人劫持到了数据,此时他的确无法得到浏览器生成的密钥X,这个密钥本身被公钥A加密了,只有服务器才有私钥A’解开它,然而中间人却完全不需要拿到私钥A’就能干坏事了。请看:
- 某网站有用于非对称加密的公钥A、私钥A’。
- 浏览器向网站服务器请求,服务器把公钥A明文给传输浏览器。
- 中间人劫持到公钥A,保存下来,把数据包中的公钥A替换成自己伪造的公钥B(它当然也拥有公钥B对应的私钥B’)。
- 浏览器生成一个用于对称加密的密钥X,用公钥B(浏览器无法得知公钥被替换了)加密后传给服务器。
- 中间人劫持后用私钥B’解密得到密钥X,再用公钥A加密后传给服务器。
- 服务器拿到后用私钥A’解密得到密钥X。
这样在双方都不会发现异常的情况下,中间人通过一套“狸猫换太子”的操作,掉包了服务器传来的公钥,进而得到了密钥X。根本原因是浏览器无法确认收到的公钥是不是网站自己的,因为公钥本身是明文传输的,难道还得对公钥的传输进行加密?这似乎变成鸡生蛋、蛋生鸡的问题了。解法是什么?
7. 如何证明浏览器收到的公钥一定是该网站的公钥?
其实所有证明的源头都是一条或多条不证自明的“公理”(可以回想一下数学上公理),由它推导出一切。比如现实生活中,若想证明某身份证号一定是小明的,可以看他身份证,而身份证是由政府作证的,这里的“公理”就是“政府机构可信”,这也是社会正常运作的前提。
那能不能类似地有个机构充当互联网世界的“公理”呢?让它作为一切证明的源头,给网站颁发一个“身份证”?
它就是CA机构,它是如今互联网世界正常运作的前提,而CA机构颁发的“身份证”就是数字证书。
网站在使用HTTPS前,需要向CA机构申领一份数字证书,数字证书里含有证书持有者信息、公钥信息等。服务器把证书传输给浏览器,浏览器从证书里获取公钥就行了,证书就如身份证,证明“该公钥对应该网站”。
而这里又有一个显而易见的问题,“证书本身的传输过程中,如何防止被篡改”?即如何证明证书本身的真实性?身份证运用了一些防伪技术,而数字证书怎么防伪呢?解决这个问题我们就接近胜利了!
8. 如何放防止数字证书被篡改?
我们把证书原本的内容生成一份“签名”,比对证书内容和签名是否一致就能判别是否被篡改。这就是数字证书的“防伪技术”,这里的“签名”就叫数字签名。
这部分内容建议看下图并结合后面的文字理解,图中左侧是数字签名的制作过程,右侧是验证过程:
数字签名的制作过程:
- CA机构拥有非对称加密的私钥和公钥。
- CA机构对证书明文数据T进行hash。
- 对hash后的值用私钥加密,得到数字签名S。
明文和数字签名共同组成了数字证书,这样一份数字证书就可以颁发给网站了。
那浏览器拿到服务器传来的数字证书后,如何验证它是不是真的(有没有被篡改、掉包)?
浏览器验证过程:
- 拿到证书,得到明文T,签名S。
- 用CA机构的公钥对S解密(由于是浏览器信任的机构,所以浏览器保有它的公钥。详情见下文),得到S’。
- 用证书里指明的hash算法对明文T进行hash得到T’。
- 显然通过以上步骤,T’应当等于S‘,除非明文或签名被篡改。所以此时比较S’是否等于T’,等于则表明证书可信。
为何么这样可以保证证书可信呢?我们来仔细想一下。
9. 中间人有可能篡改该证书吗?
假设中间人篡改了证书的原文,由于他没有CA机构的私钥,所以无法得到此时加密后签名,无法相应地篡改签名。浏览器收到该证书后会发现原文和签名解密后的值不一致,则说明证书已被篡改,证书不可信,从而终止向服务器传输信息,防止信息泄露给中间人。
既然不可能篡改,那整个证书被掉包呢?
10. 中间人有可能把证书掉包吗?
假设有另一个网站B也拿到了CA机构认证的证书,它想劫持网站A的信息。于是它成为中间人拦截到了A传给浏览器的证书,然后替换成自己的证书,传给浏览器,之后浏览器就会错误地拿到B的证书里的公钥了,这确实会导致上文“中间人攻击”那里提到的漏洞?
其实这并不会发生,因为证书里包含了网站A的信息,包括域名,浏览器把证书里的域名与自己请求的域名比对一下就知道有没有被掉包了。
10. 为什么制作数字签名时需要hash一次?
我初识HTTPS的时候就有这个疑问,因为似乎那里的hash有点多余,把hash过程去掉也能保证证书没有被篡改。
最显然的是性能问题,前面我们已经说了非对称加密效率较差,证书信息一般较长,比较耗时。而hash后得到的是固定长度的信息(比如用md5算法hash后可以得到固定的128位的值),这样加解密就快很多。
当然也有安全上的原因,这部分内容相对深一些,感兴趣的可以看这篇解答:crypto.stackexchange.com/a/12780
11. 怎么证明CA机构的公钥是可信的?
上文中说到CA机构的公钥,我几乎一笔带过,“浏览器保有它的公钥”,这是个什么保有法?怎么证明这个公钥是否可信?
让我们回想一下数字证书到底是干啥的?没错,为了证明某公钥是可信的,即“该公钥是否对应该网站”,那CA机构的公钥是否也可以用数字证书来证明?没错,操作系统、浏览器本身会预装一些它们信任的根证书,如果其中会有CA机构的根证书,这样就可以拿到它对应的可信公钥了。
实际上证书之间的认证也可以不止一层,可以A信任B,B信任C,以此类推,我们把它叫做信任链
或
。也就是一连串的数字证书,由根证书为起点,透过层层信任,使终端实体证书的持有者可以获得转授的信任,以证明身份。数字证书链
另外,不知你们是否遇到过网站访问不了、提示需安装证书的情况?这里安装的就是根证书。说明浏览器不认给这个网站颁发证书的机构,那么你就得手动下载安装该机构的根证书(风险自己承担XD)。安装后,你就有了它的公钥,就可以用它验证服务器发来的证书是否可信了。
12. 每次进行HTTPS请求时都必须在SSL/TLS层进行握手传输密钥吗?
这也是我当时的困惑之一,显然每次请求都经历一次密钥传输过程非常耗时,那怎么达到只传输一次呢?
服务器会为每个浏览器(或客户端软件)维护一个session ID,在TLS握手阶段传给浏览器,浏览器生成好密钥传给服务器后,服务器会把该密钥存到相应的session ID下,之后浏览器每次请求都会携带session ID,服务器会根据session ID找到相应的密钥并进行解密加密操作,这样就不必要每次重新制作、传输密钥了!
至此,我们已自上而下地打通了HTTPS加密的整体脉络以及核心知识点,不知你是否真正搞懂了HTTPS呢?由于篇幅和能力所限,一些更深入的内容没有覆盖到。但我认为一般对于前后端开发人员来说,了解到这步就够了。
参考知乎文章https://zhuanlan.zhihu.com/p/43789231