sm2加解密中出现裸密文如何处理以及导入公钥加密和导入私钥解密的方法

对于sm2的导入密钥的处理,sm2不支持裸密文直接导入,遇到此类情况需要转换为另外一种支持裸密文的加解密方式去转换,如:ECC。

HarmonyOS
2024-05-28 21:23:30
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
ssscan

使用的核心API

SM2加解密规格

核心代码解释

初始化即把传入的sm2裸密文传入,然后转换为ECC密钥对或者是公钥/私钥:

async init(): Promise<cryptoFramework.KeyPair | null> { 
​ 
  let publicKey: string = "048dc347c86a9c5f75c38c64ed68cd240298e19512f863ab9fa7b3f3768f4730ef7e08c2374172937f64f81ae9b1ac51d069309da960c14568f964875ed4c2396f"; 
​ 
  //转16进制放入对应的位置 
  let pk: cryptoFramework.Point = { 
    x: BigInt("0x8dc347c86a9c5f75c38c64ed68cd240298e19512f863ab9fa7b3f3768f4730ef"), 
    y: BigInt("0x7e08c2374172937f64f81ae9b1ac51d069309da960c14568f964875ed4c2396f") 
  } 
  let sk: bigint = BigInt("0x6d562d653d74f41bff9c3f2359e5add416a931c44783b9afdf5c3327121c2266"); 
  // 公钥对象参数 
  let pubKey: cryptoFramework.ECCPubKeySpec = { 
    params: this.genSM2CommonSpec(), 
    pk: pk, 
    algName: "ECC", 
    specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC 
  } 
  // 私钥对象数据 
  let priKey: cryptoFramework.ECCPriKeySpec = { 
    params: this.genSM2CommonSpec(), 
    sk: sk, 
    algName: "ECC", 
    specType: cryptoFramework.AsyKeySpecType.PRIVATE_KEY_SPEC 
  } 
  // 密钥对对象数据 
  let keyPair: cryptoFramework.ECCKeyPairSpec = { 
    params: this.genSM2CommonSpec(), 
    sk: sk, 
    pk: pk, 
    algName: 'ECC', 
    specType: cryptoFramework.AsyKeySpecType.KEY_PAIR_SPEC 
  } 
​ 
  let KeyPair: cryptoFramework.KeyPair | null = null; 
  try { 
    let KeyPairGenerator: cryptoFramework.AsyKeyGeneratorBySpec; 
    KeyPairGenerator = cryptoFramework.createAsyKeyGeneratorBySpec(keyPair); 
    KeyPair = await KeyPairGenerator.generateKeyPair() 
      .then((keyPair) => { 
        return keyPair; 
      }) 
      .catch((e: Error): null => { 
        console.log(JSON.stringify(e)) 
        return null; 
      }) 
  } catch (err) { 
    let e: BusinessError = err as BusinessError; 
    console.error(`sync error, ${e.code}, ${e.message}`); 
  } 
  return KeyPair; 
}

把转换后的 密钥对/公钥/私钥 传入执行加解密步骤

