返回首页

什么是 HTTP?HTTP 和 HTTPS 的区别

问题解析(面试官考察点)

面试官通过此问题主要考察:

  • 对 HTTP 协议基本概念的理解
  • 了解 HTTP 的特点和局限性
  • 理解 HTTPS 的工作原理和优势
  • 能够清晰对比 HTTP 和 HTTPS 的区别
  • 了解 SSL/TLS 在 HTTPS 中的作用

核心概念(基础知识点)

什么是 HTTP

HTTP(HyperText Transfer Protocol,超文本传输协议)是互联网上应用最广泛的一种网络协议,用于从 Web 服务器传输超文本到本地浏览器。

HTTP 的主要特点:

特点 说明
简单快速 客户端向服务器请求服务时,只需传送请求方法和路径
灵活 允许传输任意类型的数据对象,通过 Content-Type 标记
无连接 限制每次连接只处理一个请求,响应后立即断开
无状态 协议对事务处理没有记忆能力,每次请求都是独立的

什么是 HTTPS

HTTPS(HyperText Transfer Protocol Secure)是 HTTP 的安全版本,在 HTTP 下加入 SSL/TLS 层,通过加密传输、身份认证保证数据传输的安全性。

HTTPS = HTTP + SSL/TLS

HTTP 与 HTTPS 的核心区别

对比项 HTTP HTTPS
安全性 明文传输,不安全 加密传输,安全性高
连接方式 直接建立 TCP 连接 先建立 SSL/TLS 连接,再建立 HTTP 连接
默认端口 80 443
证书 不需要 需要 SSL 证书
性能 较快 相对较慢(加密解密开销)
成本 需要购买证书(有免费证书)

详细解答(代码示例)

HTTP 请求示例

// HTTP 请求(明文传输)
GET /api/users HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
Accept: application/json

// 响应
HTTP/1.1 200 OK
Content-Type: application/json

{"id": 1, "name": "张三", "password": "123456"}

问题: 数据以明文传输,容易被窃听和篡改。

HTTPS 请求流程

客户端                                    服务器
  |                                         |
  |-------- 1. Client Hello -------------->|
  |  (支持的加密算法、随机数)                 |
  |                                         |
  |<------- 2. Server Hello ---------------|
  |  (选定加密算法、服务器证书、随机数)        |
  |                                         |
  |-------- 3. 验证证书 ------------------->|
  |  (检查证书合法性、提取公钥)               |
  |                                         |
  |-------- 4. 生成并发送预主密钥 ----------->|
  |  (用公钥加密预主密钥)                    |
  |                                         |
  |<------- 5. 确认建立安全连接 -------------|
  |                                         |
  |======== 6. 加密数据传输 ===============>|
  |  (使用会话密钥对称加密)                   |

SSL/TLS 握手代码示意

// Node.js HTTPS 服务器配置示例
const https = require('https');
const fs = require('fs');

const options = {
  // 服务器证书
  cert: fs.readFileSync('server.crt'),
  // 服务器私钥
  key: fs.readFileSync('server.key'),
  // 可选:客户端证书验证
  requestCert: false,
  rejectUnauthorized: false
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('Hello Secure World!');
}).listen(443);

浏览器中检查 HTTPS 连接

// 检查当前页面是否使用 HTTPS
if (window.location.protocol === 'https:') {
  console.log('当前使用安全连接');

  // 获取证书信息(有限)
  console.log('主机名:', window.location.hostname);
  console.log('端口:', window.location.port || 443);
}

// 强制跳转到 HTTPS
if (location.protocol !== 'https:') {
  location.replace(`https:${location.href.substring(location.protocol.length)}`);
}

深入理解(原理剖析)

SSL/TLS 工作原理

SSL(Secure Sockets Layer)和 TLS(Transport Layer Security)是用于加密网络通信的协议。

