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

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

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

重要认知:

前端加密 ≠ 绝对安全

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

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

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

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

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

    用途

    1. 密码处理
    2. 签名校验
    3. 数据完整性校验

    常见算法: 
    1. MD5(已不安全) : 可人为制造碰撞(指攻击者找到两个不同的输入,经过哈希计算后,却产生相同的哈希值的过程)
    2. SHA-1 (不推荐,逐渐被淘汰,存在碰撞攻击) 
    3. SHA-256 和 SHA-512(推荐,属于SHA-2),目前广泛应用

        示例
        1.使用api : window.crypto.subte( ) 密码学操作(需要HTTPS)
        2. 也可以使用CryptoJS js 的加密库, 支持多种加密算法(AES,SHA,MD5等)

// 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(已过时): 被破解 

示例: 

// 最简单的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.非对称加密(公钥/私钥): 先用它安全的交换对称密钥,然后用对称加密处理数据! 

特点: 

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

适合: 

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

缺点

  • 慢 
  • 不适合大量数据 

常见算法 : 

ECC(更安全,少见) 加密原理来自于椭圆双曲线
 

// 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. 非对称加密和对称加密对比

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

 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);

特性

对称加密

非对称加密

密钥数量

单个密钥,加解密相同。

一对密钥,公钥加密,私钥解密。

速度

非常快,适合加密大量数据。

非常慢(比对称加密慢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 + 前端处理 + 后端校验 + 风控策略 

Read more

Qwen3-TTS-12Hz-1.7B-VoiceDesign在虚拟现实中的应用:沉浸式语音体验

Qwen3-TTS-12Hz-1.7B-VoiceDesign在虚拟现实中的应用:沉浸式语音体验 想象一下,你戴上虚拟现实头盔,进入一个奇幻世界。迎面走来的精灵向导开口说话,声音清脆悦耳,带着森林的灵动气息。你向左转,听到远处巨龙的低吼,声音低沉浑厚,仿佛从山洞深处传来。你开口询问,向导立刻回应,声音自然流畅,就像真人在你身边对话。 这不是科幻电影,而是Qwen3-TTS-12Hz-1.7B-VoiceDesign技术正在实现的虚拟现实体验。传统的虚拟现实语音要么是机械的合成音,要么需要大量真人录音,成本高、灵活性差。现在,有了这个语音设计模型,开发者可以用自然语言描述任何声音,让虚拟世界里的每个角色都拥有独特、自然的嗓音。 1. 为什么虚拟现实需要更好的语音体验? 虚拟现实的魅力在于沉浸感——让你感觉真的置身于另一个世界。视觉上,现在的头显设备已经能做到相当逼真,4K分辨率、高刷新率、广阔的视野,画面越来越接近真实。但听觉体验呢?很多时候还是个短板。 你可能有这样的经历:在虚拟现实游戏里,NPC(非玩家角色)说话声音单调,所有角色听起来都差不多,或者有明显的机械感。对话不

无人机树木计数目标检测数据集(附YOLOv1-v13资料和部分代码)

无人机树木计数目标检测数据集(附YOLOv1-v13资料和部分代码)

小伙伴们好,我是小嬛。专注于人工智能、计算机视觉领域相关分享研究。【目标检测、图像分类、图像分割、目标跟踪等项目都可做,也可做不同模型对比实验;需要的可联系(备注来意)。】 引言: 目标检测开源数据集是计算机视觉领域的重要基石,支撑目标检测任务的算法研发、模型训练与性能评估,兼顾样本的丰富性、场景的覆盖性与应用的通用性。它包含海量标注精细的图像或视频样本,覆盖日常场景(如行人、车辆、家具)、自然场景(如动物、植物、地形)、工业场景(如机械零件、生产流水线)等数十类通用目标,也涵盖医疗场景(如血细胞、病灶区域)、遥感场景(如建筑、农田、舰船)、自动驾驶场景(如交通标志、障碍物)等专业领域目标。优质的目标检测开源数据集不仅样本数量充足、场景多样性强,还具备精准的目标边界框标注(部分含目标类别、姿态、遮挡状态等属性信息),并合理划分为训练集、验证集与测试集,能够有效支撑算法创新与模型优化,

Spring Boot 集成 Neo4j 图数据库实战教程

Spring Boot 集成 Neo4j 图数据库实战教程

在当今大数据时代,传统的关系型数据库在处理复杂关系网络时往往力不从心。Neo4j 作为领先的图数据库,能够高效地存储和查询海量关系数据。本文将详细介绍如何在 Spring Boot 项目中集成 Neo4j,并提供完整的实战案例,帮助读者快速掌握图数据库的开发技巧。 一、图数据库概述与 Neo4j 简介 1.1 为什么选择图数据库 在传统的关系型数据库中,当我们需要查询"朋友的朋友"这样的多跳关系时,往往需要编写复杂的多表关联查询,性能随关系层数增加呈指数级下降。而图数据库天然适合处理这类场景,它将数据之间的关系作为核心Citizens,利用图遍历算法高效地查询关系网络。 图数据库的核心优势体现在以下几个方面。首先是性能优势,对于深度关系查询,图数据库的性能是关系型数据库的数倍甚至数十倍。其次是灵活性优势,图数据库的 schema 更加灵活,可以随时添加新的节点类型和关系类型,而无需修改表结构。第三是表达力优势,图的数据模型更加直观,使用节点和边来描述现实世界的关系,与人类的思维方式更加契合。 Neo4j 是目前最流行的图数据库之一,它使用 Cypher 查询语言,具有高性能

Angular应用在Chrome中调用高德地图API定位超时问题解析与安全方案

1. 问题现象:为什么我的Angular应用在Chrome里定位总是“转圈圈”? 最近在做一个基于Angular的项目,需要集成高德地图来实现用户位置获取。功能在Edge、Firefox上跑得挺顺溜,可一到Chrome上就卡壳了——那个定位的小图标转啊转,最后给你弹出一个“定位超时”(Geolocation Timeout)的错误。这事儿别提多闹心了,明明代码一样,高德地图的Key也配置对了,怎么换个浏览器就不灵了呢? 一开始我也以为是自己的代码写错了,反复检查了@types/amap-js-api的类型声明,确认AMap.Geolocation的调用方式没问题。后来一搜,发现不少用Vue、React甚至原生JS开发的朋友,只要在Chrome里调用高德地图定位,都踩过这个坑。这就有点意思了,看来不是我们前端框架的锅,问题可能出在更底层的地方。最让人困惑的是,有时候你开了“科学上网”工具,诶,定位居然成功了!但这显然不是个正经的解决方案,且不说安全性和稳定性,你总不能要求每个用户都先去折腾网络配置吧。 这个问题的核心体验就是:在Chrome浏览器中,通过高德地图JavaScript