sm2加解密和签名验签
先看看官网文档怎么说:SM2为非对称加密算法,加密长度需要在固定长度进行。算法库目前支持以GM/T 0009-2012定义的格式加密或解密数据。SM2非对称加密的结果由C1、C2、C3三部分组成。其中C1是根据生成的随机数计算出的椭圆曲线点,C2是密文数据,C3是通过指定的摘要算法计算的值。当前支持以字符串参数完成SM2加解密,具体的“字符串参数”由“非对称密钥类型(加解密算法+密钥长度)”、“摘要算法”使用符号“|”拼接而成,用于在创建非对称加解密实例时,指定算法规格。
不过SM2原理上是不支持分段的,但是文档提到当数据量较大时,可以多次调用doFinal,即分段加解密。 文档只是提了一嘴说可以多次调用doFinal来实现分段加密,没有给出SM2的分段加解密的demo,我尝试了在解密的时候并不能解出正确的结果。
以下是SM2的加解密示例:
function encryptFunc(){let cipher = cryptoFramework.createCipher("SM2_256|SM3");let encoder = util.TextEncoder.create("utf-8");let pubBlob: Uint8Array = new Uint8Array();pubBlob = encoder.encodeInto(this.encryptStr);let keyGenerator = cryptoFramework.createAsyKeyGenerator("SM2_256");this.keyPair = keyGenerator.generateKeyPairSync();let pubKey = this.keyPair.pubKey;cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null); //非对称密钥无加密参数,直接传入null。let pubDataBlob: cryptoFramework.DataBlob = {data: pubBlob}this.encryptData = cipher.doFinalSync(pubDataBlob)}function decryptFunc(){let decoder = cryptoFramework.createCipher('SM2_256|SM3');decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, this.keyPair?.priKey, null);let str = decoder.doFinalSync(this.encryptData)let decoderText = new util.TextDecoder();this.showRes = decoderText.decodeToString(str.data);}
注意:这里的cipher在加密和解密的过程也是需要重新创建的,不能用同一个。对于SM2都是用来和SM4混合使用,SM4加密明文,然后SM2加密SM4的密钥。
简单说完SM2的加密解密,再说说SM2的另一个常见用法:签名和验签。
先看看文档怎么说:
SM2数字签名算法,是基于椭圆曲线的签名验签算法。
以字符串参数完成SM2签名验签,具体的“字符串参数”由“非对称密钥类型”和“摘要”使用符号“|”拼接而成,用于在创建非对称签名验签实例时,指定非对称签名验签算法规格。
来看看例子:
let signerGenerator = cryptoFramework.createAsyKeyGenerator("SM2_256");this.VKeyPair = signerGenerator.generateKeyPairSync();const signer = cryptoFramework.createSign("SM2_256|SM3");signer.initSync(this.VKeyPair.priKey);let textEncoder = new util.TextEncoder("utf-8");this.VOrencoderData = textEncoder.encodeInto(this.encryptStr);const blockSize = 128;for (let i = 0; i < this.VOrencoderData.length; i+=blockSize) {let perData = this.VOrencoderData.subarray(i,i+blockSize);signer.updateSync({data:perData})}let finalData = signer.signSync(null);this.VData = finalData.data;const verify = cryptoFramework.createVerify("SM2_256|SM3");verify.initSync(this.VKeyPair?.pubKey);const blockSize = 128;for (let i = 0; i < this.VOrencoderData.length; i+=blockSize) {const perData = this.VOrencoderData.subarray(i,i+blockSize);verify.updateSync({data:perData})}let res = verify.verifySync(null,{data:this.VData})
签名验签的过程就像签名:一开始你加密了一个东西,验签的时候我再对有明文加密一遍。再去对比这两次解密的结果是不是一样的。这个类比不一定恰当,但是这么想就能理解为什么在验签是要使用明文重新update/verify了。过程还是简单的。
o了,除了SM2分段加解密没整明白,其他都还行,期望有大佬评论区讲一下SM2能不能,怎么做分段加解密。
版权保护: 本文由 绿茶加糖-郭保升 原创,转载请保留链接: https://www.guobaosheng.com/tuijian/2025/0711/366.html
