前端实现加密的常见方法和步骤

 更新时间:2025年06月19日 08:28:52   作者:liangshanbo1215  
这篇文章主要介绍了前端实现加密的常见方法和步骤,包括对称(AES)、非对称(RSA/ECC)及哈希(SHA-256)算法,推荐使用WebCryptoAPI、CryptoJS等工具,需要的朋友可以参考下

前言

在前端实现加密是一种常见的安全措施,用于保护敏感数据(如密码、用户信息等)在传输或存储过程中的安全性。以下是实现前端加密的常见方法和步骤:

1. 常见的加密方式

(1) 对称加密

  • 使用同一个密钥进行加密和解密。
  • 优点:速度快,适合加密大量数据。
  • 缺点:密钥需要安全地共享,容易被破解。
  • 常见算法:AES(Advanced Encryption Standard)。

(2) 非对称加密

  • 使用一对密钥(公钥和私钥),公钥用于加密,私钥用于解密。
  • 优点:安全性高,适合密钥交换和身份验证。
  • 缺点:速度较慢,不适合加密大量数据。
  • 常见算法:RSA、ECC(Elliptic Curve Cryptography)。

(3) 哈希算法

  • 将数据转换为固定长度的散列值,不可逆。
  • 常用于密码存储和数据完整性校验。
  • 常见算法:SHA-256、MD5(不推荐用于安全性要求高的场景)。

2. 实现前端加密

(1) 使用 Web Crypto API (推荐)

Web Crypto API 是浏览器原生提供的加密接口,支持现代加密标准。

// 加密函数
async function encryptData(plainText, secretKey) {
  const encoder = new TextEncoder();
  const data = encoder.encode(plainText);
  
  // 使用AES-GCM算法
  const iv = window.crypto.getRandomValues(new Uint8Array(12));
  const encrypted = await window.crypto.subtle.encrypt(
    {
      name: "AES-GCM",
      iv: iv
    },
    secretKey,
    data
  );
  
  return {
    iv: Array.from(iv).join(','),
    ciphertext: Array.from(new Uint8Array(encrypted)).join(',')
  };
}

// 生成密钥
async function generateKey() {
  return await window.crypto.subtle.generateKey(
    {
      name: "AES-GCM",
      length: 256
    },
    true,
    ["encrypt", "decrypt"]
  );
}

(2) CryptoJS

CryptoJS 是一个流行的 JavaScript 加密库,支持多种加密算法(如 AES、SHA、MD5 等)。

// 引入 CryptoJS
const CryptoJS = require("crypto-js");

// 加密
const secretKey = "my-secret-key-123"; // 密钥
const data = "Sensitive data";
const encrypted = CryptoJS.AES.encrypt(data, secretKey).toString();
console.log("Encrypted:", encrypted);

// 解密
const decrypted = CryptoJS.AES.decrypt(encrypted, secretKey).toString(CryptoJS.enc.Utf8);
console.log("Decrypted:", decrypted);

(3) jsrsasign

jsrsasign 是一个支持 RSA 和 ECC 的 JavaScript 加密库。

const KJUR = require("jsrsasign");

// 生成密钥对
const keyPair = KJUR.KEYUTIL.generateKeypair("RSA", 1024);
const publicKey = KJUR.KEYUTIL.getPEM(keyPair.pubKeyObj);
const privateKey = KJUR.KEYUTIL.getPEM(keyPair.prvKeyObj, "PKCS8PRV");

// 加密
const plainText = "Sensitive data";
const encrypted = KJUR.crypto.Cipher.encrypt(plainText, keyPair.pubKeyObj);
console.log("Encrypted:", encrypted);

// 解密
const decrypted = KJUR.crypto.Cipher.decrypt(encrypted, keyPair.prvKeyObj);
console.log("Decrypted:", decrypted);

3. 前端加密的应用场景

(1) 用户密码加密

  • 在用户登录时,前端对密码进行加密后再发送到服务器。
  • 通常使用哈希算法(如 SHA-256)或非对称加密(如 RSA)。
const CryptoJS = require("crypto-js");

function hashPassword(password) {
  return CryptoJS.SHA256(password).toString(CryptoJS.enc.Hex);
}

const password = "user_password";
const hashedPassword = hashPassword(password);
console.log("Hashed Password:", hashedPassword);

(2) 数据传输加密

  • 在前后端通信中,使用对称加密(如 AES)或 HTTPS 协议保护数据。
  • 如果使用对称加密,密钥应通过安全的方式(如非对称加密)传递。

1、非对称加密传输密钥

// 客户端生成对称密钥
async function generateAndEncryptKey(publicKey) {
  const symmetricKey = await generateKey();
  
  // 使用服务器的公钥加密对称密钥
  const exportedKey = await window.crypto.subtle.exportKey('raw', symmetricKey);
  const encryptedKey = await window.crypto.subtle.encrypt(
    {
      name: "RSA-OAEP"
    },
    publicKey,
    exportedKey
  );
  
  return {
    encryptedKey: Array.from(new Uint8Array(encryptedKey)).join(','),
    symmetricKey
  };
}

