HarmonyOS鸿蒙Next中RN第三方库希望适配react-native-aes-cbc库
HarmonyOS鸿蒙Next中RN第三方库希望适配react-native-aes-cbc库 在我们应用的登录的时候使用RN的react-native-aes-cbc库加解密功能传递用户信息
aes的cbc加解密方法可以参考:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/crypto-aes-sym-encrypt-decrypt-cbc-V5
其中同步方案代码为:
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer } from '@kit.ArkTS';
function genIvParamsSpec() {
let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 bytes
let dataIv = new Uint8Array(arr);
let ivBlob: cryptoFramework.DataBlob = { data: dataIv };
let ivParamsSpec: cryptoFramework.IvParamsSpec = {
algName: "IvParamsSpec",
iv: ivBlob
};
return ivParamsSpec;
}
// 加密消息
function encryptMessage(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
let cipher = cryptoFramework.createCipher('AES128|CBC|PKCS7');
let iv = genIvParamsSpec();
cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, iv);
let cipherData = cipher.doFinalSync(plainText);
return cipherData;
}
// 解密消息
function decryptMessage(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {
let decoder = cryptoFramework.createCipher('AES128|CBC|PKCS7');
let iv = genIvParamsSpec();
decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, iv);
let decryptData = decoder.doFinalSync(cipherText);
return decryptData;
}
async function genSymKeyByData(symKeyData: Uint8Array) {
let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
let symKey = await aesGenerator.convertKey(symKeyBlob);
console.info('convertKey success');
return symKey;
}
async function main() {
try {
let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]);
let symKey = await genSymKeyByData(keyData);
let message = "This is a test";
let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
let encryptText = encryptMessage(symKey, plainText);
let decryptText = decryptMessage(symKey, encryptText);
if (plainText.data.toString() === decryptText.data.toString()) {
console.info('decrypt ok');
console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8'));
} else {
console.error('decrypt failed');
}
} catch (error) {
console.error(`AES CBC "${error}", error code: ${error.code}`);
}
}
或者看看已适配的三方开源库crypto-js是否符合要求:https://gitee.com/openharmony-sig/crypto-js
可参考以下:
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer, util } from '@kit.ArkTS';
function genIvParamsSpec(IV: Uint8Array) {
let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 bytes
let dataIv = IV;
let ivBlob: cryptoFramework.DataBlob = { data: dataIv };
let ivParamsSpec: cryptoFramework.IvParamsSpec = {
algName: "IvParamsSpec",
iv: ivBlob
};
return ivParamsSpec;
}
function generateSalt(): cryptoFramework.DataBlob {
let rand = cryptoFramework.createRandom();
let len = 16; // Generate a 16-byte random number.
return rand.generateRandomSync(len);
}
function getEncryptedPassword(password: string, salt: cryptoFramework.DataBlob): cryptoFramework.DataBlob {
let spec: cryptoFramework.PBKDF2Spec = {
algName: 'PBKDF2',
password: password,
salt: salt.data,
iterations: 32767,
keySize: 16
};
let kdf = cryptoFramework.createKdf('PBKDF2|SHA256');
return kdf.generateSecretSync(spec);
}
// 加密消息
function encryptMessage(keySalt: cryptoFramework.DataBlob, password: string, plainText: cryptoFramework.DataBlob) {
let symKey = cryptoFramework.createSymKeyGenerator("AES128").convertKeySync(keySalt)
let cipher = cryptoFramework.createCipher('AES128|CBC|PKCS7');
let iv = genIvParamsSpec(new Uint8Array(16));
cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, iv);
let cipherData = cipher.doFinalSync(plainText);
return cipherData;
}
function decryptMessage(password: cryptoFramework.DataBlob, cipherText: cryptoFramework.DataBlob, IV: Uint8Array) {
let symKey = cryptoFramework.createSymKeyGenerator("AES128").convertKeySync(password)
let decoder = cryptoFramework.createCipher('AES128|CBC|PKCS7');
let iv = genIvParamsSpec(IV);
decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, iv);
let decryptData = decoder.doFinalSync(cipherText);
return decryptData;
}
// 字节流转成可理解的字符串
function uint8ArrayToString(array: Uint8Array) {
// 将UTF-8编码转换成Unicode编码
let out: string = '';
let index: number = 0;
let len: number = array.length;
while (index < len) {
let character = array[index++];
switch (character >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
out += String.fromCharCode(character);
break;
case 12:
case 13:
out += String.fromCharCode(((character & 0x1F) << 6) | (array[index++] & 0x3F));
break;
case 14:
out += String.fromCharCode(((character & 0x0F) << 12) | ((array[index++] & 0x3F) << 6) |
((array[index++] & 0x3F) << 0));
break;
default:
break;
}
}
return out;
}
async function main() {
let password: string = "a230e43a230e43543f5d14=="
let message =
"jQFzOGyT4IrlQsuDV6o6mAQ7AtOHBmhEWRGU/02AAgfkxuhQmZ0bJ9whz2etF2psov/Iu9SuUmZVZEmaC7bkcw2MK4ba4xoRBCxRYOo7bJjvA53I7qtQUVtdgyE5+xjGJBMMpbrhbpRjZ7CuvYbiR1boK4vSxjKwmoX/NvZrdgMITkBTWkWDoWnZMYtgksMHVdhRr11QHpegt0WuNRVBkNAsScBydXbOStiON9ePSJNY0Sg2KH48L3ivUhk/50VOEbN+FwwMWvbPb7xV5F4IX3Zbiv8u4yFiT/suoXi0Pq7Lo56QU2YI64z4ne0fxwDCSdarsCJatKjfJ6yZdayFhA=="
let base64: util.Base64Helper = new util.Base64Helper();
let decodeMsg: Uint8Array = base64.decodeSync(message, util.Type.BASIC);
let saltkey = decodeMsg.slice(0, 16)
let iv = decodeMsg.slice(16, 32)
let msg = decodeMsg.slice(32, decodeMsg.length)
let keySalt = getEncryptedPassword(password, { data: saltkey });
let newpassword = base64.encodeToStringSync(keySalt.data, util.Type.BASIC);
newpassword = newpassword.substring(0, 16);
let encryptText: cryptoFramework.DataBlob = { data: msg };
let decryptText = decryptMessage({ data: new Uint8Array(buffer.from(newpassword, 'utf-8').buffer) }, encryptText, iv);
console.info('decrypt plainText: ' + uint8ArrayToString(decryptText.data));
}
@Entry @Component struct Index { @State message: string = ‘Hello World’;
aboutToAppear(): void {}
build() { RelativeContainer() { Text(this.message) .id(‘HelloWorld’) .fontSize(50) .fontWeight(FontWeight.Bold) .alignRules({ center: { anchor: ‘container’, align: VerticalAlign.Center }, middle: { anchor: ‘container’, align: HorizontalAlign.Center } }) Button(“AES cbc test”).onClick(() => { main() }) } .height(‘100%’) .width(‘100%’) } }
更多关于HarmonyOS鸿蒙Next中RN第三方库希望适配react-native-aes-cbc库的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中适配react-native-aes-cbc库,首先需要确保该库的底层依赖(如OpenSSL或其他加密库)在鸿蒙平台上可用。如果鸿蒙系统支持这些依赖,可以通过以下步骤进行适配:
-
修改Native模块:检查
react-native-aes-cbc的Native代码(如C/C++部分),确保其与鸿蒙的NDK兼容。可能需要调整与平台相关的API调用。 -
调整构建配置:更新
build.gradle或CMakeLists.txt,确保在鸿蒙平台上正确编译和链接。 -
测试与验证:在鸿蒙设备或模拟器上运行测试,确保加密功能正常工作。
如果鸿蒙不支持某些依赖,可能需要寻找替代方案或自行实现相关功能。


