You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Expo的React Native AES加密实现方法问询

没错,你说得对——expo-crypto确实只提供哈希相关的工具,没有直接支持AES加密/解密的API。不过好在有几个靠谱的方案能在Expo项目里实现AES加密,我给你整理了最常用的几种:

方案1:使用crypto-js库(最简便)

这是最直接的方式,crypto-js是一个成熟的JavaScript加密库,完全兼容Expo环境,不需要额外的原生配置。

首先安装依赖:

npx expo install crypto-js

然后可以封装一个加密/解密工具函数:

import CryptoJS from 'crypto-js';

// 加密函数
export const encryptAES = (data, key) => {
  // 将密钥转换为WordArray格式
  const parsedKey = CryptoJS.enc.Utf8.parse(key);
  // 生成随机IV(初始向量)
  const iv = CryptoJS.lib.WordArray.random(16);
  // 执行AES-CBC加密
  const encrypted = CryptoJS.AES.encrypt(data, parsedKey, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  });
  // 将IV和加密结果拼接(解密时需要用到IV)
  return iv.toString(CryptoJS.enc.Base64) + ':' + encrypted.toString();
};

// 解密函数
export const decryptAES = (encryptedData, key) => {
  const parsedKey = CryptoJS.enc.Utf8.parse(key);
  // 拆分IV和加密内容
  const [ivBase64, encryptedText] = encryptedData.split(':');
  const iv = CryptoJS.enc.Base64.parse(ivBase64);
  // 执行解密
  const decrypted = CryptoJS.AES.decrypt(encryptedText, parsedKey, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  });
  // 将解密结果转换为字符串
  return decrypted.toString(CryptoJS.enc.Utf8);
};

注意:密钥长度建议用128位(16字符)或256位(32字符),确保加密强度;另外,IV必须是随机的,不要固定使用同一个IV,否则会降低安全性。

方案2:使用Web Crypto API(原生支持,无需额外库)

Expo的JavaScript运行环境(Hermes或JSC)其实支持Web Crypto API,你可以直接用它来实现AES加密,不需要依赖第三方库。

这里是一个示例实现:

// 生成加密密钥(可以缓存密钥,不用每次加密都生成)
const generateAESKey = async (keyString) => {
  // 将密钥字符串转换为Uint8Array
  const keyBuffer = new TextEncoder().encode(keyString);
  // 导出密钥(使用SHA-256哈希确保密钥长度符合要求)
  const hashedKey = await crypto.subtle.digest('SHA-256', keyBuffer);
  // 生成CryptoKey对象
  return crypto.subtle.importKey(
    'raw',
    hashedKey,
    { name: 'AES-CBC', length: 256 },
    false,
    ['encrypt', 'decrypt']
  );
};

// 加密函数
export const encryptWithWebCrypto = async (data, keyString) => {
  const key = await generateAESKey(keyString);
  // 生成随机IV
  const iv = crypto.getRandomValues(new Uint8Array(16));
  // 加密数据
  const encryptedBuffer = await crypto.subtle.encrypt(
    { name: 'AES-CBC', iv: iv },
    key,
    new TextEncoder().encode(data)
  );
  // 将IV和加密结果转换为Base64并拼接
  const ivBase64 = btoa(String.fromCharCode(...iv));
  const encryptedBase64 = btoa(String.fromCharCode(...new Uint8Array(encryptedBuffer)));
  return `${ivBase64}:${encryptedBase64}`;
};

// 解密函数
export const decryptWithWebCrypto = async (encryptedData, keyString) => {
  const key = await generateAESKey(keyString);
  const [ivBase64, encryptedBase64] = encryptedData.split(':');
  // 将Base64转换为Uint8Array
  const iv = new Uint8Array(atob(ivBase64).split('').map(c => c.charCodeAt(0)));
  const encryptedBuffer = new Uint8Array(atob(encryptedBase64).split('').map(c => c.charCodeAt(0)));
  // 解密数据
  const decryptedBuffer = await crypto.subtle.decrypt(
    { name: 'AES-CBC', iv: iv },
    key,
    encryptedBuffer
  );
  // 转换为字符串
  return new TextDecoder().decode(decryptedBuffer);
};

注意:Web Crypto API是异步的,所以所有操作都需要用async/await;另外,确保你的Expo项目使用的是支持Web Crypto的运行环境(Hermes在0.70+版本支持,JSC也支持)。

方案3:自定义Expo模块(适合需要原生级加密的场景)

如果上面的方案都满足不了你的需求(比如需要和原生系统的加密API深度集成),你可以基于expo-modules-core开发一个自定义模块,调用iOS的CommonCrypto或Android的javax.crypto实现AES加密。不过这个方案需要一定的原生开发知识,适合复杂场景。

内容的提问来源于stack exchange,提问作者Sadiq Sadiq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 23:42:46