前端密码加密

4 阅读1分钟
import { encryptRsaOaepSha256 } from 'rsa-oaep';
let password = await encryptRsaOaepSha256(formObj.value.password, serverKey);

rsa-oaep.js

// 基于 WebCrypto 的 RSA-OAEP(SHA-256) 加密

function base64ToArrayBuffer(base64) {
  const clean = (base64 || '').replace(/\s+/g, '');
  const binaryString = typeof atob === 'function' ? atob(clean) : Buffer.from(clean, 'base64').toString('binary');
  const len = binaryString.length;
  const bytes = new Uint8Array(len);
  for (let i = 0; i < len; i += 1) {
    bytes[i] = binaryString.charCodeAt(i);
  }
  return bytes.buffer;
}

function arrayBufferToBase64(buffer) {
  const bytes = new Uint8Array(buffer);
  let binary = '';
  for (let i = 0; i < bytes.byteLength; i += 1) {
    binary += String.fromCharCode(bytes[i]);
  }
  return typeof btoa === 'function' ? btoa(binary) : Buffer.from(binary, 'binary').toString('base64');
}

async function importSpkiPublicKey(base64Spki) {
  const keyData = base64ToArrayBuffer(base64Spki);
  return await window.crypto.subtle.importKey(
    'spki',
    keyData,
    {
      name: 'RSA-OAEP',
      hash: 'SHA-256',
    },
    false,
    ['encrypt']
  );
}

export async function encryptRsaOaepSha256(plainText, base64SpkiPublicKey) {
  const cryptoKey = await importSpkiPublicKey(base64SpkiPublicKey);
  const encoded = new TextEncoder().encode(plainText);
  const cipher = await window.crypto.subtle.encrypt({ name: 'RSA-OAEP' }, cryptoKey, encoded);
  return arrayBufferToBase64(cipher);
}

这段代码是前端实现的密码加密逻辑,核心是用 RSA-OAEP (SHA-256) 算法对用户密码加密,避免明文传输,保障数据安全。

整体流程很清晰:

  1. 先把服务端给的 Base64 格式公钥,转换成浏览器原生 WebCrypto API 能识别的密钥对象;
  2. 把用户输入的明文密码转成二进制格式,用公钥做 RSA-OAEP 加密;
  3. 再把加密后的二进制密文转回 Base64 字符串,方便接口传输。

实现的前端侧 RSA-OAEP (SHA-256) 非对称加密逻辑,主要用于用户密码等敏感信息在传输到服务端前的加密,避免明文传输导致的安全风险,底层基于浏览器原生的 WebCrypto API 实现,而非第三方库,兼顾安全性和性能。