Linux 学习笔记(四十五):Web 安全基石——Cookie、Session 与 HTTPS 原理解析

📌 核心结论(TL;DR):

  1. HTTP 缺陷:无状态、明文传输。

  2. Cookie :数据存在客户端,服务器通过 Set-Cookie 响应头写入,浏览器后续请求自动带上。

  3. Session :数据存在服务器端。服务器只给客户端发一个 SessionID,保证私密数据不泄露。

  4. HTTPS :HTTP + 加密层(TLS/SSL)。采用非对称加密协商密钥,对称加密传输数据。

  5. CA 证书:解决"中间人攻击"的终极武器。浏览器内置 CA 公钥,用来验证服务器证书的真伪。

HTTP 协议是"无状态"的,每次请求都是独立的,服务器记不住你是谁。为了解决"保持登录状态"等问题,引入了 Cookie 和 Session。

1. Cookie(客户端存储)

  • 原理 :服务器在响应头中添加 Set-Cookie: username=zhangsan。浏览器保存后,下次请求自动携带。

  • 缺点:存在客户端,容易被篡改或窃取;如果直接存密码,极其危险。

2. Session(服务器端存储)

  • 原理 :服务器生成随机 SessionID(如 12345),保存在服务器内存中(记录用户信息)。响应给浏览器,让浏览器存进 Cookie。

  • 优点:真实数据在服务器,客户端只有一个 ID,安全性大幅提升。

cpp 复制代码
// 在响应头中加入 Set-Cookie
snprintf(response,  sizeof(response), 
    "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/html; charset=utf-8\r\n"
    "Set-Cookie: username=zhangsan; expires=Fri, 18 Dec 2026 12:00:00 UTC; path=/\r\n"
    "Content-Length: %ld\r\n"
    "\r\n"
    "%s", strlen(body), body);

踩坑:expires 的日期格式极其严格,必须是 UTC 或 GMT 格式,推荐使用 gmtime() 生成。

四、 HTTPS:不仅仅是加个 S

HTTP 是明文传输,运营商或黑客可以轻易进行中间人劫持。HTTPS 在 HTTP 和 TCP 之间加了一层加密协议(SSL/TLS)。

  1. 对称加密:加密解密用同一把钥匙,速度快,但钥匙容易泄露。

  2. 非对称加密:公钥加密,私钥解密。安全但极慢。

  3. HTTPS 方案 :非对称加密 + 对称加密 + CA证书。

    • 客户端请求服务器,服务器返回 CA 证书。

    • 客户端校验证书(防中间人),获取服务端真实公钥。

    • 客户端生成一个对称密钥,用服务端公钥加密发给服务端。

    • 服务端用私钥解密拿到对称密钥,后续双方全用对称加密通信。

五、 为什么中间人改不了 CA 证书?

证书里包含了网站的域名、公钥等明文信息,以及 CA 机构用自己的私钥加密的签名。黑客没有 CA 的私钥,无法伪造签名;如果强行篡改明文,浏览器验签时哈希值对不上,立刻报警。

自我实战操作

由于完整的 HTTP 框架加上 Session 管理代码量极大,咱们直接在刚才的【极简 HTTP 服务器】代码上做修改,看看如何在浏览器里写入 Cookie。

bash 复制代码
cd ~/linux_study/network_test
vim http_cookie_server.c

(基于上节课的代码,只改了构造响应报文那几行)

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>

#define PORT 8081
#define BUF_SIZE 4096

int main() {
    int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    int opt = 1;
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    struct sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    server_addr.sin_addr.s_addr = INADDR_ANY;

    bind(server_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
    listen(server_fd, 5);
    printf("HTTP Cookie 服务器启动,访问: http://127.0.0.1:%d\n", PORT);

    while (1) {
        struct sockaddr_in client_addr;
        socklen_t client_len = sizeof(client_addr);
        int client_fd = accept(server_fd, (struct sockaddr*)&client_addr, &client_len);

        char buffer[BUF_SIZE] = {0};
        int n = read(client_fd, buffer, sizeof(buffer) - 1);
        if (n > 0) {
            // 提取并打印浏览器发来的 Cookie
            char *cookie_ptr = strstr(buffer, "Cookie:");
            if (cookie_ptr) {
                // 优化点1:把后面的 \r\n 截断,避免终端打印一堆乱码
                char *end_ptr = strstr(cookie_ptr, "\r\n");
                if (end_ptr) *end_ptr = '\0'; 
                printf("【抓到 Cookie】 %s\n", cookie_ptr);
            }
        }

        // 构造响应报文
        const char *body = "<html><body><h1>Cookie Test Page</h1><p>刷新页面,看看终端是否抓到了Cookie</p></body></html>";
        char response[2048]; // 确保缓冲区足够大
        
        // 优化点2:使用 snprintf 防止溢出;修正了 2026-12-18 对应的星期是 Fri (周五)
        snprintf(response, sizeof(response), 
                "HTTP/1.1 200 OK\r\n"
                "Content-Type: text/html; charset=utf-8\r\n"
                "Set-Cookie: username=zhangsan; expires=Fri, 18 Dec 2026 12:00:00 UTC; path=/\r\n"
                "Content-Length: %ld\r\n"
                "Connection: close\r\n"
                "\r\n"
                "%s", strlen(body), body);

        write(client_fd, response, strlen(response));
        close(client_fd); 
    }
    return 0;
}
测试与排坑
bash 复制代码
gcc http_cookie_server.c -o http_cookie_server
./http_cookie_server

操作步骤:

  1. 在浏览器访问 http://127.0.0.1:8081。

  2. 按下 F12 打开开发者工具,找到 "应用(Application)" -> "Cookie" 。你会看到里面已经存了 username=zhangsan。

  3. 刷新页面 。回到 Linux 终端,你会看到服务器打印出了 【抓到 Cookie】 Cookie: username=zhangsan。

  4. 排坑 :如果你发现 Cookie 没写进去,或者过期时间报错,检查 expires 的时间格式。它必须是 Fri, 18 Dec 2026 12:00:00 UTC 这种严格的 RFC 1123 格式(GMT 或 UTC),千万不能用中文,也不能用 2026-12-18。

相关推荐
~央千澈~1 小时前
优雅草新产品2026 年 10 月 31 日公测完毕v1.0.0 优雅草人机盾正式运营上线
安全·网络安全·安全防御
2401_868534781 小时前
网络规划设计师之案例分析 - 网络安全与等级保护
服务器·网络
zhangrelay1 小时前
Arduino-MEGA-ESP单片机理论课笔记-01入门-02硬件-03开发环境-2026
笔记·单片机·嵌入式硬件·学习·机器人
是真的小外套1 小时前
网络安全实战第10期:Nmap主机发现之一键扫清整个网段
网络·安全·web安全
环境栈笔记1 小时前
指纹浏览器安卓怎么用?从运行位置到功能验收,先把三种方案分清
前端·人工智能·后端·自动化
垚垚学技术_聚焦云原生1 小时前
Ansible Vault 安全实践:敏感密码、密钥加密存储方案
安全·elasticsearch·ansible
北冥you鱼1 小时前
区块链供应链金融如何降低中小企业融资成本
网络·金融·区块链
tianbin9111 小时前
Claude Code 用户的中转站实战笔记:接入、压测与避坑
笔记
计算机魔术师1 小时前
Anthropic IPO 招股文件披露近 9000 亿美元隐性债务
前端