HTTP 与 HTTPS 核心知识手册

45 阅读13分钟

HTTP 与 HTTPS 核心知识手册(含身份验证方案对比)

一、HTTP 与 HTTPS 基础认知

1.1 核心区别

特性HTTP (超文本传输协议)HTTPS (HTTP Secure)
传输方式明文传输,数据无加密基于 TLS/SSL 协议加密传输
端口默认 80 端口默认 443 端口
安全性低,易被拦截、篡改、伪造高,可防窃听、防篡改、防中间人攻击
证书需求无需证书需由权威 CA 机构签发的 SSL 证书

1.2 为什么需要从 HTTP 升级到 HTTPS?

  • 数据安全需求:用户登录信息、支付数据等敏感信息需加密保护,避免泄露。

  • 浏览器与搜索引擎要求:Chrome、Firefox 等浏览器会标记 HTTP 网站为 “不安全”,搜索引擎(如 Google)会降低 HTTP 网站排名。

  • 合规要求:金融、电商等领域需符合《网络安全法》《个人信息保护法》等法规,HTTPS 是基础安全措施。

二、身份验证方案深度解析:Basic 与 Bearer 对比

2.1 两种方案的核心原理

2.1.1 HTTP Basic 验证
  • 定义:HTTP 协议内置的简单身份验证机制,通过将 “用户名:密码”Base64 编码后传输实现身份校验。

  • 传输格式

    Authorization: Basic dXNlcjE6cGFzc3dvcmQxMjM= # 解码后为 "user1:password123"

  • 验证流程

  1. 客户端首次请求需验证的资源时,服务端返回 401 Unauthorized 响应,并附带 WWW-Authenticate: Basic realm="需要登录的资源域" 头。

  2. 客户端将 “用户名:密码”Base64 编码后,在后续请求头中携带 `Authorization: Basic

  3. 服务端解码编码串,验证用户名密码是否匹配,匹配则返回资源,不匹配则继续返回 401。

2.1.2 Bearer 验证(Token 验证)
  • 定义:基于 “令牌(Token)” 的身份验证机制,客户端通过获取短期有效的 Token,在请求中携带 Token 证明身份(常见 Token 类型如 JWT、OAuth 2.0 令牌)。

  • 传输格式

    Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEsIm5hbWUiOiJ1c2VyMSIsImV4cCI6MTY4NzAwMDAwMH0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

  • 验证流程

  1. 客户端通过 “登录接口”(如输入用户名密码、扫码等)向服务端申请 Token,服务端验证身份后生成短期有效的 Token 并返回。

  2. 客户端在后续请求需验证的资源时,在请求头中携带 Authorization: Bearer 3. 服务端验证 Token 的有效性(如是否过期、签名是否正确、权限是否匹配),有效则返回资源,无效则返回 401 Unauthorized403 Forbidden`。

2.2 Basic 与 Bearer 方案核心对比

对比维度HTTP Basic 验证Bearer 验证(Token 验证)
凭据本质直接传输 “用户名:密码”(Base64 编码)传输短期有效的 Token(无原始账号密码)
安全性低:编码可逆,凭据长期有效,泄露即风险高:Token 可设置短期有效期,泄露影响范围小;部分 Token(如 JWT)可加密签名防篡改
凭据有效期长期有效(除非用户修改密码)短期有效(通常几分钟到几小时,需定期刷新)
权限精细化弱:仅能验证 “是否为合法用户”,无法区分权限强:可在 Token 中嵌入权限信息(如角色、资源访问范围),支持精细化权限控制
性能开销低:仅需 Base64 编码 / 解码,无需额外存储中:服务端需验证 Token 签名 / 查询有效性(若用 Redis 存储黑名单则需额外开销)
适用场景简单内部系统、测试环境、低安全需求场景(如个人博客后台)生产环境、高安全需求场景(如电商支付、用户中心、开放 API)
依赖 HTTPS必须搭配 HTTPS(否则凭据易被拦截解码)建议搭配 HTTPS(防止 Token 被拦截盗用)

2.3 关键注意事项

2.3.1 Basic 验证的安全强化建议
  • 强制搭配 HTTPS:这是底线,避免 Base64 编码的凭据被明文拦截。

  • 添加 “凭据过期机制”:通过服务端配置,强制客户端定期重新提交用户名密码(如每 24 小时),减少长期泄露风险。

  • 仅限内部低风险场景:不建议在面向外部用户的生产系统(如电商、金融)中使用。

