跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
JavaScriptNode.js大前端算法

Web 聊天室消息加解密方案详解

Web 聊天室通信安全核心在于防止中间人攻击与数据泄露。对比了 AES 对称加密、非对称 ECC/RSA、混合加密及 Signal 协议等主流方案,结合前端 Web Crypto API 与后端 Node.js 实现细节,分析各场景下的性能与安全性权衡。重点阐述密钥协商机制与前向安全性设计,为实时通讯系统提供可落地的加密选型建议。

古灵精怪发布于 2026/3/23更新于 2026/8/2038 浏览
Web 聊天室消息加解密方案详解

文章配图

一、Web 聊天室消息加解密需求与技术约束

基于 WebSocket 或 Socket.IO 的 Web 聊天室,承载着文本、图片甚至文件的实时传输。在单聊、群聊和广播场景下,安全风险主要集中在中间人监听、内容篡改、身份伪造以及服务器存储泄露。为了保障通信安全,我们需要在满足核心安全需求的同时,兼顾实时性与兼容性。

1.1 核心安全需求
需求维度定义与目标
机密性仅收发方可解密,防止流量被截获后解析
完整性验证传输过程未被篡改,如防止攻击者修改文本
身份认证确认发送方身份,杜绝冒充管理员等指令
前向安全性即使当前密钥泄露,历史消息仍无法解密
抗重放攻击防止旧消息(如转账指令)被重复发送
1.2 技术约束
  1. 实时性:加解密耗时需控制在毫秒级,避免 WebSocket 延迟影响群聊体验。
  2. 浏览器兼容:前端依赖 JS 实现,需考虑 Web Crypto API 及第三方库的支持范围。
  3. 前后端协同:算法、密钥格式、IV/密文/标签拼接规则必须统一。
  4. 设备适配:需支持低性能设备(如旧手机 WebView),避免强依赖硬件加速。
  5. 密钥管理:前端私钥存储要安全(慎用 localStorage),群聊密钥分发需高效。

二、主流消息加解密方案详解

2.1 方案 1:对称加密(AES-256-GCM)
2.1.1 方案概述

对称加密使用同一密钥完成加解密。AES-256 是当前主流标准,GCM 模式则同时提供机密性与完整性(通过认证标签)。它非常适合对实时性要求高的聊天室场景。

2.1.2 核心原理
  1. AES-256 基础:分组密码,将明文按 128 位分组,用 256 位密钥进行多轮置换与混淆。
  2. GCM 模式流程:生成 12 字节随机 IV,利用计数器生成密钥流与明文异或得到密文;同时对 IV、密文及附加数据计算 Galois 哈希,生成 16 字节认证标签。
  3. 解密验证:接收方用相同密钥 + IV 解密,重新计算标签比对,不一致即视为篡改。
2.1.3 实现步骤(分场景)
场景 1:单聊加密
  1. 密钥协商:用户 A 与 B 通过安全渠道交换 AES-256 密钥(通常结合非对称加密保护密钥传输)。
  2. :发送方生成 12 字节 IV,调用 AES-GCM 加密 API,输出密文与标签,拼接为 Base64 发送。
