欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > ArkTS中SM2加解密

ArkTS中SM2加解密

2025/2/5 14:41:14 来源:https://blog.csdn.net/guoxulieying/article/details/143618961  浏览:    关键词:ArkTS中SM2加解密

文章目录

  • 一、简介
  • 二、生成随机密钥对
  • 三、加密方法
  • 四、解密方法

一、简介

SM2是国密加解密方法,在官方文档中有介绍,因使用中发现系统的方法有对应的格式,在这里对使用方法做出说明。

二、生成随机密钥对

因生成的密钥对,数据前方有格式头描述,所以从26位开始截取,这里是密钥的数据。

/** 生成SM2临时密钥对 */public generateSM2Key(): string {if (this.pubKey != undefined) {return this.pubKey;}// 创建一个AsyKeyGenerator实例let sm2Generator = cryptoFramework.createAsyKeyGenerator('SM2_256');// 使用密钥生成器随机生成非对称密钥对let keyPair = sm2Generator.generateKeyPairSync();let pubKey = keyPair.pubKey;this.priKey = keyPair.priKey;// 获取非对称密钥对的二进制数据let pkBlob = pubKey.getEncoded();let skBlob = this.priKey.getEncoded();DKLogger.info("生成的临时密钥" + buffer.from(pkBlob.data).toString('hex'));DKLogger.info("生成的临时密钥" + buffer.from(skBlob.data).toString('hex'));let base64 = new util.Base64Helper();let base64Str = base64.encodeToStringSync(pkBlob.data.slice(26));this.pubKey = base64Str;return base64Str;}

三、加密方法

···
/** 加密方法 */
public encryptSM2(publicKey: cryptoFramework.PubKey, plainText: cryptoFramework.DataBlob): string | undefined {
let cipher = cryptoFramework.createCipher(‘SM2_256|SM3’);
cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, publicKey, null);
let encryptData = cipher.doFinalSync(plainText);
let base64 = new util.Base64Helper();
let base64Str = base64.encodeToStringSync(encryptData.data);
return base64Str;
}
···

四、解密方法

/** 解密方法 */public decryptSM2(cipherText: string): Uint8Array| undefined {let base64 = new util.Base64Helper();let cipherData = base64.decodeSync(cipherText)// DKLogger.info("密文" + buffer.from(cipherData).toString('hex'))// 用于将SM2裸密文数据序列化let hexStr = this.i2d_SM2_Ciphertext(buffer.from(cipherData).toString('hex'))// hex转Uint8Arraylet encryptedArray = hexStr2Uint8Array(hexStr)// DKLogger.info("密文" + hexStr)let decoder = cryptoFramework.createCipher('SM2_256|SM3');decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, this.priKey, null);let specData: cryptoFramework.DataBlob = { data: encryptedArray};try {let decryptData = decoder.doFinalSync(specData);return decryptData.data;} catch (err) {DKLogger.error("errCode:" + err.code + ",errMessage:" + err.message);return undefined}}

因为Java加密的结果是普通数据没有前缀描述,这里做了一下转换

/*** 用于将SM2裸密文数据序列化* @param primal_data SM2裸密文数据,长度为96+明文长度(字节),输入格式为C1C3C2的Hex字符串* @returns 返回序列化后的标准密文数据,输出格式为Hex字符串*/private i2d_SM2_Ciphertext(primal_data: string): string {let sm2_sequence = new SM2_SEQUENCE();sm2_sequence.C1x = primal_data.slice(2, 66);primal_data = primal_data.slice(66, primal_data.length);sm2_sequence.C1y = primal_data.slice(0, 64);primal_data = primal_data.slice(64, primal_data.length);sm2_sequence.C3 = primal_data.slice(0, 64);primal_data = primal_data.slice(64, primal_data.length);sm2_sequence.C2 = primal_data;let C1x_title: string = (Number.parseInt("0x" + sm2_sequence.C1x.slice(0, 2)) > 127) ? "022100" : "0220";let C1y_title: string = (Number.parseInt("0x" + sm2_sequence.C1y.slice(0, 2)) > 127) ? "022100" : "0220";let C3_title: string = "0420";let C2_title: string = "04" + this.genLenHex(sm2_sequence.C2);let sequence_message: string = C1x_title + sm2_sequence.C1x + C1y_title + sm2_sequence.C1y + C3_title + sm2_sequence.C3 + C2_title + sm2_sequence.C2;let sequence_lenHex: string = this.genLenHex(sequence_message);let standard_data = "30" + sequence_lenHex + sequence_message;return standard_data;}  
// 生成传入内容的长度域private genLenHex(content: string): string {let size: number = content.length / 2;let lenHex: string;if (size.toString(16).length % 2 == 1) {lenHex = '0' + size.toString(16);} else {lenHex = size.toString(16);}if (size < 0x80) {return lenHex;}let lenHex_size: number = lenHex.length / 2;return (lenHex_size | 0x80).toString(16) + lenHex;}
class SM2_SEQUENCE{private _C1x: string = "";private _C1y: string = "";private _C2: string = "";private _C3: string = "";public set C1x(value: string) {this._C1x = value;}public get C1x(): string {return this._C1x;}public set C1y(value: string) {this._C1y = value;}public get C1y(): string {return this._C1y;}public set C2(value: string) {this._C2 = value;}public get C2(): string {return this._C2;}public set C3(value: string) {this._C3 = value;}public get C3(): string {return this._C3;}public toString():string{return JSON.stringify(this);}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com