2、完整传输流程

  • 客户端请求服务器公钥

  • 服务器返回RSA公钥

  • 客户端生成AES密钥并用RSA公钥加密

  • 发送加密后的AES密钥到服务器

  • 之后通信使用AES加密

(3) 数据完整性校验

  • 使用哈希算法生成数据的散列值,并在接收端校验散列值是否一致。
const CryptoJS = require("crypto-js");

const data = "Original data";
const hash = CryptoJS.SHA256(data).toString(CryptoJS.enc.Hex);

console.log("Generated Hash:", hash);

(4) 本地存储加密

// 使用Web Crypto API封装本地存储
const secureStorage = {
  async setItem(key, value, secretKey) {
    const encrypted = await encryptData(value, secretKey);
    localStorage.setItem(key, JSON.stringify(encrypted));
  },
  
  async getItem(key, secretKey) {
    const encryptedData = JSON.parse(localStorage.getItem(key));
    if (!encryptedData) return null;
    
    const decrypted = await decryptData(encryptedData, secretKey);
    return decrypted;
  }
};

// 使用示例
(async () => {
  const key = await generateKey();
  await secureStorage.setItem('user_data', JSON.stringify({name: 'John'}), key);
  const data = await secureStorage.getItem('user_data', key);
  console.log(data);
})();

4. 注意事项

  • 不要依赖前端加密作为唯一的安全措施

    • 前端代码容易被篡改,攻击者可以通过调试工具绕过加密逻辑。
    • 后端始终需要对数据进行验证和加密。
  • 结合 HTTPS 使用

    • 始终使用HTTPS

    • 实施CSRF保护

    • 添加时间戳和随机数防止重放攻击

  • 避免硬编码密钥

    • 不要在前端硬编码密钥,容易被查看源码获取。
    • 考虑使用密钥派生函数(如PBKDF2)或者定期轮换密钥
  • 选择合适的算法

    • 对于密码存储,优先使用不可逆的哈希算法(如 SHA-256 或 bcrypt)。
    • 对于数据传输,优先使用对称加密(如 AES)或 HTTPS。
  • 性能考虑:
    • Web Workers中进行加密运算避免阻塞UI

    • 对大文件使用分块加密

总结 

到此这篇关于前端实现加密的常见方法和步骤的文章就介绍到这了,更多相关前端实现加密内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • javascript屏蔽右键代码

    javascript屏蔽右键代码

    屏蔽右键在某些特殊的情况下还是比较有用的,下面与大家分享个常用的屏蔽方法
    2014-05-05
  • javascript结合canvas实现图片旋转效果

    javascript结合canvas实现图片旋转效果

    图片的旋转可以说是一种效果,但是逐渐旋转已经不单单是属于视觉效果那个范畴,其更具有使用性,功能性。照片有时候是需要横过来的拍的,当我们预览或共享到web上时需要进行旋转。这个操作在以往可能更多的是交给软件去完成,然后再将旋转到正常角度的图片发布到web上。
    2015-05-05
  • javascript使用prototype完成单继承

    javascript使用prototype完成单继承

    这篇文章主要介绍了javascript使用prototype完成单继承的方法及示例代码,有需要的小伙伴参考下
    2014-12-12
  • JS获取客户端IP地址、MAC和主机名的7个方法汇总

    JS获取客户端IP地址、MAC和主机名的7个方法汇总

    这篇文章主要介绍了JS获取客户端IP地址、MAC和主机名的7个方法汇总,JS本身是不支持获取IP地址等信息的,本文通过其它方法实现,需要的朋友可以参考下
    2014-07-07
  • JS正则表达式验证密码格式的集中情况总结

    JS正则表达式验证密码格式的集中情况总结

    这篇文章主要介绍了JS正则表达式验证密码格式的集中情况总结,需要的朋友可以参考下
    2017-02-02
  • JS函数的定义与调用方法推荐

    JS函数的定义与调用方法推荐

    下面小编就为大家带来一篇JS函数的定义与调用方法推荐。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-05-05
  • JavaScript代码性能优化总结(推荐)

    JavaScript代码性能优化总结(推荐)

    下面小编就为大家带来一篇JavaScript代码性能优化总结(推荐)。小编觉得挺不错的,现在分享给大家,也给大家做个参考,一起跟随小编过来看看吧,祝大家游戏愉快哦
    2016-05-05
  • 复制小说文本时出现的随机乱码的去除方法

    复制小说文本时出现的随机乱码的去除方法

    想把小说复制下来慢慢看,却发现复制到记事本里出现一大堆乱七八糟的东西,很是不爽。于是就想了个简单的办法把它干掉了。
    2010-09-09
  • 在Web关闭页面时发送Ajax请求的实现方法

    在Web关闭页面时发送Ajax请求的实现方法

    这篇文章主要给大家介绍了关于如何在Web关闭页面时发送Ajax请求的实现方法,文中通过示例代码以及图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-03-03
  • 浅谈Rx响应式编程

    浅谈Rx响应式编程

    在学习Rx编程的过程中,理解Observable这个概念至关重要,常规学习过程中,通常需要进行多次碰壁才能逐渐开悟。这个有点像小时候学骑自行车,必须摔几次才能掌握一样。当然如果有办法能言传,则可以少走一些弯路,尽快领悟Rx的精妙
    2021-06-06

最新评论