前端加密(常用加密方式及使用)

一. 什么是前端加密?(先纠正一个常见误区)

前端加密 ,指的是在浏览器(js环境)中,对数据进行加密 /签名 /混淆 /校验等操作,再发送给后端

重要认知:

前端加密 ≠ 绝对安全

前端代码是可被查看,可被调试,可被篡改的.

所以前端加密的核心目的不是[防止高手],而是:

  • 防止明文传输
  • 防止低成本抓包,脚本刷接口
  • 提高攻击门槛
  • 与后端做配合校验

二 . 前端常见的加密[分类]

  1. 哈希(不可逆) : (哈希也叫散列,是一种将任意长度 的输入如数据,文件,消息)通过哈希函数转换成固定长度 输出的过程,这个输出通常成为哈希值 ,散列值摘要

    用途 :

    1. 密码处理

    2. 签名校验

    3. 数据完整性校验

    常见算法:

    1. MD5(已不安全) : 可人为制造碰撞 (指攻击者找到两个不同的输入,经过哈希计算后,却产生相同的哈希值的过程)

    2. SHA-1 (不推荐,逐渐被淘汰,存在碰撞攻击)

    3. SHA-256 和 SHA-512(推荐,属于SHA-2),目前广泛应用

示例 :

1.使用api : window.crypto.subte( ) 密码学操作(需要HTTPS)

  1. 也可以使用CryptoJS js 的加密库, 支持多种加密算法(AES,SHA,MD5等)
javascript 复制代码
// 1. 准备数据
const text = "123456";
const encoder = new TextEncoder();
const data = encoder.encode(text);

// 2. 计算哈希
const hashBuffer = await crypto.subtle.digest('SHA-256', data);

// 3. 转为十六进制
const hashArray = Array.from(new Uint8Array(hashBuffer));
const hashHex = hashArray.map(b => b.toString(16).padStart(2, '0')).join('');

console.log("SHA-256:", hashHex);
// 输出: 8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92

2.对称加密(前后端共用密钥)

特点:

  • 加密解密使用同一个key
  • 性能好,适合大量数据

常见算法:

  • AES(主流): 是目前全球最常用的对称加密算法,美国国家安全局用来保护绝密级信息的算法
  • DES(已过时): 被破解

示例:

javascript 复制代码
// 最简单的AES加密解密
async function aesSimple() {
  // 1. 生成密钥
  const key = await crypto.subtle.generateKey(
    {name: "AES-GCM", length: 256}, true, ["encrypt", "decrypt"]
  );
  
  // 2. 加密
  const iv = crypto.getRandomValues(new Uint8Array(12));
  const encrypted = await crypto.subtle.encrypt(
    {name: "AES-GCM", iv}, key, new TextEncoder().encode("你好世界")
  );
  
  // 3. 解密
  const decrypted = await crypto.subtle.decrypt(
    {name: "AES-GCM", iv}, key, encrypted
  );
  
  console.log("结果:", new TextDecoder().decode(decrypted)); // 你好世界
}
aesSimple();

3.非对称加密(公钥/私钥): 先用它安全的交换对称密钥,然后用对称加密处理数据!

特点:

  • 前端: 公钥加密
  • 后端: 私钥解密
  • 私钥不暴露

适合:

  • 密码
  • 关键字段
  • 初始密钥交换

缺点:

  • 不适合大量数据

