尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

HTTP和HTTPS到底有啥区别?咱们掰开揉碎来讲讲

HTTP和HTTPS到底有啥区别?咱们掰开揉碎来讲讲 HTTP 和 HTTPS 就差一个 S凭啥一个被浏览器骂不安全不知道朋友们有没有过这种经历自己辛辛苦苦本地起了个服务浏览器地址栏敲http://localhost:8080是岁月静好可一旦部署到服务器上用域名http://一访问浏览器立马给你甩脸子——要么是个大大的不安全要么直接警告你与此网站之间建立的连接并非私密连接。咱当时就懵了HTTP 和 HTTPS 不就差一个字母 S 吗咋差距跟我跟马云都姓马一样离谱捏更离谱的是去面试的时候面试官一句说说 HTTPS 的加密过程能把一堆人问得哑口无言。咱明明每天都在用 HTTPS却说不清楚它到底把 HTTP 怎么了 (꒦ິ⌓꒦ີ)所以这篇就来把这个事掰开揉碎了讲清楚——它不背八股咱就聊明白 HTTP 有啥毛病、HTTPS 是怎么一个一个把毛病治好的。看完之后面试再被问到你也能跟面试官唠上两句。一、HTTP 到底是个啥先用大白话说HTTP超文本传输协议就是浏览器和服务器之间聊天用的一套规矩。你打开一个网页本质上是这么个流程浏览器客户端跟服务器说“我要/index.html这个文件”服务器把文件内容回给你浏览器拿到 HTML再按里面的内容去要 CSS、JS、图片……就这么一来一回靠的就是 HTTP。它规定了请求长什么样、“响应长什么样”、用哪个方法GET/POST 啥的这些格式问题。那你有没有想过一个问题浏览器和服务器之间的这些聊天记录是怎么传到对方那儿的答案是通过一大堆网络设备你的路由器 → 运营商 → 各种骨干网节点 → 目标服务器所在的机房……中间要经过多少个节点谁也说不准。关键来了HTTP 传输的东西是明文的。啥叫明文就是原原本本、不加任何遮挡地传。这就好比你去寄快递但是没装箱、没封口里面的东西一路裸奔到收件人手里中途任何一个经手的人都能直接看到、甚至顺手改一改。平时传个今天天气不错那当然无所谓可你要是传的是账号密码、身份证号、银行卡号、支付验证码呢想想就后背发凉 (•́︿•̀)二、HTTP 的三大原罪咱把 HTTP 的问题总结成三条江湖人称三大原罪罪一窃听别人能看见因为明文传输数据经过的任何一台中间设备比如公共 WiFi 的路由器都能把你的聊天内容看个精光。你在星巴克连个免费 WiFi随手填个登录密码旁边坐着的大哥可能就把你密码抄走了。罪二篡改别人能改更狠的是中间人不仅能看到还能改了再转给对方。比如你请求一个网页中间人偷偷在返回的 HTML 里塞了一段广告代码、或者把页面里的转账给张三改成转账给李四你这边完全不知情。罪三冒充别人能装还有一招叫冒充中间人直接假装自己就是目标服务器跟你建立连接。你以为你在跟银行聊其实全程是在跟骗子聊。![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/im一句话总结 HTTP 的痛点它只管把话传到不管话有没有被偷看、被改、对方是不是本人。传输的安全性它一概不管。那咋办捏于是 HTTPS 就登场了。三、HTTPS 是怎么治病的先给结论HTTPS HTTP TLS。也就是说HTTPS 没有推翻 HTTP 重来而是在 HTTP 和底层的 TCP 之间夹了一层叫 TLS 的安全层。你的 HTTP 报文先交给 TLS 加密加密之后再发出去对面收到后先解密再交给 HTTP 处理。可以这么理解HTTP 是信的内容TLS 就是那个信封 火漆印章 只有收件人能开的锁。内容还是那个内容但一路都裹得严严实实。顺带提一嘴TLS 的前身叫 SSL现在大家嘴上说的 SSL 证书、SSL 握手其实严格来讲都该叫 TLS。就像现在还有人管所有智能手机叫苹果习惯问题但咱心里得门儿清。那 TLS 这层包装具体解决了啥对付窃听→ 把内容加密中间人看到的是乱码对付篡改→ 给内容加上完整性校验被改过就能发现对付冒充→ 用数字证书证明我真的是这个网站下面咱一个一个拆开看。四、先整明白加密对称和非对称要讲 TLS就绕不开两种加密方式。别慌咱用大白话打比方。对称加密一把钥匙开一把锁对称加密就是加密和解密用的是同一把钥匙。你拿钥匙 A 把箱子锁上对面拿同一把钥匙 A把箱子打开。简单粗暴、速度快适合加密大量数据。但问题来了这把钥匙怎么安全地交到对方手里你要是不加密地把钥匙发过去那中间人不就直接把钥匙抄走了那后面加不加密还有啥意义……这就是著名的**“密钥分发难题”**。非对称加密公钥锁门私钥开门非对称加密就巧妙多了它有一对钥匙一把叫公钥一把叫私钥。公钥可以满世界公开谁都能拿私钥只有服务器自己藏着绝不外传规则是用公钥加密的数据只有对应的私钥能解开反过来用私钥加密的公钥能解。这就像给全世界发了一堆只能锁不能开的挂锁公钥只有服务器手里握着唯一能开锁的钥匙私钥。任何人想给服务器发东西就用这把公开的挂锁锁上中途谁都没法开只有服务器能开。听起来完美对吧但非对称加密很慢开销比对称加密大得多。你拿它去加密整个网页、几张高清大图那性能直接原地爆炸。那咋整捏混合加密我全都要成年人不做选择——两种一起用。用非对称加密来安全地交换那把对称加密的钥匙然后用对称加密来传真正的数据。翻译成人话就是服务器先用自己的私钥保护一把对称钥匙的交换过程保证钥匙安全送到双方拿到同一把对称钥匙之后后面所有聊天内容都用这把钥匙加解密保证速度。这样既安全又快这就是 TLS 的实际做法。聪明吧嘿嘿。五、数字证书怎么确定对面真是本人加密的问题解决了可还有个要命的环节我凭什么相信对面给我的公钥真的是银行的公钥万一对面是骗子它把自己的公钥发给我那我加密的东西不就全被它解开了这就是前面说的冒充。于是**数字证书CA 证书**出场了。你可以把数字证书理解成网站的身份证而颁发它的机构叫CA证书颁发机构Certificate Authority相当于公安局。流程大致是网站向 CA 申请证书提交自己的公钥和域名信息CA 审核通过后用自己的私钥给网站的信息签个名生成证书浏览器访问网站时网站把这个证书发过来浏览器内置了各大 CA 的公钥拿 CA 的公钥一验签就能确认这证书确实是 CA 发的而且是给这个网站的没被伪造所以浏览器信任的不是网站本身而是**“给这个网站背书的 CA”**。全球那些知名 CADigiCert、Let’s Encrypt 等早就被所有浏览器内置信任了它们不可能为了你这一个网站砸自己招牌所以这套信任链是成立的。注意证书是有有效期的常见的坑就是证书过期了浏览器一样会报警告。这是很多线上事故的经典原因后面咱细说。六、TLS 握手一场精心设计的接头好把前面的零件拼起来就得到了完整的TLS 握手过程。你可以把它想象成一场地下党接头双方得先对暗号、验身份才能开始传文件。大致的步骤是客户端打招呼Client Hello浏览器说你好我支持这些加密算法、这个 TLS 版本这是我的随机数 A服务器回应Server Hello服务器说收到那咱用这套算法这是我的随机数 B并把证书一起发过来验证证书浏览器拿内置的 CA 公钥验证这证书靠不靠谱、域名对不对、过没过期生成会话密钥浏览器生成一个预主密钥用证书里的公钥加密发给服务器只有服务器的私钥能解开双方各自算出会话密钥浏览器和服务器拿随机数 A 随机数 B 预主密钥这三样各自算出一个一模一样的对称密钥这个密钥从来没在网络上明文传过中间人根本算不出来加密通信开始从此以后双方就用这把对称密钥加密数据聊得又快又安全注意这里精妙的地方对称密钥不是传过去的而是双方各自算出来的。中间人就算全程偷听手里没有服务器私钥也推不出这个密钥。这一步是 HTTPS 防窃听的核心。补充一下上面说的是 TLS 1.2 的经典流程握手要来回好几趟。TLS 1.3 把这套流程优化到了只需一趟往返1-RTT还砍掉了一堆不安全的旧算法速度更快。现在主流浏览器和服务器基本都在用 TLS 1.3 了。七、Java 里怎么用 HTTPS讲完原理咱回到老本行——Java 里访问一个 HTTPS 接口到底要不要干啥特殊操作答案是基本上不用。前面第一篇咱聊过的 JDK 原生的HttpClient你直接把地址写成https://就行握手、加解密这些脏活累活它全帮你办了importjava.net.http.HttpClient;importjava.net.http.HttpRequest;importjava.net.http.HttpResponse;importjava.net.URI;HttpClientclientHttpClient.newHttpClient();// 直接用 https剩下的交给 JDKHttpRequestrequestHttpRequest.newBuilder().uri(URI.create(https://api.github.com/users/octocat)).GET().build();HttpResponseStringresponseclient.send(request,HttpResponse.BodyHandlers.ofString());System.out.println(response.body());Spring 的RestTemplate、WebClient也是同理写https://就完事了因为 JDK 内置了一个叫做cacerts的信任库里面躺着全球各大 CA 的根证书验签全靠它。那啥时候会翻车捏当你访问的是自签名证书自己给自己签的证书的网站时。比如公司内网的一些服务、测试环境、咱自己用keytool签的证书这类证书没有 CA 背书浏览器和 Java 都会认为这证书来路不明直接拒绝连接。浏览器里你还能点个继续前往不安全强行闯过去但在 Java 代码里它会直接给你甩一个异常javax.net.ssl.SSLHandshakeException:PKIXpath building failed:sun.security.provider.certpath.SunCertPathBuilderException:unabletofindvalid certification pathtorequestedtarget这一长串看着吓人翻译过来其实是“这证书我没见过也没人给它背书我不敢跟它聊。”两个解决办法方案一把证书导入 JDK 的信任库推荐正规做法把这些自签名证书导入到 JDK 的cacerts信任库里之后 JDK 就认它了。用 JDK 自带的keytool工具# 1. 先从网站上把证书导出来浏览器点锁图标就能导出# 假设导出来叫 server.crt# 2. 导入到 JDK 的信任库keytool-import-trustcacerts-aliasmyserver\-fileserver.crt\-keystore$JAVA_HOME/lib/security/cacerts\-storepasschangeit注意cacerts默认密码就是changeit这是个大家都知道的公开密码生产环境记得改。另外你这么导是改的本机 JDK换个环境部署又得重新导一遍有点烦但最正规。方案二代码里信任所有证书方便但只能测试用有些朋友觉得导证书太麻烦就想在代码里一把梭——搞一个什么都信的TrustManager// ⚠️ 警告这么写会完全放弃证书校验等于裸奔生产环境千万别用TrustManager[]trustAllnewTrustManager[]{newX509TrustManager(){publicvoidcheckClientTrusted(X509Certificate[]c,Stringa){}// 不检查publicvoidcheckServerTrusted(X509Certificate[]c,Stringa){}// 不检查publicX509Certificate[]getAcceptedIssuers(){returnnewX509Certificate[0];}}};这么写 HTTPS 就白上了——中间人攻击、冒充全都防不住了纯粹是把 HTTPS 当成 HTTP 在用。所以这个法子只能在本地测试图个方便千万别带进生产代码。咱踩过这个坑当年图省事上线了后来被安全扫描揪出来一通批评 (ŏ_ŏ)八、几个咱踩过的坑除了证书实际开发里还有几个常见坑提前给你们排一排。坑一HTTP 页面里混着 HTTPS 资源 → 浏览器拦截浏览器现在有个规矩HTTPS 页面里不允许再加载 HTTP 的图片/脚本/接口这叫混合内容Mixed Content会被直接拦掉。表现就是页面明明开了 HTTPS但图片不显示、接口报错。排查思路打开浏览器 F12看看 Console 里是不是一堆Mixed Content的报错把那些 http:// 的资源全换成 https:// 就行。坑二证书过期前面说过证书有有效期一般 1 年Let’s Encrypt 的免费证书是 90 天。忘了续期网站直接访问不了用户看到的是一片红色的警告页。建议用 Let’s Encrypt 的话把自动续期配上certbot renew或者干脆用云厂商的免费证书 监控到期时间。这个坑坑过无数团队包括一些大厂。坑三老 JDK 不支持的 TLS 版本有些老项目还跑在 JDK 8 早期版本上遇到只支持 TLS 1.3 的服务器握手会失败。排查思路用curl -v https://your-server.com看看握手协商的 TLS 版本再对照 JDK 支持的版本。升级 JDK 或手动开启高版本 TLS 通常能解决。坑四HTTPS 就一定安全吗不是。HTTPS 保证的是传输过程的安全不保证网站本身是好人。一个钓鱼网站照样可以申请合法证书、挂上 HTTPS。所以看到那个小锁只能说明你和这个网站之间的传输是加密的不能说明这个网站可信。这个区别咱心里要有数。九、总结一下咱用一张表把 HTTP 和 HTTPS 的差别收个尾对比项HTTPHTTPS全称超文本传输协议HTTP TLS传输方式明文加密默认端口80443能否防窃听/篡改/冒充都不能都能需要证书吗不需要需要CA 签发速度略快少一次握手略慢多一层加解密但影响很小一句话概括这篇的核心HTTP 只管把话传到不管路上的安全HTTPS 在 HTTP 下面垫了一层 TLS通过非对称加密换对称密钥 数字证书验明正身把窃听、篡改、冒充这三大原罪挨个治好了。现在你再看浏览器地址栏那个小锁是不是感觉完全不一样了嘿嘿。给个实践建议现在做项目https://基本已经是默认选项了。Let’s Encrypt 的证书免费、能自动续期配合 Nginx 配一下也就十几分钟的事不折腾的话云厂商控制台点几下也能一键申请。没有任何理由让自己的网站还裸奔在 HTTP 上。以上是个人的一些经验分享原理部分已经尽量说人话嘞。如果有哪里有什么错误的地方也请大佬们不吝指出咱一起学习进步本文完结撒花ヾ(≧▽≦*)o
返回列表