HarmonyOS 鸿蒙Next cryptoFramework中AES的CBC模式加密结果与java后端不一致
HarmonyOS 鸿蒙Next cryptoFramework中AES的CBC模式加密结果与java后端不一致
的AES加密方法时,使用了CBC模式,和java后端加密出来的结果不一样,也无法互相解密。我们的明文是“123456”,秘钥是“381ccb3658e1ef2bd182870221e5f01b”,java偏移量写的是16个0“0000000000000000”,鸿蒙端也是一个16位的都是0的数组,let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
但是java后端加密出来的结果是“pXcp7U+XxCkJX1oj3qtjHQ==”,和网上各种AES加密工具加出来的一致,如
https://tool.lvtao.net/aes
https://www.ssleye.com/ssltool/aes_cipher.html
但是鸿蒙端加密出来的结果却是“SbTfhttrenx6rhBqpSVsRQ==”。
请问到底是哪里出了问题,是不是偏移量的问题?16个0的写法,是不是在鸿蒙里对应是这样写呢?谢谢解答!
代码如下:
// AES加密
static async AESEncrypt(message: string, AESKeyHex: string): Promise<string> {
let keyData = CmftLiveEncryptUtils.hexToUint8Array(AESKeyHex);
//let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]);
let symKey = await CmftLiveEncryptUtils.genSymKeyByData(keyData);
let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, ‘utf-8’).buffer) };
let encryptText = await CmftLiveEncryptUtils.AESEncryptMessagePromise(symKey, plainText);
let that = new util.Base64Helper();
let result = that.encodeToStringSync(encryptText.data);
console.info(‘AES加密完成’ + result);
return result;
}
// AES解密
static async AESDecrypt(message: string, AESKeyHex: string): Promise<string> {
let keyData = CmftLiveEncryptUtils.hexToUint8Array(AESKeyHex);
let symKey = await CmftLiveEncryptUtils.genSymKeyByData(keyData);
let that = new util.Base64Helper();
let newMessage = that.decodeSync(message);
let input: cryptoFramework.DataBlob = { data: newMessage };
let decryptText = await CmftLiveEncryptUtils.AESDecryptMessagePromise(symKey, input);
//console.info('AES解密完成decrypt plainText: ’ + buffer.from(decryptText.data).toString(‘utf-8’));
let resultStr = buffer.from(decryptText.data).toString(‘utf-8’);
return resultStr;
}
// AES加密消息
static async AESEncryptMessagePromise(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
let cipher = cryptoFramework.createCipher(‘AES128|CBC|PKCS7’);
// let cipher = cryptoFramework.createCipher(‘AES128|ECB|PKCS7’);
let iv = CmftLiveEncryptUtils.genIvParamsSpec();
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, iv);
let cipherData = await cipher.doFinal(plainText);
return cipherData;
}
// AES解密消息
static async AESDecryptMessagePromise(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {
let decoder = cryptoFramework.createCipher(‘AES128|CBC|PKCS7’);
// let decoder = cryptoFramework.createCipher(‘AES128|ECB|PKCS7’);
let iv = CmftLiveEncryptUtils.genIvParamsSpec();
await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, iv);
let decryptData = await decoder.doFinal(cipherText);
return decryptData;
}
static async genSymKeyByData(symKeyData: Uint8Array) {
let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
let aesGenerator = cryptoFramework.createSymKeyGenerator(‘AES128’);
let symKey = await aesGenerator.convertKey(symKeyBlob);
CmftLogger.info(‘convertKey success’);
return symKey;
}
static genIvParamsSpec() {
let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 bytes
// let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6]; // 16 bytes
let dataIv = new Uint8Array(arr);
let ivBlob: cryptoFramework.DataBlob = { data: dataIv };
let ivParamsSpec: cryptoFramework.IvParamsSpec = {
algName: “IvParamsSpec”,
iv: ivBlob
};
return ivParamsSpec;
}
<button style="position: absolute; padding: 4px 8px 0px; cursor: pointer; top: 8px; right: 8px; font-size: 14px;">复制</button>
两个平台数据显示方式不同,并不影响加密结果。
以-59和197为例:
Java返回的-59,是0xC5 使用 8位带符号整数 表示的结果。
ArkTS返回的197,是0xC5 使用 无符号整数 表示的结果。
加解密也可以使用三方库crypto-js实现,链接如下:https://ohpm.openharmony.cn/#/cn/detail/[@ohos](/user/ohos)%2Fcrypto-js
iv是字符串“0000000000000000”,转换为Uint8Array是48,试试let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];里面的0都改为48就对了。
针对HarmonyOS 鸿蒙Next的cryptoFramework中AES的CBC模式加密结果与Java后端不一致的问题,这通常是由于加密参数(如密钥、初始化向量IV、填充方式等)不匹配或数据格式转换不一致导致的。
要解决这个问题,请确保以下几点:
- 密钥一致性:确保在HarmonyOS端和Java后端使用的AES密钥完全相同,且密钥长度符合AES算法要求(如AES-128, AES-192, AES-256)。
- IV一致性:CBC模式需要一个随机生成的IV,确保两端在加密和解密时使用相同的IV。
- 填充方式:确认两端使用的填充方式是否一致,常见的填充方式有PKCS#5、PKCS#7等。
- 数据格式:在加密前,确保数据格式(如字符串编码)在两端一致。加密后的数据通常为二进制格式,在传输或存储时需注意保持其完整性。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html。