鸿蒙ef_crypto-加密组件-SM2Sync
大家好,本人是oh三方库eftool的作者,针对于最初开始的SM2而言,均采用async/await 方法来操作,广大开发者提问最多的就是可不可以是同步操作,在API12中官方也是听劝的均新增了同步操作,故eftool也紧跟其后,接下来我们进入到eftool的同步加密组件SM2Sync的使用
本示例使用eftool版本为API12的1.2.1-rc.2版本
首选需要引入SM2Sync
import {SM2Sync
} from '@yunkss/eftool'
使用
SM2Sync提供了更加灵活的操作方式
针对于生成秘钥方法,可以传入期望生成秘钥的类型,不传默认生成为base64格式,支持传入basea64/hex
针对于加密后的输出字符串 也支持传入输出字符串类型,支持传入basea64/hex
针对于解密传入的key同样支持传入utf8/base64/hex格式的,其中utf8指的是普通字符串
generateSM2Key 生成秘钥
let key = SM2Sync.generateSM2Key();this.message = key.getDataRow().publicKey;生成的返回对象为eftool中的OutDTO对象,key.getDataRow().publicKey获取生成的公钥,key.getDataRow().privateKey获取生成的私钥,此时生成的秘钥为base64格式的let key = SM2Sync.generateSM2Key('hex');此时生成的秘钥为hex格式
encode 加密
let encode = SM2Sync.encode('测试SM2的加密~~~~',key.getDataRow().publicKey, 'base64');this.message = encode.getDataRow();生成的返回对象为eftool中的OutDTO对象,通过encode.getDataRow()获取加密后的内容,此处的base64表示传入key的类型为base64,支持utf8/base64/hex,加密后的结果不传格式此时默认生成的为base64格式let encode = SM2Sync.encode('测试SM2的加密~~~~',key.getDataRow().publicKey, 'base64', 'hex');此时'base64', 'hex'表示传入秘钥key的格式为base64,期望加密后的输出格式为hex,支持hex/base64
decode 解密
let decode = SM2Sync.decode(encode.getDataRow(),key.getDataRow().privateKey, 'base64');this.message = decode.getDataRow();生成的返回对象为eftool中的OutDTO对象,通过decode.getDataRow()获取解密后的内容,此处的base64表示传入key的类型为base64,支持utf8/base64/hex,待解密的结果不传格式此时默认为base64格式,支持hex/base64let decode = SM2Sync.decode(encode.getDataRow(),key.getDataRow().privateKey, 'base64', 'hex');此时'base64', 'hex'表示传入秘钥key的格式为base64,待解密字符串格式为hex,支持hex/base64
sign 签名
let sign = SM2Sync.sign('测试SM2的加密~~~~',key.getDataRow().privateKey, 'base64');this.message = sign.getDataRow();生成的返回对象为eftool中的OutDTO对象,通过sign.getDataRow()获签名的结果,此处的base64表示传入key的类型为base64,支持utf8/base64/hex,签名的结果不传格式此时默认为base64格式,支持hex/base64
verify 验签
let verify = SM2Sync.verify(sign.getDataRow(), '测试SM2的加密~~~~',key.getDataRow().publicKey, 'base64');this.message = verify.getMsg();生成的返回对象为eftool中的OutDTO对象,通过verify.getMsg()获取验签的结果,此处的base64表示传入key的类型为base64,支持utf8/base64/hex,待验签的字符串不传格式此时默认为base64格式,支持hex/base64
注意,目前服务器端大多数SM2的秘钥都是04开头标准密文GM/T0003.4格式即C1C3C2格式的,而鸿蒙生成的是ASN1格式,故需要进行格式转换,如下提供了公私钥转换方法
convertSM2PubKey 将服务器端生成的16进制的长度为130位的04开头的C1C3C2格式的SM2公钥转换为前端所需的ASN1格式公钥字符串
//C1C3C2格式的公钥字符串
let pk = '04ba3bc3c5834d9ad1a7d81c4b49cf1209d2f28e4a97c73b75d6561792a2bfafe811e0284692006b0ce1b51f8aadfd65241d80eb979365048253408f5d705ec17b';//转换后的ASN1格式的字符串
let sm2 = await SM2.convertSM2PubKey(pk);返回对象为eftool中的OutDTO对象,通过sm2.getDataRow()即可获取到转换后的ASN1格式的公钥,接着进行加密即可,此处需要注意转换后的秘钥格式为hex,加解密的key入参格式记得是hex,否则会导致加解密失败let encode = SM2Sync.encode('测试SM2的加密~~~~', sm2.getDataRow(), 'hex');let ddd = encode.getDataRow();
convertSM2PriKey 将服务器端生成的16进制的长度为64位的C1C3C2格式的SM2私钥转换为前端所需的ASN1格式SM2私钥字符串
//C1C3C2格式的私钥字符串
let pik = '7713d336bcbbffb8b7f9cab8db984a5c989a0b07697f569a06d5cd38e1351d07';//转换后的ASN1格式的字符串
let sm2 = await SM2.convertSM2PriKey(pik);返回对象为eftool中的OutDTO对象,通过sm2.getDataRow()即可获取到转换后的ASN1格式的私钥,接着进行解密即可,此处需要注意转换后的秘钥格式为hex,加解密的key入参格式记得是hex,否则会导致加解密失败let decode = SM2Sync.decode(encode.getDataRow(),sm2.getDataRow().privateKey, 'hex');this.message = aaaa.getDataRow();
扩展知识
鸿蒙生成的秘钥以及加解密后的字符串均为ASN1格式的,而目前服务器端的SM2大多数为标准密文GM/T0003.4格式即C1C3C2格式的,故需要将双端加密后的数据进行标准转换
SM2Convert SM2ASN1跟C1C3C2转换类
d2i ASN1格式的字符串转换成C1C3C2格式的字符
//模拟生成key
let key = SM2Sync.generateSM2Key();//加密返回ASN1格式字符串,此处需要注意格式转换时ASN1的字符串格式需要为hex,故加密后生成的加密字符串格式只能为hex
let encode = SM2Sync.encode('测试SM2的加密~~~~',key.getDataRow().publicKey, 'base64','hex');//创建转换类
let convert = new SM2Convert();//转换格式
let result = convert.d2i(encode.getDataRow());返回的result即是转换后的C1C3C2格式的字符串
i2dSM2 C1C3C2格式的字符串转换成ASN1格式的字符
//调用方法
let reConvert = convert.i2dSM2(result);this.msg = reConvert;返回的reConvert即是转换后的ASN1格式的字符串,此处需要注意转换后的ASN1的字符串格式也为hex
