HarmonyOS 鸿蒙Next开发涉及到加解密的内容时,是必须要使用真机吗?

发布于 1周前 作者 songsunli 来自 鸿蒙OS

HarmonyOS 鸿蒙Next开发涉及到加解密的内容时,是必须要使用真机吗?

问题背景、现象

最近在看鸿蒙的加解密内容,根据文档 指定二进制数据转换非对称密钥对 使用RSA非对称密钥分段加解密 编写了如下代码:

代码段

代码1,根据已有的公钥,生成密钥对对象

private static getRSAKeyPair(key: string = PublicKey): cryptoFramework.KeyPair | undefined {
    let publicKeyBlob: cryptoFramework.DataBlob = {data: Base64Utils.decode2Uint8Array(key)}
    let rsaGenerator = cryptoFramework.createAsyKeyGenerator("RSA2048")
    let keyPair: cryptoFramework.KeyPair | undefined
    try {
        keyPair = rsaGenerator.convertKeySync(publicKeyBlob, null)
    } catch (e) {
        hilog.error(RSAUtils.Domain, RSAUtils.LogTag, `getRSAKeyPair exception code = ${e.code}, ${e.message}`)
    }
    return keyPair
}

代码2,根据指定需要解密的密文和密钥字符串,完成解密之前的准备工作

public static decryptByString(src: string, key: string = PublicKey): string {
    // RSAUtils.getRSAKeyPairTest(key)
    let keyPair = RSAUtils.getRSAKeyPair(key)
    if (keyPair == undefined) {
        return RSAUtils.ERROR_KeyPair
    }
    const input: cryptoFramework.DataBlob = {data: new Uint8Array(buffer.from(src).buffer)}
    const result = RSAUtils.decryptByDataBlob(input, keyPair)
    return result.data.toString()
}

代码3,解密

private static decryptByDataBlob(src: cryptoFramework.DataBlob, keyPair: cryptoFramework.KeyPair): cryptoFramework.DataBlob {
    console.error("调用方法 decryptByDataBlob")
    const decoder = cryptoFramework.createCipher('RSA2048|PKCS1')
    decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.pubKey, null).then(() => {
        console.log("then回调resolve")
    }).catch((reason: Error) => {
        console.log("catch回调reject")
    })
    // decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.pubKey, null)
    const CipherTextSplitLen = 256;
    let decryptText = new Uint8Array()
    const cipherArray = src.data
    for (let i = 0; i < cipherArray.length; i+= CipherTextSplitLen) {
        const element = cipherArray.subarray(i, i + CipherTextSplitLen)
        const elementBlob: cryptoFramework.DataBlob = {data: element}
        // 解密出这一段的原文
        let decryptElement = decoder.doFinalSync(elementBlob)
        const mergeText = new Uint8Array(decryptText.length + decryptElement.data.length)
        mergeText.set(decryptText)
        mergeText.set(elementBlob.data, decryptText.length)
        // 和之前解密出的结果合并
        decryptText = mergeText
    }
    return {data: decryptText}
}

报错信息

  1. 首次调用上述代码3中被注释掉的decoder.initSync时,没有任何报错信息,也不输出结果。同一进程再次调用时,应用闪退并在log中报错init cipher fail.没有任何错误码值信息
  2. 改为调用decoder.init这个异步方法时,debug可以看到立刻走了Promise的rejected流程,catch捕获到的信息如下图

image

stack信息较长,复制下来是:

Cannot get SourceMap info, dump raw stack:
=====================Backtrace========================
#01 pc 00000000006e6437 /system/lib64/platformsdk/libark_jsruntime.so
#02 pc 00000000003127fc /system/lib64/platformsdk/libark_jsruntime.so
#03 pc 00000000001af798 /system/lib64/platformsdk/libark_jsruntime.so
#04 pc 00000000001af011 /system/lib64/platformsdk/libark_jsruntime.so
#05 pc 0000000000239e21 /system/lib64/platformsdk/libark_jsruntime.so
#06 pc 00000000005cb455 /system/lib64/platformsdk/libark_jsruntime.so
#07 pc 00000000005943be /system/lib64/platformsdk/libark_jsruntime.so
#08 pc 00000000000581a1 /system/lib64/platformsdk/libace_napi.z.so
#09 pc 00000000000319d3 /system/lib64/module/security/libcryptoframework_napi.z.so
#10 pc 0000000000015c66 /system/lib64/module/security/libcryptoframework_napi.z.so
#11 pc 0000000000064a66 /system/lib64/platformsdk/libace_napi.z.so
#12 pc 0000000000012f87 /system/lib64/platformsdk/libuv.so
#13 pc 0000000000017452 /system/lib64/platformsdk/libuv.so
#14 pc 0000000000016c63 /system/lib64/platformsdk/libuv.so
#15 pc 00000000000178e7 /system/lib64/platformsdk/libuv.so

已经尝试过但失败的方案

根据这个帖子 RSA加密的秘钥转换问题 中的4楼,我怀疑自己是类似原因导致密钥初始化失败,也照着弄了个x509,代码如下:

private static async getRSAKeyPairTest(key: string = PublicKey) {
    console.error("调用方法 getRSAKeyPair")
    // let publicKeyBlob: cryptoFramework.DataBlob = {data: Base64Utils.decode2Uint8Array(key)}
    let publicKeyBlobEncoding: cert.EncodingBlob = {
        data: Base64Utils.decode2Uint8Array(key),
        encodingFormat: cert.EncodingFormat.FORMAT_DER
    }
    let x509Cert = cert.createX509Cert(publicKeyBlobEncoding).then(result=>{
        console.log("调用方法 createX509Cert, 成功")
    }).catch((reason: Error) => {
        console.log("调用方法 createX509Cert, 失败")
    })
}

结果也在cert.createX509Cert时失败了,reason的stack信息和上面decoder.init的信息完全一致。

个人怀疑

如标题,报错信息是一堆so文件,是需要真机才能做这个加解密吗?


更多关于HarmonyOS 鸿蒙Next开发涉及到加解密的内容时,是必须要使用真机吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html

4 回复

问题初步排查了,我是使用公钥解密的,而非私钥解密,问题出在这里。这不是正常的加解密流程,公钥解密是验证签名流程应该使用。在Android中都是解密,在鸿蒙中提供了不同的api,强行传入公钥就会导致初始化失败。

使用RSA密钥对(PKCS1模式)签名及签名恢复(ArkTS)-签名验签开发指导-签名验签-Crypto Architecture Kit(加解密算法框架服务)-安全-系统 - 华为HarmonyOS开发者 (huawei.com)

更多关于HarmonyOS 鸿蒙Next开发涉及到加解密的内容时,是必须要使用真机吗?的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


按文档中对模拟器功能支持的说明加解密在模拟器上是可以跑的。

模拟器功能支持说明 - 安全

建议用文档中示例先跑起来后,再进行修改。

在HarmonyOS鸿蒙Next开发中,涉及到加解密内容时,并不一定必须使用真机。加解密操作可以在模拟器中进行,但模拟器的性能和环境可能与真机有所不同,尤其是在处理硬件相关的加密操作时,模拟器可能无法完全模拟真机的行为。因此,为了确保加解密功能的准确性和性能,建议在开发后期使用真机进行测试和验证。真机能够提供更真实的运行环境和硬件支持,确保加解密操作在实际设备上的正确性和安全性。

在HarmonyOS鸿蒙Next开发中,涉及到加解密的内容并不一定必须使用真机。开发者可以在模拟器上进行初步开发和测试。然而,由于加解密操作通常涉及硬件安全模块(如TEE)和真机特有的安全特性,最终测试和验证建议在真机上进行,以确保功能的完整性和安全性。因此,虽然模拟器可以用于开发,但真机测试是不可或缺的步骤。

回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!