常见算法 :

  • RSA(最常见): 原理来自于大数的质因数分解

    javascript 复制代码
     async function generateRSAKeys () {
                // 生成 RSA 密钥对
                const keyPair = await crypto.subtle.generateKey(
                    {
                        name: "RSA-OAEP",           // RSA 算法
                        modulusLength: 2048,        // 2048 位
                        publicExponent: new Uint8Array([0x01, 0x00, 0x01]), // 65537
                        hash: "SHA-256"             // 使用的哈希
                    },
                    true,  // 可导出
                    ["encrypt", "decrypt"]  // 用途
                );
    
                return {
                    publicKey: keyPair.publicKey,
                    privateKey: keyPair.privateKey
                };
            }
            async function rsaEncryptDecrypt () {
                console.log("=== RSA 加密解密示例 ===");
    
                // 1. 生成密钥对
                const { publicKey, privateKey } = await generateRSAKeys();
                console.log("密钥对生成完成");
    
                // 2. 准备要加密的数据
                const message = "这是一条秘密消息";
                const data = new TextEncoder().encode(message);
    
                // 3. 用公钥加密
                const encrypted = await crypto.subtle.encrypt(
                    { name: "RSA-OAEP" },
                    publicKey,
                    data
                );
                console.log("加密完成,密文长度:", encrypted.byteLength, "字节");
    
                // 4. 用私钥解密
                const decrypted = await crypto.subtle.decrypt(
                    { name: "RSA-OAEP" },
                    privateKey,
                    encrypted
                );
    
                const decryptedMessage = new TextDecoder().decode(decrypted);
                console.log("解密结果:", decryptedMessage);
    
                return { publicKey, privateKey, encrypted };
            }
    
            // 运行示例
            rsaEncryptDecrypt().catch(console.error);
  • ECC(更安全,少见) 加密原理来自于椭圆双曲线

    javascript 复制代码
    // ECC 密钥交换完整流程演示
    class ECCFlow {
      static async demonstrateCompleteFlow() {
        console.log("ECC 密钥交换完整流程演示");
        console.log("==========================");
        
        // 第1步:选择椭圆曲线
        console.log("\n第1步:选择椭圆曲线");
        const curve = "P-256";
        console.log("   选择的曲线: " + curve);
        console.log("   安全强度: 128位");
        console.log("   公钥长度: 65字节");
        console.log("   私钥长度: 32字节");
        
        // 第2步:双方生成密钥对
        console.log("\n第2步:双方生成密钥对");
        
        // Alice 生成密钥对
        const aliceKeyPair = await crypto.subtle.generateKey(
          { name: "ECDH", namedCurve: curve },
          true,
          ["deriveKey"]
        );
        console.log("   Alice 生成密钥对:");
        console.log("     - 私钥: 保密存储");
        console.log("     - 公钥: 准备发送给 Bob");
        
        // Bob 生成密钥对
        const bobKeyPair = await crypto.subtle.generateKey(
          { name: "ECDH", namedCurve: curve },
          true,
          ["deriveKey"]
        );
        console.log("   Bob 生成密钥对:");
        console.log("     - 私钥: 保密存储");
        console.log("     - 公钥: 准备发送给 Alice");
        
        // 第3步:交换公钥
        console.log("\n第3步:交换公钥(通过网络)");
        
        const bobPublicKey = bobKeyPair.publicKey;
        console.log("   Alice 收到 Bob 的公钥");
        
        const alicePublicKey = aliceKeyPair.publicKey;
        console.log("   Bob 收到 Alice 的公钥");
        
        // 第4步:计算共享密钥
        console.log("\n第4步:各自计算共享密钥");
        console.log("   数学原理:");
        console.log("   Alice私钥 × Bob公钥 = Bob私钥 × Alice公钥");
        
        // Alice 计算共享密钥
        const aliceSharedKey = await crypto.subtle.deriveKey(
          {
            name: "ECDH",
            public: bobPublicKey
          },
          aliceKeyPair.privateKey,
          { name: "AES-GCM", length: 256 },
          true,
          ["encrypt", "decrypt"]
        );
        console.log("   Alice 计算共享密钥完成");
        
        // Bob 计算共享密钥
        const bobSharedKey = await crypto.subtle.deriveKey(
          {
            name: "ECDH",
            public: alicePublicKey
          },
          bobKeyPair.privateKey,
          { name: "AES-GCM", length: 256 },
          true,
          ["encrypt", "decrypt"]
        );
        console.log("   Bob 计算共享密钥完成");
        
        // 第5步:验证密钥相同
        console.log("\n第5步:验证双方密钥相同");
        
        const aliceKeyBytes = await crypto.subtle.exportKey("raw", aliceSharedKey);
        const bobKeyBytes = await crypto.subtle.exportKey("raw", bobSharedKey);
        
        const aliceHex = Array.from(new Uint8Array(aliceKeyBytes))
          .map(b => b.toString(16).padStart(2, '0'))
          .join('');
        
        const bobHex = Array.from(new Uint8Array(bobKeyBytes))
          .map(b => b.toString(16).padStart(2, '0'))
          .join('');
        
        console.log("   验证结果:");
        console.log("   Alice 密钥: " + aliceHex.substring(0, 32) + "...");
        console.log("   Bob 密钥:   " + bobHex.substring(0, 32) + "...");
        console.log("   是否相同: " + (aliceHex === bobHex ? "是" : "否"));
        
        // 第6步:使用共享密钥加密通信
        console.log("\n第6步:使用共享密钥加密通信");
        
        const message = "会议时间改为下午2点";
        console.log("   Alice 要发送: \"" + message + "\"");
        
        // 加密
        const iv = crypto.getRandomValues(new Uint8Array(12));
        const encrypted = await crypto.subtle.encrypt(
          { name: "AES-GCM", iv },
          aliceSharedKey,
          new TextEncoder().encode(message)
        );
        
        console.log("   加密完成:");
        console.log("     - 密文长度: " + encrypted.byteLength + " 字节");
        console.log("     - IV: " + Array.from(iv).slice(0, 3).join(',') + "...");
        
        // 第7步:Bob 解密消息
        console.log("\n第7步:Bob 解密消息");
        
        const decrypted = await crypto.subtle.decrypt(
          { name: "AES-GCM", iv },
          bobSharedKey,
          encrypted
        );
        
        const decryptedMessage = new TextDecoder().decode(decrypted);
        console.log("   Bob 解密得到: \"" + decryptedMessage + "\"");
        console.log("   是否正确: " + (message === decryptedMessage ? "是" : "否"));
        
        // 安全性分析
        console.log("\n安全性分析:");
        console.log("   中间人无法计算共享密钥");
        console.log("   即使窃听到公钥交换也没用");
        console.log("   每次会话可生成新的密钥对");
        
        return {
          aliceKeyPair,
          bobKeyPair,
          sharedKey: aliceSharedKey,
          encryptedMessage: encrypted
        };
      }
    }
    
    // 运行完整流程
    ECCFlow.demonstrateCompleteFlow().catch(console.error);

    4. 非对称加密和对称加密对比