TLS 握手过程详解:

  1. Client Hello

    • 客户端发送支持的 TLS 版本
    • 支持的加密算法列表(Cipher Suites)
    • 客户端随机数(Client Random)
  2. Server Hello

    • 服务器选择 TLS 版本和加密算法
    • 发送服务器证书(包含公钥)
    • 发送服务器随机数(Server Random)
  3. 证书验证

    • 客户端验证证书链
    • 检查证书有效期
    • 验证域名匹配
    • 确认证书由可信 CA 签发
  4. 密钥交换

    • 客户端生成预主密钥(Pre-Master Secret)
    • 使用服务器公钥加密后发送
    • 双方通过 Client Random + Server Random + Pre-Master Secret 生成会话密钥
  5. 加密通信

    • 后续通信使用会话密钥对称加密
    • 使用 MAC(消息认证码)保证完整性

加密算法类型

┌─────────────────────────────────────────────────────────┐
│                    TLS 加密体系                          │
├─────────────────────────────────────────────────────────┤
│  非对称加密(握手阶段)                                    │
│  ├── RSA:传统密钥交换方式                                │
│  ├── ECDHE:椭圆曲线 Diffie-Hellman(支持前向保密)        │
│  └── 用途:身份认证、密钥交换                              │
├─────────────────────────────────────────────────────────┤
│  对称加密(数据传输阶段)                                  │
│  ├── AES:高级加密标准                                   │
│  ├── ChaCha20:流加密算法                                │
│  └── 用途:实际数据传输加密                                │
├─────────────────────────────────────────────────────────┤
│  哈希算法(完整性验证)                                    │
│  ├── SHA-256:安全哈希算法                               │
│  └── 用途:消息认证、证书签名                              │
└─────────────────────────────────────────────────────────┘

前向保密(Forward Secrecy)

传统 RSA 密钥交换的问题:
- 如果服务器私钥泄露,所有历史通信都可以被解密

ECDHE 实现前向保密:
- 每次握手生成临时密钥对
- 即使私钥泄露,也无法解密之前的会话
- 因为预主密钥不会被长期存储

最佳实践

1. 全站 HTTPS 配置

# Nginx 强制 HTTPS 配置
server {
    listen 80;
    server_name example.com;
    # 重定向到 HTTPS
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    # 启用 HSTS
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    # 安全配置
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
    ssl_prefer_server_ciphers off;
}

2. 混合内容处理

<!-- 错误:HTTPS 页面加载 HTTP 资源会被阻止 -->
<img src="http://example.com/image.jpg">
<script src="http://example.com/script.js"></script>

<!-- 正确:使用 HTTPS 或协议相对 URL -->
<img src="https://example.com/image.jpg">
<script src="//example.com/script.js"></script>

3. 安全头部配置

// Express.js 安全头部配置
const helmet = require('helmet');

app.use(helmet({
  hsts: {
    maxAge: 31536000,
    includeSubDomains: true,
    preload: true
  },
  contentSecurityPolicy: {
    directives: {
      defaultSrc: ["'self'"],
      upgradeInsecureRequests: []
    }
  }
}));

4. 证书管理

# 使用 Let's Encrypt 免费证书
# 安装 certbot
certbot --nginx -d example.com -d www.example.com

# 自动续期
certbot renew --dry-run

面试要点

  1. HTTP 的无状态性

    • 每次请求独立,服务器不保存客户端状态
    • 通过 Cookie/Session/Token 维持状态
  2. HTTPS 的性能影响

    • 握手阶段增加 1-2 个 RTT
    • 加密解密消耗 CPU 资源
    • HTTP/2 多路复用可以弥补部分性能损失
    • 现代硬件加密开销已很小
  3. 证书体系

    • 根证书(Root CA)-> 中间证书 -> 服务器证书
    • 证书链验证过程
    • 自签名证书 vs CA 签发证书
  4. 常见攻击防护

    • 中间人攻击(MITM):证书验证防止
    • 重放攻击:使用随机数和序列号
    • 降级攻击:TLS 版本检查
  5. 面试高频问题

    • 为什么 HTTPS 不是绝对安全?(客户端被劫持、证书伪造等)
    • TLS 1.3 相比 1.2 的改进?(减少握手轮次、移除不安全算法)
    • 什么是证书透明度(CT)?(防止恶意证书签发)