async convertKey(keyPair: cryptoFramework.KeyPair) { 
let pubKey = keyPair.pubKey; 
let priKey = keyPair.priKey; 
let pubKeyArr: Uint8Array = pubKey.getEncoded().data; 
console.log("PubKey code : " + baseUtil.uint8ArrayToHexStr(pubKeyArr)); 
console.log("PubKey data : " + baseUtil.base64Encode(pubKeyArr)); 
console.log("================================================================"); 
let pubKeyBlob: cryptoFramework.DataBlob = { data: pubKeyArr }; 
​ 
let priKeyArr: Uint8Array = priKey.getEncoded().data; 
console.log("PriKey code : " + baseUtil.uint8ArrayToHexStr(priKeyArr)); 
console.log("PriKey data : " + baseUtil.base64Encode(priKeyArr)); 
console.log("================================================================"); 
let priKeyBlob: cryptoFramework.DataBlob = { data: priKeyArr }; 
​ 
let cipher = cryptoFramework.createCipher("SM2_256|SM3"); 
let decoder = cryptoFramework.createCipher("SM2_256|SM3"); 
let generator = cryptoFramework.createAsyKeyGenerator("SM2_256"); 
​ 
let keypair: cryptoFramework.KeyPair; 
try { 
  generator.convertKey(pubKeyBlob, priKeyBlob) 
    .then((keyPair) => { 
      keypair = keyPair; 
      console.log("sm2 PubKey base64 : " + baseUtil.base64Encode(keypair.pubKey.getEncoded().data)); 
      console.log("sm2 PubKey data : " + baseUtil.uint8ArrayToHexStr(keypair.pubKey.getEncoded().data)); 
      console.log("sm2 PriKey base64 : " + baseUtil.base64Encode(keypair.priKey.getEncoded().data)); 
      console.log("sm2 PriKey data : " + baseUtil.uint8ArrayToHexStr(keypair.priKey.getEncoded().data)); 
      console.log("================================================================"); 
      return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keypair.pubKey, null); 
    }) 
    .then(() => { 
      // doFinal 
      let input: cryptoFramework.DataBlob = { data: baseUtil.stringToUint8Array("123456") }; 
      return cipher.doFinal(input); 
    }) 
    .then(async dataBlob => { 
      // 获取加密数据。 
      console.info("SM2 EncryptOutPut base64 is " + baseUtil.base64Encode(dataBlob.data)); 
      console.info("SM2 EncryptOutPut hexStr is " + baseUtil.uint8ArrayToHexStr(dataBlob.data)); 
      console.info("SM2 EncryptOutPut primal is " + new SM2_Ciphertext().d2i_SM2_Ciphertext(baseUtil.uint8ArrayToHexStr(dataBlob.data))); 
      console.log("================================================================"); 
      await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keypair.priKey, null); 
      return dataBlob; 
    }) 
    .then(dataBlob => { 
      return decoder.doFinal(dataBlob); 
    }) 
    .then((dataBlob: cryptoFramework.DataBlob) => { 
      console.info("SM2 DecryptOutPut is " + baseUtil.base64Encode(dataBlob.data)); 
      console.info("SM2 DecryptOutPut is " + baseUtil.uint8ArrayToHexStr(dataBlob.data)); 
      console.info("SM2 DecryptOutPut result is " + baseUtil.uint8ArrayToString(dataBlob.data)); 
      AlertDialog.show({ message: "success=>" + baseUtil.uint8ArrayToString(dataBlob.data)}); 
      console.log("================================================================"); 
    }) 
    .catch((e: Error) => { 
      console.log(JSON.stringify(e)); 
    }); 
} catch (err) { 
  let e: BusinessError = err as BusinessError; 
  console.error(`sync error, ${e.code}, ${e.message}`); 
  AlertDialog.show({ message: "Convert keypair fail" }); 
} 
}

上诉是对于密钥对的加解密的代码解释,对于导入公钥加密以及导入私钥解密的代码在附件中,可以参考一下。

实现效果

点击初始化转换密钥,生成sm2密钥对,通过密钥对去做加解密操作,点击导入密钥对及加解密按钮,导入密钥对成功,加解密成功。

适配的版本信息

  • IDE:DevEco Studio 4.1.3.220
  • SDK:HarmoneyOS 4.1.2.1
分享
微博
QQ
微信
回复
2024-05-29 22:32:19
相关问题
如何使用国SM2算法进行加解密
865浏览 • 1回复 待解决
RSA导入外部密钥实现加解密
359浏览 • 1回复 待解决
多种加密方式实现加解密
416浏览 • 1回复 待解决
如何使用SM4CBC模式加解密
177浏览 • 1回复 待解决
SM4采用OFB模式进行加解密
310浏览 • 1回复 待解决
使用32字节秘加解密后报错
467浏览 • 1回复 待解决
SM4 CBC模式加解密,有好方案吗?
449浏览 • 1回复 待解决
如何实现RSAPK加密一段文字
147浏览 • 1回复 待解决
如何进行不同规格AES加解密
210浏览 • 1回复 待解决
加解密算法库框架使用
452浏览 • 1回复 待解决
基于加解密算法框架规格问题
201浏览 • 1回复 待解决