2.3.2 Bearer 验证的安全强化建议
  • Token 有效期控制:短期有效(如 1 小时内),同时提供 “Token 刷新机制”(用旧 Token 申请新 Token,避免频繁登录)。

  • Token 存储安全

  • 前端:避免存储在 localStorage(易受 XSS 攻击窃取),优先存储在 HttpOnly Cookie(防 XSS)或内存中(页面刷新后需重新获取)。

  • 服务端:若需吊销 Token(如用户登出、账号异常),需维护 “Token 黑名单”(如用 Redis 存储已吊销的 Token,有效期与 Token 一致)。

  • Token 防篡改:使用带签名的 Token 类型(如 JWT),服务端通过密钥验证签名,确保 Token 未被篡改;敏感场景可对 Token 内容加密(如 JWE 格式)。

三、HTTP Basic 验证的安全问题与解决方案(补充)

3.1 HTTP Basic 验证的原理与缺陷

3.1.1 核心缺陷:编码≠加密
  • Base64 本质:是 “二进制转文本” 的编码方式,设计目的是解决二进制数据的文本传输问题,无任何加密能力

  • 可逆性:任何拿到编码串的人,可通过在线工具、代码(如 Python 的 base64.b64decode())瞬间解码出原始账号密码。

  • 链路风险:HTTP 明文传输时,编码串会被抓包工具(如 Wireshark)直接拦截,导致凭据泄露。

3.2 解决方案:Basic 验证 + HTTPS/TLS

HTTPS 通过 TLS 协议对整个 HTTP 通信链路加密,弥补 Basic 验证的缺陷:

  • 加密传输:TLS 会对包含 Base64 编码串的 HTTP 报文加密,即使被拦截,攻击者也只能看到密文,无法解析原始数据。

  • 身份认证:TLS 通过数字证书验证服务端身份,防止中间人伪装服务端窃取凭据。

四、HTTPS 的核心安全机制:TLS 协议与证书验证

4.1 TLS 协议工作流程(以 TLS 1.2 为例)

  1. TLS 握手阶段(核心是协商安全参数):
  • 客户端发送 “支持的加密套件列表”“随机数 1”,请求建立连接。

  • 服务端返回 “选定的加密套件”“随机数 2”“服务器证书”。

  • 客户端验证证书合法性(见 4.2),生成 “预主密钥”,用服务端公钥加密后发送给服务端。

  • 客户端、服务端分别用 “随机数 1 + 随机数 2 + 预主密钥” 生成会话密钥(对称加密密钥)。

  • 双方发送 “握手完成” 消息,后续通信用会话密钥加密。

  1. 数据传输阶段
  • 客户端用会话密钥加密 HTTP 请求,服务端解密后处理;服务端用会话密钥加密响应,客户端解密后渲染。

4.2 客户端如何验证数字证书合法性?

4.2.1 核心前提:信任锚(内置根证书)

操作系统(Windows/macOS/Linux)和浏览器(Chrome/Edge/Firefox)会预装权威 CA 机构(如 DigiCert、Let’s Encrypt)的根证书,这些根证书是客户端的 “信任基础”。

4.2.2 验证三步骤
  1. 数字签名校验
  • 证书包含 “签发机构私钥签名”,客户端用签发机构的公钥(从中间证书 / 根证书获取)解密签名。

  • 若解密结果与证书核心信息(公钥、域名、有效期)一致,说明证书未被篡改,且确由该机构签发。

  1. 证书属性校验
  • 域名匹配:证书绑定的域名需与访问域名完全一致(如访问 www.abc.com,证书不能是 www.def.com)。

  • 有效期:证书需在 “生效时间 - 过期时间” 范围内,过期证书无效。

  • 吊销状态:通过 CRL(证书吊销列表)或 OCSP(在线证书状态协议)查询证书是否被吊销(如私钥泄露时会提前吊销)。

  1. 证书链追溯
  • 证书通常按 “根证书→中间证书→服务器证书” 形成链条,客户端需追溯到内置的信任根证书。

  • 若链条断裂(如缺少中间证书)或无法匹配信任锚,浏览器会弹出 “连接不安全” 警告。

4.3 HTTPS 性能优化:避免重复握手

