React Native实现与PHP OpenSSL AES-256-CBC相同加密的问题
修正React Native中的AES加密逻辑以匹配PHP代码
你的React Native代码存在几个关键问题,导致与PHP加密逻辑不一致,无法获得API响应:
- 加密时错误地对base64编码后的字符串再次调用
JSON.stringify,PHP是直接加密base64字符串本身 - 未指定AES加密的模式、初始向量(IV),以及密钥/IV的字节长度补全逻辑(PHP的
openssl_encrypt会自动补全长度) - CryptoES默认的加密输出包含salt元数据,与PHP的原始二进制输出格式不匹配
正确的实现代码
import CryptoES from 'crypto-es'; import base64 from 'react-native-base64'; const value = session?.businessInfo?.number; const dataArray = [value]; const confidentialParams = { request_type: 'bill_status', custno: dataArray, key: 'billstatusapiauth', source: 'CustomerDashboard', }; // 1. 数组转JSON字符串(与PHP json_encode输出一致) const jsonStr = JSON.stringify(confidentialParams); // 2. JSON字符串转base64编码 const base64Str = base64.encode(jsonStr); // 3. 处理密钥和IV:补全到AES-256-CBC要求的字节长度 const keyRaw = 'billstatusapiauth'; const ivRaw = 'billrepository'; // AES-256要求密钥32字节,不足用\x00补全(和PHP逻辑一致) const key = CryptoES.enc.Utf8.parse(keyRaw.padEnd(32, '\0')); // CBC模式要求IV16字节,不足用\x00补全(和PHP逻辑一致) const iv = CryptoES.enc.Utf8.parse(ivRaw.padEnd(16, '\0')); // 4. AES-256-CBC加密,提取原始密文后转base64 const encrypted = CryptoES.AES.encrypt(base64Str, key, { iv: iv, mode: CryptoES.mode.CBC, padding: CryptoES.pad.Pkcs7, }); // 提取加密后的原始二进制数据,转base64编码 const encryptedBase64 = encrypted.ciphertext.toString(CryptoES.enc.Base64); // 最终发送给API的数据 const sendData = { enc: encryptedBase64 };
关键逻辑说明
- 密钥/IV补全:PHP的
openssl_encrypt在使用AES-256-CBC时,会自动将不足长度的密钥/IV用\x00填充到指定长度(32字节密钥、16字节IV),JS中必须手动实现该补全逻辑 - 加密参数对齐:明确指定CBC模式、PKCS7填充规则(与PHP默认行为一致),确保加密算法的各个参数完全匹配
- 输出格式匹配:直接提取加密后的原始密文(不包含CryptoES默认的salt元数据),再转base64编码,与PHP中
OPENSSL_RAW_DATA+base64_encode的输出完全一致 - 冗余代码移除:删除了不必要的
JSON.stringify(encodedbase64)调用,直接对base64字符串进行加密
内容的提问来源于stack exchange,提问作者Vishali
相关产品推荐
相关产品推荐

