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

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

HarmonyOS
2024-05-28 21:23:30
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
走在河边捡到鱼

使用的核心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算法进行加解密
3282浏览 • 1回复 待解决
HarmonyOS Sm2DES加解密问题
302浏览 • 1回复 待解决
HarmonyOS SM2SM4国加解密使用demo
100浏览 • 1回复 待解决
RSA导入外部密钥实现加解密
696浏览 • 1回复 待解决
HarmonyOS RSA如何解密
459浏览 • 0回复 待解决
多种加密方式实现加解密
916浏览 • 1回复 待解决
HarmonyOS 支持rsa使用解密
374浏览 • 1回复 待解决
rsa 解密初始化报错
87浏览 • 1回复 待解决
如何使用SM4CBC模式加解密
754浏览 • 1回复 待解决