频繁请求(如轮询任务进度)时,HTTPS 通过以下机制减少性能消耗:

  1. 会话复用
  • 会话 ID:第一次握手后,服务端生成 会话ID,客户端缓存;后续请求携带该 ID,直接复用会话密钥,仅需 1 个网络往返。

  • 会话票据:服务端将会话信息加密成票据,客户端缓存;集群部署时,任何服务器均可解密票据复用会话。

  1. TLS 1.3 0-RTT 握手
  • 客户端首次握手后缓存服务端公钥,后续请求可直接发送加密的应用数据,无需等待握手完成,实现 “零往返时间”。

五、HTTP 网站升级 HTTPS 实操步骤

5.1 步骤 1:选择并获取 SSL 证书

5.1.1 证书类型选择(按验证级别)
证书类型验证内容适用场景价格
DV SSL仅验证域名所有权个人博客、小型展示站免费(如 Let’s Encrypt)/ 低价
OV SSL验证域名 + 企业组织信息企业官网、中小型电商中价
EV SSL严格验证企业资质(需面签)金融平台、大型电商、支付网站高价
5.1.2 获取证书流程
  1. 生成 CSR 文件(证书签名请求):在服务器执行命令(以 Nginx 为例):

    openssl req -new -newkey rsa:2048 -nodes -keyout yourdomain.key -out yourdomain.csr

  2. 将 CSR 文件提交给 CA 机构,完成验证(DV 证书验证域名所有权,如解析指定 DNS 记录;OV/EV 需提交企业资质)。

  3. CA 验证通过后,下载证书文件(通常包含 .crt 证书文件、.key 私钥文件、中间证书 .ca-bundle)。

5.2 步骤 2:配置 Web 服务器(主流服务器示例)

5.2.1 Nginx 配置
  1. 上传证书文件到服务器(如 /etc/nginx/ssl/ 目录)。

  2. 修改 Nginx 配置文件(如 /etc/nginx/nginx.conf):

    # HTTP请求重定向到HTTPS

    server {

    listen 80;

    server_name yourdomain.com www.yourdomain.com;

    return 301 https://$server_name$request_uri; # 301永久重定向

    }

    # HTTPS配置

    server {

    listen 443 ssl;

    server_name yourdomain.com www.yourdomain.com;

    # 证书路径

    ssl_certificate /etc/nginx/ssl/yourdomain.crt;

    ssl_certificate_key /etc/nginx/ssl/yourdomain.key;

    ssl_trusted_certificate /etc/nginx/ssl/yourdomain.ca-bundle; # 中间证书

    # TLS优化配置

    ssl_protocols TLSv1.2 TLSv1.3; # 禁用旧协议(如SSLv3、TLSv1.0)

    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384; # 优先强加密套件

    ssl_session_cache shared:SSL:10m; # 会话缓存,有效期10分钟

    ssl_session_timeout 10m; # 会话超时时间

    # 启用HSTS(强制HTTPS访问)

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # 网站根目录与默认页面

    root /usr/share/nginx/html;

    index index.html index.htm;

    }

  3. 检查配置并重启 Nginx:

    nginx -t # 检查配置语法

    nginx -s reload # 重启服务

5.2.2 Apache 配置
  1. 启用 SSL 模块:

    a2enmod ssl # Ubuntu/Debian

    # 或 httpd -M | grep ssl 检查,未启用则修改httpd.conf加载mod_ssl.so

  2. 修改配置文件(如 /etc/apache2/sites-available/000-default-le-ssl.conf):

    Host *:443>

    ServerName yourdomain.com

    ServerAlias www.yourdomain.com

    DocumentRoot /var/www/html

    # 证书路径

    SSLEngine on

    SSLCertificateFile /etc/apache2/ssl/yourdomain.crt

    SSLCertificateKeyFile /etc/apache2/ssl/yourdomain.key

    SSLCertificateChainFile /etc/apache2/ssl/yourdomain.ca-bundle

    # HSTS配置

    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

    # HTTP重定向HTTPS

    *:80>

    ServerName yourdomain.com

    ServerAlias www.yourdomain.com

    Redirect permanent / yourdomain.com/

    Host>

  3. 重启 Apache:

    systemctl restart apache2 # Ubuntu/Debian

    # 或 systemctl restart httpd # CentOS/RHEL

