HarmonyOS 鸿蒙Next:为什么鸿蒙AES加密后的字节数组与Java加密后的字节数组不同,鸿蒙字节全是正数而Java字节有正有负
HarmonyOS 鸿蒙Next:为什么鸿蒙AES加密后的字节数组与Java加密后的字节数组不同,鸿蒙字节全是正数而Java字节有正有负
这是鸿蒙的加密相关逻辑
async encrypt(str: string): Promise<string> {
const input = { data: this.getbyte(str) };
Logger.error(“east input =====”, input.data.toString())
const rsaGenerator = cryptoFramework.createSymKeyGenerator(“AES128”);
const encryptCipher = cryptoFramework.createCipher(“AES128|CBC|PKCS5”);
const keyPair = await rsaGenerator.convertKey({ data: this.arrKey });
Logger.error(“east arrKey =====”, this.arrKey.toString())
encryptCipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair, this.genGcmParamsSpec());
const dataBlob = await encryptCipher.doFinal(input);
Logger.error(“east input =====”, dataBlob.data.toString())
let retStr = new util.Base64Helper().encodeToStringSync(dataBlob.data)
Logger.error(“east retStr =====”, retStr)
return retStr;
}
genGcmParamsSpec() {
let arr = [0, 0, 0, 0 , 0, 0, 0, 0, 0, 0 , 0, 0]; // 12 bytes
let dataIv = new Uint8Array(arr);
let ivBlob = {data : dataIv};
arr = [0, 0, 0, 0 , 0, 0, 0, 0]; // 8 bytes
let dataAad = new Uint8Array(arr);
let aadBlob = {data : dataAad};
arr = [0, 0, 0, 0 , 0, 0, 0, 0, 0, 0, 0, 0 , 0, 0, 0, 0]; // 16 bytes
let dataTag = new Uint8Array(arr);
let tagBlob = {data : dataTag}; // GCM的authTag在加密时从doFinal结果中获取,在解密时填入init函数的params参数中
let gcmParamsSpec = {iv : ivBlob, aad : aadBlob, authTag : tagBlob, algName : “GcmParamsSpec”};
return gcmParamsSpec;
}
getbyte(str) {
let textEncoder = new util.TextEncoder();
let buffer = new ArrayBuffer(20);
let result = new Uint8Array(buffer);
result = textEncoder.encodeInto(str);
return result;
}
getstr(arr: Uint8Array) {
let result = util.TextDecoder.create(‘utf-8’, { ignoreBOM: true })
let retStr = result.decodeWithStream(arr)
return retStr
}
getkey(str: string): Uint8Array {
// 创建一个空的16位字节数组(默认值为0)
let arrBTmp = this.getbyte(str)
const arrB: Uint8Array = new Uint8Array(16);
// 将原始字节数组转换为 8 位
for (let i = 0;
i < arrBTmp.length && i < arrB.length;
i++) {
arrB[i] = arrBTmp[i];
}
return arrB
}
}
这是java的加密逻辑
public String getEncString(String strMing) {
Key key = getKey(arrKey);//16的整数倍
byte[] iv = new byte[16];//16的整数倍
IvParameterSpec ivspec = new IvParameterSpec(iv);
encryptCipher = Cipher.getInstance(“AES/CBC/PKCS5Padding”);
encryptCipher.init(Cipher.ENCRYPT_MODE, key,ivspec);
byte[] byteMi = null;
byte[] byteMing = null;
String strMi = “”;
try {
byteMing = strMing.getBytes(“UTF8”);
byteMi = Cipher.doFinal(byteMing;
strMi = Base64.encodeToString(byteMi,Base64.NO_WRAP);
strMi = strMi.replace("\r", “”);
strMi = strMi.replace("\n", “”);
} catch (Exception e) {
strMi = strMing;
}
return strMi;
}
private Key getKey(byte[] arrBTmp) throws Exception {
// 创建一个空的16位字节数组(默认值为0)
byte[] arrB = new byte[16];
// 将原始字节数组转换为8位
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
arrB[i] = arrBTmp[i];
}
// 生成密钥
Key key = new javax.crypto.spec.SecretKeySpec(arrB, “AES”);
return key;
}
两个语言加密出来的字节数组,除了负数对应位置数据不同,其他数据相同,这是为什么呢?
下面是是鸿蒙加密的字节数组
[43, 281,85,261, 84,43, 15,63, 116,32, 285,55, 131,33, 109,41, 199,53, 56, 210, 166, 227 ,64,18, 244, 31,177, 28,95,106,193,75]
java加密的字节数组
[43, -55, 85, -20, -72, 43, 15, 63, 116, 32, -51, 55, -125, 33, 109, 41, -57, 53, 56, -46, -90, -29, 64, 18, -12, 31, -79, 28, 95, 106, -63, 75]
Uint8Array
类型,这个无符号,是0~255的数组
还有一个类型是
Int8Array
这个是有符号的,范围 -128~127,应该和Java的byte[]显示结果类似,
两种类型显示结果不同,但是二进制的情况下,两种类型的每一位应该都是一样的,如果单纯进行按位操作的话,两个类型应该是没什影响,
作为IT专家,对于HarmonyOS鸿蒙Next与Java在AES加密后字节数组表现上的差异,以下进行简要解析:
HarmonyOS与Java在底层实现和数据处理上存在本质区别。HarmonyOS的AES加密结果可能经过特定处理,如使用无符号字节(Uint8Array)表示,其值域为非负整数(0~255)。而Java中的字节(byte)是有符号的,值域为-128~127,因此加密后的字节数组会包含正数和负数。
此外,加密过程中的填充方式、初始向量(IV)、密钥管理等细节也可能影响加密结果。即使使用相同的加密算法和密钥,如果这些细节处理不一致,也会导致加密后的字节数组不同。
因此,开发者在跨平台加密解密时,需确保两端使用的加密算法、密钥、填充方式等完全一致,并对加密后的数据进行适当的编码(如Base64)以确保数据在传输和存储过程中的一致性和安全性。
如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html