HarmonyOS 鸿蒙Next中国密SM2解密报错,错误码17630001如何解决
HarmonyOS 鸿蒙Next中国密SM2解密报错,错误码17630001如何解决
【问题现象】
采用国密SM2加密,对加密出来的密文做解密操作报错,错误码17630001。
加密实现代码如下:
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算法规格:SM2为非对称加密算法,加密长度需要在固定长度进行。
- 使用SM2非对称密钥加解密开发指导。
【定位思路】
根据错误码,查询相关信息,可能是加解密算法框架与三方算法库交互时出现错误。但是基于这个还是无法定位具体错误地方。考虑是否是传给三方算法库的参数有问题,最终发现入参的长度有问题,如下:
加密出来的密文长度为单数,不符合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
}
更多关于HarmonyOS 鸿蒙Next中国密SM2解密报错,错误码17630001如何解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS 鸿蒙Next中国密SM2解密报错,错误码17630001如何解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中使用中国密SM2解密时,报错17630001通常与密钥格式或数据输入不匹配有关
SM2解密要求密钥和数据符合特定格式,错误码17630001表示解密过程中遇到格式问题。
首先,确保使用的私钥是有效的SM2私钥,且格式正确。SM2私钥通常为DER或PEM格式,需符合国密标准。其次,检查待解密的数据是否为有效的SM2加密数据,数据格式需与加密时一致。
如果密钥和数据格式无误,检查解密函数的参数是否正确传递。确保密钥、密文和其他参数(如IV或填充模式)正确设置。
最后,确认使用的鸿蒙版本和SM2库是否支持当前的解密操作。某些版本可能存在兼容性问题,建议查阅相关文档或更新到最新版本。
若问题仍未解决,可尝试使用其他SM2工具或库进行解密,以排除环境或实现问题。