React Native中实现与给定C#方法等效的Rijndael加解密逻辑
React Native 实现C# Rijndael AES-CBC加解密方案
核心逻辑对齐说明
C#端代码的核心加解密参数如下,所有实现必须严格对齐才能互通:
- 对称加密算法:Rijndael 即AES,工作模式为CBC,默认填充规则为PKCS7
- 密钥派生:使用.NET 内置
PasswordDeriveBytes生成密钥,无盐值、无迭代次数,基于SHA1哈希的PBKDF1规则扩展密钥长度,这是绝大多数网上公开方案适配失败的核心原因 - 初始向量IV:取配置中
sInitVector字符串的UTF8编码字节(和代码中ASCII编码完全兼容,只要IV为纯英文字符) - 输入输出:明文为UTF8编码的JSON字符串,密文输出为标准Base64编码
实现步骤
1. 安装依赖
使用原生层加密库保证性能和逻辑一致性,安装命令如下:
npm install react-native-quick-crypto buffer cd ios && pod install
2. 加解密工具代码
首先复现.NET专属的密钥派生逻辑,再封装和C#方法一一对应的加解密函数:
import { Buffer } from 'buffer'; import crypto from 'react-native-quick-crypto'; // 替换为客户提供的实际配置参数 const CRYPT_CONFIG = { passPhrase: '替换为MySecret.sPassPhrase的实际值', initVector: '替换为MySecret.sInitVector的实际值(固定16字节长度)', keySize: 256 // 替换为MySecret.iKeySize的实际值,常见为128或256 }; /** * 对齐.NET PasswordDeriveBytes的密钥派生规则 * @param {string} password 派生用密码 * @param {number} keyByteLength 所需密钥字节长度 * @returns {Buffer} 生成的密钥字节 */ function deriveDotNetKey(password, keyByteLength) { const pwdBuf = Buffer.from(password, 'utf8'); const hashList = []; let lastHash = null; let collectedLen = 0; while (collectedLen < keyByteLength) { const hashInput = lastHash ? Buffer.concat([lastHash, pwdBuf]) : pwdBuf; lastHash = crypto.createHash('sha1').update(hashInput).digest(); hashList.push(lastHash); collectedLen += lastHash.length; } return Buffer.concat(hashList).subarray(0, keyByteLength); } /** * 对应C#端EncryptFromDataObject方法 * @param {string} jsonStr 待加密的JSON字符串 * @returns {string} Base64格式密文 */ export function encrypt(jsonStr) { const key = deriveDotNetKey(CRYPT_CONFIG.passPhrase, CRYPT_CONFIG.keySize / 8); const iv = Buffer.from(CRYPT_CONFIG.initVector, 'utf8'); const cipher = crypto.createCipheriv(`aes-${CRYPT_CONFIG.keySize}-cbc`, key, iv); const encryptedBuf = Buffer.concat([ cipher.update(Buffer.from(jsonStr, 'utf8')), cipher.final() ]); return encryptedBuf.toString('base64'); } /** * 对应C#端DecryptToDataObject方法 * @param {string} cipherBase64 Base64格式密文 * @returns {string} 解密后的JSON字符串 */ export function decrypt(cipherBase64) { const key = deriveDotNetKey(CRYPT_CONFIG.passPhrase, CRYPT_CONFIG.keySize / 8); const iv = Buffer.from(CRYPT_CONFIG.initVector, 'utf8'); const cipherBuf = Buffer.from(cipherBase64, 'base64'); const decipher = crypto.createDecipheriv(`aes-${CRYPT_CONFIG.keySize}-cbc`, key, iv); const decryptedBuf = Buffer.concat([ decipher.update(cipherBuf), decipher.final() ]); return decryptedBuf.toString('utf8'); }
避坑说明
- 不要直接使用crypto-js等纯JS加密库的默认PBKDF2派生逻辑,该逻辑和.NET
PasswordDeriveBytes的PBKDF1扩展规则不兼容,会导致密钥不匹配加解密失败 - IV长度必须为16字节,不要对IV字符串做Base64解码,直接取UTF8编码字节即可
- 密钥长度必须严格和C#端
iKeySize一致,128位密钥对应aes-128-cbc算法标识,256位对应aes-256-cbc,不要混用 - 保持默认PKCS7填充即可,不要手动修改填充规则,否则会和C#端默认逻辑不兼容
内容的提问来源于stack exchange,提问作者izek_zam
相关产品推荐
相关产品推荐

