草庐IT

HTTPS协议是如何防中间人窃听的

somenzz 2023-03-28 原文
​相信你看过 HTTPS 协议的定义,知道它是一个安全的通讯协议,可以防止中间人窃听,但是你也知道很多代理都可以对 HTTPS 协议抓包,那 HTTPS 协议是如何防中间人窃听的呢?还有,HTTPS 也可以双向验证,也就是服务器端可以验证客户端证书,这一点和防止中间人窃听有没有关系呢?本文就来回答这个问题,如果有不同意见,可以直接发消息与我交流。

HTTPS 协议的基本概念:HTTPS 协议是在 HTTP 协议的基础上,通过添加 SSL/TLS 加密协议而成的。SSL/TLS 协议是一种用于网络通信安全的加密协议,可以将数据在传输过程中进行加密,保证数据的机密性和完整性。

如何防止中间人窃听

要回答这个问题,我们先看看 HTTPS 协议双方,也就是客户端和服务器的通信过程。

  1. 客户端发送请求
当用户在浏览器中输入一个 HTTPS 网址时,浏览器会向服务器发送一个请求,请求建立一个HTTPS 连接。请求中包含有客户端支持的加密算法列表,当然也包括客户端自己的公钥。

  1. 服务器回应
服务器会回应客户端的请求,并从中选择一种加密算法。服务器会使用该算法生成一组密钥,并将该密钥用客户端的公钥加密,并将加密后的密钥及数字证书发送给客户端。

  1. 客户端验证证书
客户端收到服务器的回应后,会验证服务器的数字证书是否合法。数字证书是由数字证书认证机构(CA)颁发的,用于证明服务器的身份。客户端会根据自己的信任列表,验证数字证书的合法性。

验证数字证书的过程如下:

  • 客户端(浏览器或 APP)读取证书中的证书对应的域名、所有者、有效期等信息进行一一校验;
  • 客户端开始查找操作系统中已内置的受信任的证书发布机构 CA,与服务器发来的证书中的颁发者 CA 比对,用于校验证书是否为合法机构颁发;
  • 如果找不到,客户端就会报错,说明服务器发来的证书是不可信任的;
  • 如果找到,那么客户端就会从操作系统中取出 颁发者 CA 的公钥,然后对服务器发来的证书里面的签名进行解密;
  • 客户端使用相同的 hash 算法计算出服务器发来的证书的 hash 值,将这个计算的 hash 值与证书中签名做对比;
  • 对比结果一致,则证明服务器发来的证书合法,没有被冒充;
  • 此时客户端就可以读取证书中的公钥,用于后续加密了;
  1. 客户端生成密钥
如果数字证书验证通过,客户端会使用自己的私钥解密服务器发送过来的密钥。然后客户端会使用该密钥生成一对对称密钥,一份用于加密,一份用于解密。

  1. 客户端发送密钥
客户端使用服务器的公钥加密刚刚生成的对称密钥,并将加密后的密钥发送给服务器。

  1. 服务器解密密钥
服务器收到客户端发送的加密后的对称密钥后,会使用自己的私钥解密该密钥。

  1. 开始数据传输
经过以上的验证和加密,HTTPS 通信就建立了起来。此时,客户端和服务器之间的数据传输都是通过对称密钥进行加密的。为什么用对称密钥?因为对称加密的开销小,且其密钥采用非对称加密算法传输,通信过程非常安全。

理解了以上过程,你就会明白,防止中间人最重要最重要的过程是验证证书,只要证书是合法的,服务器就是合法的,不会是冒充的。证书是专业的机构 CA 颁发和管理,所以是可信的。

假如,客户端和服务器直接有一个中间人,比如你用了代理,那么这个代理就是中间人。中间人要想监听客户端和服务器,就需要获取客户端和服务器的通信用的密钥。服务器的密钥,中间人可以作为客户端的身份进行获取,但是要想获取客户端的密钥,中间人需要伪装服务器的身份,从而发布自己的证书,中间人的证书可以是自签名证书,也可以是向 CA 申请的证书,无论是哪个证书,对应的域名一定 不是服务器的域名,这样,客户端在验证证书时一定不会通过,我们就会收到浏览器的提醒:证书不被信任。

如果,客户端(你)选择信任并继续,那么你的通信将毫无安全可言。除非,这个代理(中间人)是你自己部署的,基于测试或抓包分析等其他原因,你可以信任并继续。

回想一下,很多代理之所以可以抓取 HTTPS 包,是因为我们提前导入并信任它们的 CA 证书,然后就可以通过替换证书的方式进行密钥交换,以 charles 为例,具体过程如下:

图片来源:https://ost.51cto.com/posts/19810

因此,HTTPS 协议是借助于证书防中间人窃听的,请注意,如果自己从没有做过什么代理设置,不要相信任何不受信任的证书,推而广之,IOS 不要相信任何描述文件,不要安装不明来源的 APP,不要赋予任何 APP 不需要的权限,这是保障自己信息安全的根本。

HTTPS 的双向验证

HTTPS 也可以双向验证,也就是服务器端可以验证客户端证书,那么什么场景需要这样?

之前的过程,只能说明服务器是合法的,如果服务器想让客户端也是合法的,那么就需要验证客户端的证书,因此,如果服务端需要限定的客户端才能访问服务,那么可以采取 HTTPS 的双向验证[1]。因此 即使 HTTPS 不开启双向验证,也可以防止中间人攻击。

HTTPS 的双向验证 nginx 的配置示范如下:

location / {
# 开启 HTTPS 协议
listen 443 ssl;
# 指定 SSL 证书文件和私钥文件
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# 开启证书校验
ssl_verify_client on;
# 指定 CA 证书文件
ssl_client_certificate /path/to/ca.pem;
# 指定校验方式为深度校验
ssl_verify_depth 2;
}

最后的话

HTTPS 协议通过使用 SSL/TLS 加密技术,通过证书检验,可以有效防止中间人窃听、篡改和伪造等安全问题。

最后,请注意,当浏览器或手机出现安全提醒时,一定不要添加信任并继续,因为,诈骗犯/黑客正在暗处等着你,除非你真的知道你在做什么。

有关HTTPS协议是如何防中间人窃听的的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  4. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  5. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  6. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  7. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  8. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  9. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  10. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

随机推荐