特性 对称加密 非对称加密
密钥数量 单个密钥,加解密相同。 一对密钥,公钥加密,私钥解密。
速度 非常快,适合加密大量数据。 非常慢(比对称加密慢100-1000倍),不适合大数据。
安全性基础 密钥的保密性。密钥必须安全共享。 密钥对的数学关系。私钥保密,公钥可公开。
主要功能 保证数据的机密性 保证机密性、身份认证和不可否认性
密钥分发 核心难题。如何安全地将密钥传递给对方? 天然解决。公钥可以公开分发,无需保密。
常见算法 AES(高级加密标准)、DES、3DES、ChaCha20 RSA、ECC(椭圆曲线加密)、ElGamal
典型应用 文件加密、数据库加密、SSL/TLS会话加密、Wi-Fi(WPA2) SSL/TLS密钥交换、数字签名、电子邮件加密(PGP)、区块链

5. 签名≠加密

签名的本质是:

证明数据是"你"发的,且未被篡改

常见做法:

sign = hash(params + secret + timestamp)

//前端

sign = sha256(a=1&b=2&secret=xxx&ts=123

后端:

  • 用同样规则计算
  • 对比sign是否一致

三. 前端加密的底线原则

  1. 前端加密永远不是安全的终点
  2. 所有安全校验,必须在后端完成
  3. 前端加密的价值是: 降低成本攻击,而不是消灭攻击
  4. 真正的安全 = https + 前端处理 + 后端校验 + 风控策略
相关推荐
脩衜者3 分钟前
极其灵活且敏捷的WPF组态控件ConPipe 2026
前端·物联网·ui·wpf
Mike_jia8 分钟前
Dockge:轻量开源的 Docker 编排革命,让容器管理回归优雅
前端
GISer_Jing14 分钟前
前端GEO优化:AI时代的SEO新战场
前端·人工智能
没想好d17 分钟前
通用管理后台组件库-4-消息组件开发
前端
文艺理科生18 分钟前
Google A2UI 解读:当 AI 不再只是陪聊,而是开始画界面
前端·vue.js·人工智能
晴栀ay21 分钟前
React性能优化三剑客:useMemo、memo与useCallback
前端·javascript·react.js
JS_GGbond21 分钟前
JavaScript继承大冒险:从“原型江湖”到“class殿堂”
前端
XiaoYu200221 分钟前
第6章 Postgres数据库安装
前端·postgresql
洛卡卡了22 分钟前
从活动编排到积分系统:事件驱动在业务系统中的一次延伸
前端·后端·面试
知其然亦知其所以然23 分钟前
别再死记硬背了,一篇文章搞懂 JS 乘性操作符
前端·javascript·程序员