消息加密
  • 消息解密:接收方拆分 IV、密文、标签,验证标签通过后还原明文。
  • 场景 2:群聊加密
    1. 群密钥分发:创建者生成群密钥,用成员公钥加密后分发,确保只有成员能解出群密钥。
    2. 消息传输:发送方用群密钥加密,服务器转发,所有成员用群密钥解密。
    3. 密钥更新:成员变更时,重新生成群密钥并分发,旧成员自动失效。
    2.1.4 代码实现(前端 + 后端)
    前端(Vue3 + Web Crypto API)
    // 1. 生成 AES-256 密钥(extractable: false 防止导出)
    async function generateAesKey() {
      const key = await crypto.subtle.generateKey(
        { name: "AES-GCM", length: 256 },
        false,
        ["encrypt", "decrypt"]
      );
      return key;
    }
    
    // 2. AES-GCM 加密(注意参数补全)
    async function aesGcmEncrypt(plaintext, aesKey, additionalData = "") {
      const iv = crypto.getRandomValues(new Uint8Array(12));
      const plaintextUint8 = new TextEncoder().encode(plaintext);
      const adUint8 = new TextEncoder().encode(additionalData);
    
      const encrypted = await crypto.subtle.encrypt(
        { name: "AES-GCM", iv: iv, additionalData: adUint8, tagLength: 128 },
        aesKey,
        plaintextUint8
      );
    
      const encryptedUint8 = new Uint8Array(encrypted);
      // 最后 16 字节是标签
      const ciphertext = encryptedUint8.slice(0, encryptedUint8.length - 16);
      const tag = encryptedUint8.slice(encryptedUint8.length - 16);
    
      const combined = new Uint8Array([...iv, ...ciphertext, ...tag]);
      return btoa(String.fromCharCode(...combined));
    }
    
    // 3. AES-GCM 解密
    async function aesGcmDecrypt(base64Str, aesKey, additionalData = "") {
      const combined = new Uint8Array(
        atob(base64Str).split("").map(c => c.charCodeAt(0))
      );
      
      const iv = combined.slice(0, 12);
      const tag = combined.slice(combined.length - 16);
      const ciphertext = combined.slice(12, combined.length - 16);
      const adUint8 = new TextEncoder().encode(additionalData);
    
      try {
        const decrypted = await crypto.subtle.decrypt(
          { name: "AES-GCM", iv: iv, additionalData: adUint8, tagLength: 128 },
          aesKey,
          new Uint8Array([...ciphertext, ...tag])
        );
        return new TextDecoder().decode(decrypted);
      } catch (err) {
        throw new Error("密文被篡改或密钥错误");
      }
    }
    
    // 4. 单聊消息发送示例
    async function sendPrivateMessage(toUserId, plaintext, aesKey) {
      const messageId = uuidv4();
      const encryptedStr = await aesGcmEncrypt(plaintext, aesKey, messageId);
      socket.emit("privateMessage", {
        toUserId,
        messageId,
        encryptedStr,
        timestamp: Date.now()
      });
    }
    
    后端(Node.js + crypto)

    后端主要承担转发职责,不处理解密逻辑以保护密钥安全。若需验证完整性可添加签名校验。

    const express = require("express");
    const http = require("http");
    const { Server } = require("socket.io");
    
    const app = express();
    const server = http.createServer(app);
    const io = new Server(server, {
      cors: { origin: "http://localhost:8080" }
    });
    
    const userMap = new Map();
    
    io.on("connection", (socket) => {
      socket.on("userRegister", (userId, eccPublicKey) => {
        userMap.set(userId, { socketId: socket.id, eccPublicKey });
        socket.userId = userId;
        console.log(`用户${userId}上线`);
      });
    
      socket.on("privateMessage", (data) => {
        const { toUserId, messageId, encryptedStr, timestamp } = data;
        const targetUser = userMap.get(toUserId);
        if (targetUser) {
          io.to(targetUser.socketId).emit("privateMessage", {
            fromUserId: socket.userId,
            messageId,
            encryptedStr,
            timestamp
          });
        }
      });
    
      socket.on("groupMessage", (groupData) => {
        const { groupId, encryptedStr, messageId, timestamp } = groupData;
        io.to(groupId).emit("groupMessage", {
          fromUserId: socket.userId,
          messageId,
          encryptedStr,
          timestamp
        });
      });
    });
    
    server.listen(3000, () => console.log("后端服务启动:3000 端口"));
    
    2.1.5 优劣分析
    优点缺点
    性能优异,纯软件可达 GB/s 级密钥分发困难,单聊需安全通道
    兼容性好,现代浏览器均支持无身份认证,易被冒充
    GCM 模式抗篡改,256 位抗暴力破解缺乏前向安全性,密钥泄露即全量曝光
    消息体积小,带宽占用低群聊扩展性差,成员增多效率下降
    2.2 方案 2:非对称加密(RSA-2048/ECC secp256r1)
    2.2.1 方案概述

    非对称加密使用密钥对(公钥 + 私钥)。ECC(椭圆曲线加密)在同等安全性下密钥更短,性能优于 RSA,更适合 Web 场景。

    2.2.2 核心原理
    1. ECC secp256r1:基于有限域上的椭圆方程。私钥为随机整数,公钥为曲线上点。通过临时随机数派生共享密钥。
    2. RSA-2048:基于大数分解问题。适合兼容旧系统,但加密长度受限(最大约 245 字节)。
    2.2.3 实现步骤(分场景)
    场景 1:单聊加密(ECC)
    1. 密钥分发:用户生成密钥对,公钥上传服务器,私钥本地保存。
    2. 消息加密:发送方用接收方公钥生成临时密钥,派生 AES 密钥加密消息,发送临时公钥 + 密文。
    3. 消息解密:接收方用私钥派生相同 AES 密钥解密。
    场景 2:群聊加密(ECC)

    直接加密会导致 N 个成员需加密 N 次。优化方案是发送方生成临时 AES 群密钥,用每个成员公钥加密该 AES 密钥,再发送'加密的 AES 密钥 + AES 加密的消息'。

    2.2.4 代码实现(前端 ECC 加密)

    使用 libsodium-wrappers 库简化操作:

    import sodium from "libsodium-wrappers";
    await sodium.ready;
    
    // 1. 生成 ECC secp256r1 密钥对
    function generateEccKeyPair() {
      const keyPair = sodium.crypto_box_keypair();
      return {
        privateKey: sodium.to_base64(keyPair.privateKey),
        publicKey: sodium.to_base64(keyPair.publicKey)
      };
    }
    
    // 2. ECC 加密
    function eccEncrypt(plaintext, receiverPkBase64, senderSkBase64) {
      const receiverPk = sodium.from_base64(receiverPkBase64);
      const senderSk = sodium.from_base64(senderSkBase64);
      const nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);
      
      const ciphertext = sodium.crypto_box_easy(
        sodium.encode_utf8(plaintext),
        nonce,
        receiverPk,
        senderSk
      );
      
      const combined = sodium.concat([nonce, ciphertext]);
      return sodium.to_base64(combined);
    }
    
    // 3. ECC 解密
    function eccDecrypt(encryptedBase64, senderPkBase64, receiverSkBase64) {
      const senderPk = sodium.from_base64(senderPkBase64);
      const receiverSk = sodium.from_base64(receiverSkBase64);
      const combined = sodium.from_base64(encryptedBase64);
      
      const nonce = combined.slice(0, sodium.crypto_box_NONCEBYTES);
      const ciphertext = combined.slice(sodium.crypto_box_NONCEBYTES);
      
      try {
        const plaintext = sodium.crypto_box_open_easy(
          ciphertext, nonce, senderPk, receiverSk
        );
        return sodium.decode_utf8(plaintext);
      } catch (err) {
        throw new Error("解密失败:密钥错误或密文篡改");
      }
    }
    
    // 单聊发送示例
    const userAKeyPair = generateEccKeyPair();
    const userBPublicKey = "xxx"; // 从服务器获取
    const plaintext = "Hello, 非对称加密单聊!";
    const encryptedStr = eccEncrypt(plaintext, userBPublicKey, userAKeyPair.privateKey);
    
    socket.emit("privateMessage", {
      toUserId: "userB",
      encryptedStr,
      fromUserPublicKey: userAKeyPair.publicKey
    });
    
    2.2.5 优劣分析
    优点缺点
    密钥分发安全,公钥可公开性能较差,约为 AES 的 1/10
    支持身份认证(签名 + 验签)消息长度受限,大文件需分段
    前向安全性,会话密钥独立群聊兼容性差,N 个成员需 N 次加密
    私钥仅需本地存储部分旧浏览器不支持 ECC
    2.3 方案 3:混合加密(AES-256-GCM + ECC secp256r1)
    2.3.1 方案概述

    混合加密结合了对称加密的高性能与非对称加密的密钥分发优势,类似 TLS 协议原理,是 Web 聊天室的最优解之一。

    2.3.2 核心原理
    1. 密钥交换(ECDH):双方通过 ECDH 协议派生共享密钥,无需传输密钥本身。
    2. 消息传输(AES-GCM):用派生的 AES 密钥加密实际消息,保证高速传输。
    3. 前向安全:每次会话生成新的 ECC 密钥对,确保历史消息安全。
    2.3.3 实现步骤(单聊 + 群聊)
    场景 1:单聊加密(完整流程)
    1. 密钥协商:A 生成临时密钥对发送给 B,B 返回其长期公钥;双方各自计算共享点 S,派生 AES 密钥。
    2. 消息加密:使用派生的 AES 密钥加密消息。
    3. 会话更新:每发送一定数量消息或超时后,重新执行 ECDH 协商。
    场景 2:群聊加密(优化方案)

    群创建者生成 AES 群密钥,用每个成员的公钥加密该密钥后分发。成员收到后解密得到群密钥,后续消息直接用群密钥加密。

    2.3.4 代码实现(前端 ECDH 密钥协商 + AES 加密)
    // 1. 生成 ECC 长期密钥对
    async function generateLongEccKeyPair() {
      const keyPair = await crypto.subtle.generateKey(
        { name: "ECDH", namedCurve: "P-256" },
        true,
        ["deriveKey"]
      );
      const publicKeyRaw = await crypto.subtle.exportKey("spki", keyPair.publicKey);
      const publicKeyBase64 = btoa(String.fromCharCode(...new Uint8Array(publicKeyRaw)));
      return {
        privateKey: keyPair.privateKey,
        publicKey: publicKeyBase64
      };
    }
    
    // 2. ECDH 派生 AES 密钥
    async function deriveAesKey(localPrivateKey, peerPublicKeyBase64) {
      const peerPublicKeyRaw = new Uint8Array(
        atob(peerPublicKeyBase64).split("").map(c => c.charCodeAt(0))
      );
      const peerPublicKey = await crypto.subtle.importKey(
        "spki", peerPublicKeyRaw,
        { name: "ECDH", namedCurve: "P-256" },
        false, []
      );
    
      const sharedSecret = await crypto.subtle.deriveKey(
        { name: "ECDH", public: peerPublicKey },
        localPrivateKey,
        { name: "AES-GCM", length: 256 },
        false, ["encrypt", "decrypt"]
      );
      return sharedSecret;
    }
    
    // 3. 单聊完整流程示例
    async function initPrivateChat(withUserId) {
      const localLongKeyPair = await loadLocalLongKeyPair();
      const peerLongPublicKey = await axios.get(`/api/user/${withUserId}/publicKey`);
      
      const localTempKeyPair = await crypto.subtle.generateKey(
        { name: "ECDH", namedCurve: "P-256" }, true, ["deriveKey"]
      );
      const localTempPublicKeyRaw = await crypto.subtle.exportKey("spki", localTempKeyPair.publicKey);
      const localTempPublicKey = btoa(String.fromCharCode(...new Uint8Array(localTempPublicKeyRaw)));
    
      const peerTempPublicKey = await new Promise((resolve) => {
        socket.emit("requestTempPublicKey", { toUserId: withUserId, localTempPublicKey });
        socket.once("responseTempPublicKey", (data) => resolve(data.peerTempPublicKey));
      });
    
      const aesKey = await deriveAesKey(localTempKeyPair.privateKey, peerTempPublicKey);
      const plaintext = "混合加密单聊消息:AES+ECC";
      const messageId = uuidv4();
      const encryptedStr = await aesGcmEncrypt(plaintext, aesKey, messageId);
    
      socket.emit("privateMessage", { toUserId, messageId, encryptedStr });
    
      socket.on("privateMessage", async (data) => {
        if (data.fromUserId === withUserId) {
          const decryptedText = await aesGcmDecrypt(data.encryptedStr, aesKey, data.messageId);
          console.log("解密消息:", decryptedText);
        }
      });
    }
    
    2.3.5 优劣分析
    优点缺点
    性能均衡,适合实时群聊实现复杂度高,需处理多流程
    安全性强,兼顾机密与前向安全群密钥分发依赖服务器协同
    密钥管理可控,降低泄露风险旧浏览器兼容性差,需降级方案
    扩展性好,成员增多仅需加密一次密钥密钥更新需同步机制
    2.4 方案 4:端到端加密(基于 Signal Protocol)
    2.4.1 方案概述

    Signal Protocol 是专为即时通讯设计的端到端加密方案,被 WhatsApp、Signal 等采用,提供顶级安全性,支持单聊/群聊、前向安全及抗重放攻击。

    2.4.2 核心原理
    1. 双棘轮算法:结合对称棘轮与不对称棘轮,每次交互更新密钥,确保前向安全。
    2. 预密钥机制:用户提前上传一批预密钥,支持离线发起会话。
    3. Sender Key 机制:群聊中生成 Sender Key,发送方加密消息,成员解密。
    2.4.3 实现步骤(单聊场景)
    1. 初始化:生成身份密钥、签名密钥、预密钥,上传公钥到服务器。
    2. 会话建立:A 获取 B 的预密钥,生成临时密钥对,派生初始会话密钥。
    3. 持续更新:每发送消息更新发送密钥,定期更新预密钥。
    2.4.4 代码实现(基于 libsignal-protocol-javascript)
    import * as signal from "libsignal-protocol-javascript";
    
    class SignalStore {
      constructor() {\n    this.identityKeyPair = null;
        this.preKeys = new Map();
        this.signedPreKey = null;
        this.sessions = new Map();
      }
      putIdentityKeyPair(keyPair) { this.identityKeyPair = keyPair; }
      getIdentityKeyPair() { return this.identityKeyPair; }
      storePreKey(id, preKey) { this.preKeys.set(id, preKey); }
      getPreKey(id) { return this.preKeys.get(id); }
      storeSession(addr, session) { this.sessions.set(addr, session); }
      loadSession(addr) { return this.sessions.get(addr); }
    }
    
    async function registerSignalUser(userId) {
      const store = new SignalStore();
      const keyHelper = signal.KeyHelper;
      
      const identityKeyPair = await keyHelper.generateIdentityKeyPair();
      store.putIdentityKeyPair(identityKeyPair);
      
      const signedPreKey = await keyHelper.generateSignedPreKey(
        identityKeyPair, Math.floor(Date.now() / 1000)
      );
      store.signedPreKey = signedPreKey;
      
      for (let i = 0; i < 100; i++) {
        const preKey = await keyHelper.generatePreKey(i);
        store.storePreKey(preKey.keyId, preKey);
      }
    
      await axios.post("/api/signal/register", {
        userId,
        identityPublicKey: Buffer.from(identityKeyPair.pubKey).toString("base64"),
        signedPreKey: {
          keyId: signedPreKey.keyId,
          publicKey: Buffer.from(signedPreKey.pubKey).toString("base64"),
          signature: Buffer.from(signedPreKey.signature).toString("base64")
        },
        preKeys: Array.from(store.preKeys.entries()).map(([id, pk]) => ({
          keyId: id,
          publicKey: Buffer.from(pk.pubKey).toString("base64")
        }))
      });
      return store;
    }
    
    async function initSignalChat(store, targetUserId) {
      const keyHelper = signal.KeyHelper;
      const address = new signal.SignalProtocolAddress(targetUserId, 1);
      const targetPubKeys = await axios.get(`/api/signal/user/${targetUserId}/keys`);
      
      const ephemeralKeyPair = await keyHelper.generateEphemeralKeyPair();
      const sessionBuilder = new signal.SessionBuilder(store, address);
    
      await sessionBuilder.processPreKey({
        registrationId: 1,
        identityKey: Buffer.from(targetPubKeys.identityPublicKey, "base64"),
        signedPreKey: {
          keyId: targetPubKeys.signedPreKey.keyId,
          publicKey: Buffer.from(targetPubKeys.signedPreKey.publicKey, "base64"),
          signature: Buffer.from(targetPubKeys.signedPreKey.signature, "base64")
        },
        preKey: {
          keyId: targetPubKeys.preKey.keyId,
          publicKey: Buffer.from(targetPubKeys.preKey.publicKey, "base64")
        }
      });
    
      const sessionCipher = new signal.SessionCipher(store, address);
      const plaintext = "Signal Protocol 端到端加密消息";
      const ciphertext = await sessionCipher.encrypt(Buffer.from(plaintext, "utf8"));
    
      socket.emit("signalMessage", {
        toUserId: targetUserId,
        ciphertext: {
          type: ciphertext.type,
          ephemeralKeyId: ciphertext.ephemeralKeyId,
          ciphertext: Buffer.from(ciphertext.body).toString("base64")
        }
      });
    
      socket.on("signalMessage", async (data) => {
        if (data.fromUserId === targetUserId) {
          const decryptCiphertext = {
            type: data.ciphertext.type,
            ephemeralKeyId: data.ciphertext.ephemeralKeyId,
            body: Buffer.from(data.ciphertext.ciphertext, "base64")
          };
          const decrypted = await sessionCipher.decrypt(decryptCiphertext);
          console.log("解密消息:", decrypted.toString("utf8"));
        }
      });
    }
    
    2.4.5 优劣分析
    优点缺点
    安全性顶级,符合 E2EE 标准实现复杂度极高,需理解双棘轮等概念
    场景覆盖全,支持单聊/群聊学习成本高,API 文档较少
    成熟稳定,被数十亿用户验证服务器依赖强,需搭建兼容服务器
    密钥管理自动化前端库体积大,影响加载速度
    2.5 方案 5:轻量级加密(ChaCha20-Poly1305)
    2.5.1 方案概述

    ChaCha20 是 Google 设计的流密码,Poly1305 是高效 MAC。两者组合适合低性能设备,无需 AES 硬件加速,纯软件实现速度比 AES-GCM 快 30%~50%。

    2.5.2 核心原理
    1. ChaCha20:输入密钥、Nonce 和计数器,生成密钥流与明文异或。
    2. Poly1305:计算认证标签,验证密文完整性。
    2.5.3 实现步骤(单聊场景)
    1. 密钥生成:生成 32 字节 ChaCha20 密钥。
    2. 加密:生成 96 位 Nonce,加密明文,计算标签,发送 Nonce+ 密文 + 标签。
    3. 解密:拆分数据,生成密钥流解密,验证标签。
    2.5.4 代码实现(前端 libsodium)
    import sodium from "libsodium-wrappers";
    await sodium.ready;
    
    function generateChaChaKey() {
      return sodium.to_base64(sodium.randombytes_buf(sodium.crypto_aead_chacha20poly1305_ietf_KEYBYTES));
    }
    
    function chachaEncrypt(plaintext, keyBase64, additionalData = "") {
      const key = sodium.from_base64(keyBase64);
      const nonce = sodium.randombytes_buf(sodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES);
      const ad = sodium.encode_utf8(additionalData);
    
      const ciphertext = sodium.crypto_aead_chacha20poly1305_ietf_encrypt(
        sodium.encode_utf8(plaintext), ad, null, nonce, key
      );
      
      const combined = sodium.concat([nonce, ciphertext]);
      return sodium.to_base64(combined);
    }
    
    function chachaDecrypt(encryptedBase64, keyBase64, additionalData = "") {
      const key = sodium.from_base64(keyBase64);
      const combined = sodium.from_base64(encryptedBase64);
      const nonce = combined.slice(0, sodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES);
      const ciphertext = combined.slice(sodium.crypto_aead_chacha20poly1305_ietf_NPUBBYTES);
      const ad = sodium.encode_utf8(additionalData);
    
      try {
        const plaintext = sodium.crypto_aead_chacha20poly1305_ietf_decrypt(
          null, ciphertext, ad, nonce, key
        );
        return sodium.decode_utf8(plaintext);
      } catch (err) {
        throw new Error("解密失败:标签不匹配");
      }
    }
    
    // 单聊发送示例
    const chachaKey = generateChaChaKey();
    const plaintext = "低性能设备友好:ChaCha20 加密";
    const encryptedStr = chachaEncrypt(plaintext, chachaKey, "messageId_123");
    
    socket.emit("privateMessage", {
      toUserId: "userB",
      encryptedStr,
      keyId: "chacha_key_001"
    });
    
    2.5.5 优劣分析
    优点缺点
    性能优异,纯软件速度快同 AES,需非对称加密辅助分发
    兼容性好,libsodium 支持广泛

    文章配图

    目录

    1. 一、Web 聊天室消息加解密需求与技术约束
    2. 1.1 核心安全需求
    3. 1.2 技术约束
    4. 二、主流消息加解密方案详解
    5. 2.1 方案 1:对称加密(AES-256-GCM)
    6. 2.1.1 方案概述
    7. 2.1.2 核心原理
    8. 2.1.3 实现步骤(分场景)
    9. 场景 1:单聊加密
    10. 场景 2:群聊加密
    11. 2.1.4 代码实现(前端 + 后端)
    12. 前端(Vue3 + Web Crypto API)
    13. 后端(Node.js + crypto)
    14. 2.1.5 优劣分析
    15. 2.2 方案 2:非对称加密(RSA-2048/ECC secp256r1)
    16. 2.2.1 方案概述
    17. 2.2.2 核心原理
    18. 2.2.3 实现步骤(分场景)
    19. 场景 1:单聊加密(ECC)
    20. 场景 2:群聊加密(ECC)
    21. 2.2.4 代码实现(前端 ECC 加密)
    22. 2.2.5 优劣分析
    23. 2.3 方案 3:混合加密(AES-256-GCM + ECC secp256r1)
    24. 2.3.1 方案概述
    25. 2.3.2 核心原理
    26. 2.3.3 实现步骤(单聊 + 群聊)
    27. 场景 1:单聊加密(完整流程)
    28. 场景 2:群聊加密(优化方案)
    29. 2.3.4 代码实现(前端 ECDH 密钥协商 + AES 加密)
    30. 2.3.5 优劣分析
    31. 2.4 方案 4:端到端加密(基于 Signal Protocol)
    32. 2.4.1 方案概述
    33. 2.4.2 核心原理
    34. 2.4.3 实现步骤(单聊场景)
    35. 2.4.4 代码实现(基于 libsignal-protocol-javascript)
    36. 2.4.5 优劣分析
    37. 2.5 方案 5:轻量级加密(ChaCha20-Poly1305)
    38. 2.5.1 方案概述
    39. 2.5.2 核心原理
    40. 2.5.3 实现步骤(单聊场景)
    41. 2.5.4 代码实现(前端 libsodium)
    42. 2.5.5 优劣分析
    • 免费图片AI生成工具免费生成了解详情
    • Magick API 一键接入全球大模型注册送1000万token查看
    • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
    • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
    • 100+免费在线小游戏爽一把
    极客日志微信公众号二维码

    微信扫一扫,关注极客日志

    微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

    更多推荐文章

    查看全部
    • AI 小白的大模型学习路径与核心概念解析
    • 深入理解 Linux 线程控制:多线程编程实战技巧
    • Java 实战:多用户网页版聊天室项目搭建及用户好友管理模块实现
    • Ward 服务器监控工具部署与 cpolar 远程访问配置
    • CATE 条件平均处理效应估计:五大方法原理详解与实战
    • 基于 Python 和微信小程序的家教管理系统
    • AI 产品经理薪资趋势与核心面试指南
    • 华为小艺智慧助手深度评测:大模型如何重塑移动办公与生活
    • 基于 Python 与 AI 的智能害虫识别系统实战
    • 基于 Q-Learning 的无人机三维动态避障路径规划研究
    • 为何我想要线性历史与签名提交,GitHub 合并策略却难以满足
    • DES 加密算法原理详解、攻击手段及 3DES 原理
    • 本地部署 LLaMA 模型:新版 llama.cpp 实战指南
    • Arduino BLDC 基于 6.5 寸轮毂电机的智能动态跟随机器人底盘
    • AI 驱动的虚拟现实与增强现实开发
    • 并查集数据结构详解:操作、模板与经典练习
    • ChatGPT 辅助 SEO 实战技巧与提示词指南
    • Redis Hash 类型详解与核心指令实战
    • Obsidian 配置 Git 插件实现笔记同步到 GitHub(Mac 版)
    • 28 岁转行 Python:可行性分析与学习路径指南

    相关免费在线工具

    • 加密/解密文本

      使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

    • Gemini 图片去水印

      基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

    • Keycode 信息

      查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

    • Escape 与 Native 编解码

      JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

    • JavaScript / HTML 格式化

      使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

    • JavaScript 压缩与混淆

      Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online