HarmonyOS鸿蒙Next中使用SM2密钥对签名验签失败如何解决
HarmonyOS鸿蒙Next中使用SM2密钥对签名验签失败如何解决
【问题现象】
使用HarmonyOS的SM2签名的字符串,在Android端进行验签,无法通过。
HarmonyOS端base64之后的签名结果:
MEUCIAYuGY8ZtvJEMn5d81rF1e8TFcGNWKmZ+/YK0VsSreVnAiEAr94jJmpI5nvJPUhFYnddAlF071kFwbJpN0q5++HDa8w=
// Android端验签失败
var byte2 = Base64.decode("MEUCIAYuGY8ZtvJEMn5d81rF1e8TFcGNWKmZ+/YK0VsSreVnAiEAr94jJmpI5nvJPUhFYnddAlF071kFwbJpN0q5++HDa8w=", 2)
val vs = SM2Utils.verifySign( // 验签失败
joininstidStr.toByteArray(charset("utf-8")),
Util.hexToByte(BuildConfig.SM_PUBKEY),
StringUtil.hexStringToBytes(strForSignSha1),
StringUtil.hexStringToBytes(StringTool.bytesToHexString(byte2) )
)
【定位思路】
因为HarmonyOS签名后的结果与Android签名后的结果有差异,调用uint8ArrayToHexStr
转化后,HarmonyOS和Android的签名结果一致。
【背景知识】
SM2数字签名算法,是基于椭圆曲线的签名验签算法。
以字符串参数完成SM2签名验签,具体的“字符串参数”由“非对称密钥类型”和“摘要”使用符号“|”拼接而成,用于在创建非对称签名验签实例时,指定非对称签名验签算法规格。
参考材料
【解决方案】
签名后需要用uint8ArrayToHexStr
方法将其转换为十六进制,再传入d2i_SM2_SignText
方法进行数据预处理,最后返回预处理后的数据。
数据转十六进制
// Uint8Array转十六进制
function uint8ArrayToHexStr(data: Uint8Array): string {
let hexString = "";
let i: number;
for (i = 0; i < data.length; i++) {
let char = ('00' + data[i].toString(16)).slice(-2);
hexString += char;
}
return hexString;
}
签名数据预处理
/*
* 返回预处理后的数据
**/
d2i_SM2_SignText(standard_data: string): string {
let randNum: string = "";
let signText: string = "";
let message = standard_data.slice("30".length, standard_data.length);
let sequence_lenHex: string = this.getLenHex(message);
message = message.slice(sequence_lenHex.length, message.length);
try {
let randNum_len: string = message.slice(0, 4);
if (randNum_len == "0220") {
randNum = message.slice(4, 4 + 64);
message = message.slice(4 + 64, message.length);
} else {
randNum = message.slice(6, 6 + 64);
message = message.slice(6 + 64, message.length);
}
let signText_len: string = message.slice(0, 4);
if (signText_len == "0220") {
signText = message.slice(4, 4 + 64);
} else {
signText = message.slice(6, 6 + 64);
}
} catch (e) {
hilog.error(0x1, "d2i_SM2_SignText", "SignText format is err");
}
return randNum + signText;
}
// 辅助函数:提取长度域的Hex字符串
getLenHex(data: string): string {
let byte: number = Number.parseInt("0x" + data.slice(0, 2));
let len_size: number = byte > 127 ? byte - 0x80 + 1 : 1;
return data.slice(0, len_size * 2);
}
更多关于HarmonyOS鸿蒙Next中使用SM2密钥对签名验签失败如何解决的实战教程也可以访问 https://www.itying.com/category-93-b0.html
更多关于HarmonyOS鸿蒙Next中使用SM2密钥对签名验签失败如何解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中使用SM2密钥对进行签名和验签时,如果遇到失败,可能是以下原因之一:
-
密钥对不匹配:确保使用的公钥和私钥是同一对。如果密钥对不匹配,验签将失败。
-
数据格式问题:检查待签名数据的格式是否正确。SM2签名算法对输入数据格式有特定要求,确保数据符合规范。
-
算法参数配置错误:SM2算法需要正确配置参数,如椭圆曲线参数、哈希算法等。确认这些参数配置正确无误。
-
编码问题:签名和验签过程中可能涉及数据的编码和解码。确保在签名和验签时使用相同的编码方式,如Base64或Hex。
-
库版本兼容性:检查使用的鸿蒙SDK或相关库的版本是否支持SM2算法。某些旧版本可能不支持或存在bug。
-
硬件支持:如果使用硬件安全模块(HSM)或安全芯片进行签名和验签,确保硬件支持SM2算法,并且驱动程序配置正确。
-
调试日志:查看调试日志,获取更多错误信息。日志中可能包含具体的失败原因,如参数错误、内存不足等。
-
示例代码参考:参考鸿蒙官方提供的SM2签名和验签示例代码,确保实现逻辑与官方推荐一致。
通过以上步骤排查问题,可以有效解决HarmonyOS鸿蒙Next中使用SM2密钥对签名验签失败的情况。