5.3 步骤 3:网站内容与测试优化

  1. 修复混合内容问题
  • 确保网站内所有资源(图片、CSS、JS、接口)的链接从 http:// 改为 https://,或使用相对路径(如 //static.yourdomain.com/img/logo.png)。

  • 可通过浏览器 “开发者工具→Console” 查看混合内容错误,逐一修复。

  1. 更新关联配置
  • 网站地图(sitemap.xml):将所有 URL 改为 HTTPS。

  • 第三方工具(如 Google Analytics、百度统计):更新网站地址为 HTTPS。

  • 域名解析:若使用 CDN,需配置 CDN 支持 HTTPS(上传证书到 CDN 控制台)。

  1. 验证 HTTPS 配置
  • 使用在线工具检测:SSL Labs(检测证书有效性、协议支持、安全等级)、浏览器开发者工具→Security(查看连接安全状态)。

  • 测试核心功能:登录、支付、数据提交等,确保无功能异常。

六、补充实用知识(实际应用高频需求)

6.1 HSTS:强制 HTTPS 访问

  • 作用:告知浏览器 “未来 1 年内,该域名所有请求必须用 HTTPS”,即使用户手动输入 http://,浏览器也会自动跳转。

  • 配置注意

  • max-age=31536000:有效期 1 年(单位:秒)。

  • includeSubDomains:子域名也强制 HTTPS(如 blog.yourdomain.com)。

  • 配置后无法轻易回退(需等 max-age 过期),确保 HTTPS 稳定后再启用。

6.2 证书续期(以 Let’s Encrypt 为例)

Let’s Encrypt 证书有效期为 90 天,需定期续期,推荐自动化续期:

\# 安装Certbot工具

apt install certbot python3-certbot-nginx  # Ubuntu/Debian

\# 自动续期并重启Nginx

certbot renew --nginx --quiet

\# 添加定时任务(每天检查,过期则续期)

echo "0 0 \* \* \* certbot renew --nginx --quiet" >> /var/spool/cron/crontabs/root

6.3 常见问题排查

问题现象可能原因解决方案
浏览器提示 “证书无效”证书过期、域名不匹配、缺少中间证书续期证书、检查证书绑定域名、补充中间证书
部分资源加载失败混合内容(HTTP 资源)批量替换资源链接为 HTTPS
TLS 握手失败服务器禁用 TLS 1.2+/ 加密套件不兼容配置文件中启用 TLS 1.2+,更新加密套件列表
续期后证书未生效未重启 Web 服务器 / CDN 缓存未刷新重启服务器,清除 CDN 缓存

6.4 Bearer 验证实操:JWT Token 生成与验证示例(Python)

6.4.1 生成 JWT Token(服务端)
import jwt

import time

from datetime import datetime, timedelta

\# 配置参数

SECRET\_KEY = "your-strong-secret-key-keep-it-safe"  # 密钥,需保管在环境变量或配置中心

ALGORITHM = "HS256"  # 签名算法

ACCESS\_TOKEN\_EXPIRE\_MINUTES = 30  # Token 有效期30分钟

def create\_access\_token(user\_id: int, username: str):

    # 设置过期时间

    expire = datetime.utcnow() + timedelta(minutes=ACCESS\_TOKEN\_EXPIRE\_MINUTES)

    # Token 载荷(Payload):包含用户标识和过期时间,避免敏感信息

    to\_encode = {"sub": user\_id, "name": username, "exp": expire}

    # 生成 Token

    encoded\_jwt = jwt.encode(to\_encode, SECRET\_KEY, algorithm=ALGORITHM)

    return encoded\_jwt

\# 示例:生成用户ID=1、用户名为"user1"的Token

token = create\_access\_token(user\_id=1, username="user1")

print("生成的Token:", token)
6.4.2 验证 JWT Token(服务端)
def verify\_access\_token(token: str):

    try:

        # 解码并验证Token

        payload = jwt.decode(token, SECRET\_KEY, algorithms=\[ALGORITHM])

        # 提取用户标识

        user\_id: int = payload.get("sub")

        username: str = payload.get("name")

        if user\_id is None or username is None:

            raise ValueError("Token 中缺少用户信息")

        return {"user\_id": user\_id, "username": username}

    except jwt.ExpiredSignatureError:

        # Token 过期

        raise ValueError("Token 已过期")

    except jwt.InvalidTokenError:

        # Token 无效(如签名错误、格式错误)

        raise ValueError("无效的 Token")

\# 示例:验证Token

try:

    user\_info = verify\_access\_token(token)

    print("验证通过,用户信息:", user\_info)

except ValueError as e:

    print("验证失败:", str(e))

其他

参考资料 HTTP | MDN