HarmonyOS 鸿蒙Next 国密SM2解密报错,错误码17630001如何解决

发布于 1周前 作者 bupafengyu 最后一次编辑是 5天前 来自 鸿蒙OS

HarmonyOS 鸿蒙Next 国密SM2解密报错,错误码17630001如何解决

【问题现象】

采用国密SM2加密,对加密出来的密文做解密操作报错,错误码。

加密实现代码如下:

export class SM2Util {

private pubKeyStr = ‘4c7945d9c844fa33dd6b9037c0ee6bb2dd5d6cf57a758192f339964be6bbb26dd7d5818cf3ad89d28be29a37f2293c90e3a8dbdfd22d326c504a9c7e7f6b5e41’ private priKeyStr = ‘fa2d69db54fa99a24303f27b285712e500afedd8797e02cb4b170ff5827c8688’

/**

  • 加密 * @param str * @param pubKeyStr * @returns */ async encSM2C1C2C3(str: string, pubKeyStr = this.pubKeyStr) { // 将128位公钥字符串转为PubKey let pubKey = await this.convertStrToPubKey(pubKeyStr) let res = await this.encryptMessagePromise(pubKey, str) let spec: cryptoFramework.SM2CipherTextSpec = cryptoFramework.SM2CryptoUtil.getCipherTextSpec(res, ‘C1C3C2’) let C1 = spec.xCoordinate.toString(16) + spec.yCoordinate.toString(16) let C2 = buffer.from(spec.cipherTextData).toString(‘hex’) let C3 = buffer.from(spec.hashData).toString(‘hex’) return ‘04’ + C1 + C2 + C3 }

/**

  • 将128位公钥字符串转为PubKey * @param keyStr 128位公钥字符串 * @returns PubKey */ private async convertStrToPubKey(pubKeyStr: string): Promise<cryptoFramework.PubKey> { // let pubKeyStr = keyStr.startsWith(“04”) ? keyStr.slice(2) : keyStr let pkPart1 = pubKeyStr.slice(0, pubKeyStr.length / 2) let pkPart2 = pubKeyStr.slice(pubKeyStr.length / 2) let pk: cryptoFramework.Point = { x: BigInt(“0x” + pkPart1), y: BigInt(“0x” + pkPart2), } let pubKeySpec: cryptoFramework.ECCPubKeySpec = { params: cryptoFramework.ECCKeyUtil.genECCCommonParamsSpec(‘NID_sm2’), pk: pk, algName: “SM2”, specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC } let keypairGenerator = cryptoFramework.createAsyKeyGeneratorBySpec(pubKeySpec) return await keypairGenerator.generatePubKey() }

/**

  • 生成Cipher实例,获取加密后的数据。 * @param publicKey * @param plainText * @returns */ private async encryptMessagePromise(publicKey: cryptoFramework.PubKey, plainText: string) { let cipher = cryptoFramework.createCipher(‘SM2_256|SM3’) await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, publicKey, null) let encryptData = await cipher.doFinal({ data: this.stringToUint8Array(plainText) }) return encryptData }

// 字符串转成字节流 private stringToUint8Array(str: string) { return new Uint8Array(buffer.from(str, ‘utf-8’).buffer) } }

【背景知识】

【定位思路】

根据错误码,查询相关信息,可能是加解密算法框架与三方算法库交互时出现错误。但是基于这个还是无法定位具体错误地方。考虑是否是传给三方算法库的参数有问题,最终发现入参的长度有问题,如下:

加密出来的密文长度为单数,不符合SM2规格,所以解密的时候报错。

【解决方案】

国密算法的底层实现是OpenSSL,为了防止数据在拼接的时候被截取到,在返回OpenSSL数据时是直接透传返回的,中间不作任何操作来保证安全性。而OpenSSL底层返回的数据规范是在高位是的情况下默认不显示,针对这种情况需要业务自己实现,即判断返回的密文长度是否为固定的64位长度,不满足的话对高位进行补0即可。

代码示例如下:

async encSM2C1C2C3(str: string, pubKeyStr = this.pubKeyStr) {
    let pubKey = await this.convertStrToPubKey(pubKeyStr)
    let res = await this.encryptMessagePromise(pubKey, str)
    let spec: cryptoFramework.SM2CipherTextSpec = cryptoFramework.SM2CryptoUtil.getCipherTextSpec(res, 'C1C3C2')
    let C1x = spec.xCoordinate.toString(16)
    let C1y = spec.yCoordinate.toString(16)
    if (C1x.length != 64) {
      C1x = '0' + C1x
    }
    if (C1y.length != 64) {
      C1y = '0' + C1y
    }
    let C2 = buffer.from(spec.cipherTextData).toString('hex')
    let C3 = buffer.from(spec.hashData).toString('hex')
    return '04' + C1x + C1y + C2 + C3
  }
1 回复

针对HarmonyOS 鸿蒙Next在国密SM2解密过程中出现的错误码17630001,这通常指示了一个特定的解密问题。错误码本身并未在公开文档中详细列出,但基于一般经验和HarmonyOS的加密框架(CryptoFramework)的使用,可以推断这可能涉及到密钥格式、密文格式不匹配或加密解密过程中的内部错误。

要解决这个问题,可以尝试以下步骤:

  1. 检查密钥格式:确保用于解密的私钥格式正确,且与加密时使用的公钥相匹配。特别是注意密钥是否已正确转换为HarmonyOS所需的格式。
  2. 验证密文格式:确认密文是否按照ASN.1标准进行了序列化。如果不是,需要先将密文转换为正确的格式。
  3. 更新加密框架:确保你使用的CryptoFramework是最新版本,以避免已知的bug或兼容性问题。

如果以上步骤无法解决问题,建议联系HarmonyOS的官方技术支持,或访问HarmonyOS的开发者论坛寻求帮助。如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部