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

React Native中Node.js加密代码转crypto-es实现问题求助

修正后的React Native Expo TypeScript实现
import { useCallback, useMemo } from 'react';
import CryptoES from 'crypto-es';

export type CryptographyProps = {
  readonly text: string;
};

const ENCRYPTION_KEY = 'some-random-key-12345';
// 原Node.js用ASCII编码生成salt,Utf8对ASCII字符兼容,无需修改
const SALT = CryptoES.enc.Utf8.parse(ENCRYPTION_KEY);
const iterationCount = 1000;

const getKeyAndIv = () => {
  // 原Node.js生成48字节(32字节key + 16字节iv),对应crypto-es的keySize=12(每单位是4字节)
  const keyDerivation = CryptoES.PBKDF2(ENCRYPTION_KEY, SALT, {
    keySize: 12,
    iterations: iterationCount,
    hasher: CryptoES.algo.SHA1,
  });

  // 直接从WordArray截取对应字节,避免Hex转换的潜在误差
  const key = CryptoES.lib.WordArray.create(
    keyDerivation.words.slice(0, 8), // 8个32位字 = 32字节
    32
  );
  const iv = CryptoES.lib.WordArray.create(
    keyDerivation.words.slice(8), // 4个32位字 = 16字节
    16
  );

  return { key, iv };
};

export const useNewCryptography = () => {
  const encrypt = useCallback(({ text }: CryptographyProps): string => {
    const { key, iv } = getKeyAndIv();
    // 使用Utf16LE编码(对应Node.js的utf16le),而非默认的Utf16(大端序)
    const encrypted = CryptoES.AES.encrypt(
      CryptoES.enc.Utf16LE.parse(text),
      key,
      {
        iv: iv,
        padding: CryptoES.pad.Pkcs7,
        mode: CryptoES.mode.CBC,
      }
    );

    return encrypted.toString(); // 默认输出Base64,和原Node.js逻辑一致
  }, []);

  const decrypt = useCallback(({ text }: CryptographyProps): string => {
    const { key, iv } = getKeyAndIv();
    const decrypted = CryptoES.AES.decrypt(text, key, {
      iv: iv,
      padding: CryptoES.pad.Pkcs7,
      mode: CryptoES.mode.CBC,
    });

    // 用Utf16LE解码,对应原Node.js的utf16le输出
    return CryptoES.enc.Utf16LE.stringify(decrypted);
  }, []);

  return useMemo(() => ({ encrypt, decrypt }), [encrypt, decrypt]);
};

关键错误点与修正说明

  • UTF-16编码端序不匹配:
    原Node.js代码使用utf16le(小端序)处理文本,而crypto-es默认的CryptoES.enc.Utf16是大端序(UTF-16BE),这会导致文本编码完全错误。修正为CryptoES.enc.Utf16LE即可对齐原逻辑。

  • PBKDF2 keySize计算与WordArray处理错误:
    原Node.js通过pbkdf2Sync生成48字节数据(32字节密钥+16字节IV),crypto-es的keySize参数是以**32位字(4字节)**为单位,因此48字节对应keySize: 12(48/4=12)。
    原代码通过Hex字符串截取再解析的方式容易引入误差,直接操作WordArray的words数组截取对应部分更准确。

  • 冗余的Hex转换:
    原实现中将PBKDF2结果转为Hex字符串再截取解析,完全没必要,直接从WordArray的原始数据中分割密钥和IV更高效且避免转换误差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 04:45:22