一、HTTPS 核心机制:非对称加密 + 对称加密
HTTPS = HTTP over TLS/SSL,通过 混合加密体系 解决三大问题:
- 防窃听 - 对称加密传输内容(如 AES)
- 防篡改 - 数字签名验证数据完整性
- 防冒充 - 数字证书验证服务器身份
// 前端感知的典型场景:混合内容拦截
// 在 HTTPS 页面加载 HTTP 资源会被浏览器拦截
<img src="http://example.com/image.jpg">
// 控制台报错:Mixed Content: The page was loaded over HTTPS...
二、TLS 握手流程详解(三次握手后)
1. Client Hello
客户端发送:
- 支持的 TLS 版本(如 TLS 1.3)
- 客户端随机数(Client Random)
- 加密套件列表(如 ECDHE-RSA-AES128-GCM-SHA256)
# 开发者工具查看加密套件(Chrome)
chrome://flags/#tls13-variant
2. Server Hello
服务端回应:
- 选定的 TLS 版本和加密套件
- 服务器随机数(Server Random)
- 数字证书(包含公钥)
// 前端可通过 JS 获取证书信息(需要用户授权)
navigator.mediaDevices.getUserMedia({ video: true })
.then(() => {
const cert = document.querySelector('video').getCertificate();
console.log(cert.issuer); // 颁发机构
});
3. 证书验证
客户端验证证书:
- 证书链是否可信(CA 机构签发)
- 域名是否匹配
- 是否过期
// 开发环境常见错误:自签名证书报错
// 解决方案1:浏览器手动信任(危险)
// 解决方案2:配置本地CA(推荐使用 mkcert)
// 生成本地证书
$ mkcert -install
$ mkcert localhost 127.0.0.1 ::1
4. 密钥交换(以 ECDHE 为例)
- 服务端发送 Server Params(椭圆曲线公钥)
- 客户端生成 Client Params 并发送
- 双方通过 ECDHE 算法生成 Pre-Master Secret
# 简化版密钥计算逻辑(实际为二进制操作)
client_random = 0x1234
server_random = 0x5678
pre_master = ecdhe(client_params, server_params)
master_secret = PRF(pre_master, client_random + server_random)
5. 切换加密协议
双方用 Master Secret 生成对称密钥,后续通信使用对称加密。
三、前端开发重点场景
场景1:强制全站 HTTPS
nginx
# Nginx 配置自动跳转(301 永久重定向)
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
html
<!-- 前端兜底方案(慎用) -->
<script>
if (location.protocol !== 'https:') {
location.replace(`https://${location.host}${location.pathname}`);
}
</script>
场景2:安全 Cookie 传输
javascript
// 设置 Secure + HttpOnly + SameSite
document.cookie = `session=xxx; Secure; HttpOnly; SameSite=Lax`;
场景3:HSTS 预加载
nginx
# 添加 Strict-Transport-Security 头
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
提交预加载列表
四、性能优化实践
技巧1:Session Resumption
复用 TLS 会话减少握手耗时:
nginx
# Nginx 配置会话票证
ssl_session_tickets on;
ssl_session_timeout 1d;
技巧2:OCSP Stapling
由服务端缓存证书状态,减少客户端验证耗时:
nginx
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8;
技巧3:TLS 1.3 升级
比 TLS 1.2 减少一次 RTT:
nginx
ssl_protocols TLSv1.3 TLSv1.2;
五、常见坑点排查指南
问题1:证书链不完整
现象:Android 低版本报错,iOS 正常
解决:使用 openssl
补全证书链
bash
$ openssl s_client -showcerts -connect example.com:443
$ cat fullchain.pem > chained.crt # 合并根证书和中间证书
问题2:混合内容阻塞
定位:使用 CSP 报告收集非 HTTPS 请求
html
<meta http-equiv="Content-Security-Policy"
content="default-src https: 'unsafe-inline' 'unsafe-eval';
report-uri /csp-report">
问题3:CDN 证书配置错误
检测工具:
bash
$ curl -I https://example.com # 检查 Server 头
$ nscurl --ats-diagnostics https://example.com # iOS 特性检测
六、开发环境 HTTPS 最佳实践
方案1:Webpack DevServer 配置
javascript
// webpack.config.js
const fs = require('fs');
const https = require('https');
module.exports = {
devServer: {
https: {
key: fs.readFileSync('localhost-key.pem'),
cert: fs.readFileSync('localhost.pem')
},
public: 'https://localhost:8080' // 避免浏览器警告
}
};
方案2:Service Worker 调试
javascript
// sw.js 中捕获证书错误
self.addEventListener('fetch', event => {
if (event.request.url.startsWith('https://')) {
event.respondWith(
fetch(event.request).catch(err => {
console.error('证书错误:', err);
return new Response('HTTPS故障');
})
);
}
});
七、终极检测清单
- 所有子域名启用 HTTPS(包括 CDN)
- 配置 HSTS 头部并提交预加载
- 定期更新 TLS 证书(监控到期时间)
- 禁用不安全协议(SSLv3、TLS 1.0)
- 使用 Qualys SSL Labs 评分达到 A+
bash
# 一键检测(需安装 testssl.sh)
$ testssl.sh --color 0 example.com
通过理解 TLS 握手流程,前端开发者能更好地处理证书错误、优化资源加载策略,并推动全站安全升级。记住:HTTPS 不是终点,而是现代 Web 应用的起跑线。