HarmonyOS 如何进行SM2key的初始化

已有信息:

publicKeyXHex =E2F5F400F7B71BAD5596BB7D6048DAAE133F34DF3A65F6C3167B50DD295C2A8F
publicKeyYHex =A76B771B857E5881A54F45FE4D19B4815B021E69371E1BBB3CFA6D594A535181

根据文档:

// 生成SM2密钥对
async function genKeyPairByData(pubKeyData: Uint8Array, priKeyData: Uint8Array) {
  let pubKeyBlob: cryptoFramework.DataBlob = { data: pubKeyData };
  let priKeyBlob: cryptoFramework.DataBlob = { data: priKeyData };
  let sm2Generator = cryptoFramework.createAsyKeyGenerator('SM2_256');
  let keyPair = await sm2Generator.convertKey(pubKeyBlob, priKeyBlob);
  console.info('convertKey success');
  return keyPair;
}

其中必须在初始化KeyPair中要传入公钥和私钥,目前SM2加密只有公钥,没有私钥如何进行初始化?

HarmonyOS
1天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zbw_apple

HarmonyOS 端加密,java端解密的话是不需要私钥的,只需要传入已有的十六进制公钥,使用以下demo 代码实例即可

import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer, util } from '@kit.ArkTS';
import { hilog } from '@kit.PerformanceAnalysisKit';

// 加密消息
async function encryptMessagePromise(publicKey: cryptoFramework.PubKey, plainText: cryptoFramework.DataBlob) {
  //密钥类型为SM2_256、摘要算法为SM3的Cipher
  let cipher = cryptoFramework.createCipher('SM2_256|SM3');
  await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, publicKey, null);
  let encryptData = await cipher.doFinal(plainText);
  return encryptData;
}

export async function convertStrToPubKey(keyStr: string): Promise<cryptoFramework.PubKey> {
  let pubKeyStr = keyStr.startsWith("04") ? keyStr.slice(2) : keyStr
  let pkPart1 = pubKeyStr.slice(0, pubKeyStr.length / 2)
  let pkPart2 = pubKeyStr.slice(pubKeyStr.length / 2)
  let pk: cryptoFramework.Point = {
    x: BigInt("0x" + pkPart1),
    y: BigInt("0x" + pkPart2),
  }
  let pubKeySpec: cryptoFramework.ECCPubKeySpec = {
    params: cryptoFramework.ECCKeyUtil.genECCCommonParamsSpec('NID_sm2'),
    pk: pk,
    algName: "SM2",
    specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC
  }
  let keypairGenerator = cryptoFramework.createAsyKeyGeneratorBySpec(pubKeySpec)
  return await keypairGenerator.generatePubKey()
}

async function main() {
  let base64 = new util.Base64Helper();
  //十六进制的公私钥
  let pubKeyStr = "十六进制的公私钥"

  //base64的公私钥 需要转成十六进制公钥
  let pubKeyStr2 = "base64的公私钥"
  let u8aP = base64.decodeSync(pubKeyStr2)
  console.error('Uint8Array u8aP result string:' + u8aP);
  let buf = buffer.from(u8aP);
  console.log('hex u8aP result string:' + buf.toString('hex'));
  let hexpubKeyStr ="十六进制公钥"

  let pubKey = await convertStrToPubKey(hexpubKeyStr)
  // let priKey = await convertStrToPriKey(priKeyStr)

  // 此处为明文
  let message = 'thisistes';
  // 把字符串按utf-8解码为Uint8Array
  let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
  let encryptText = await encryptMessagePromise(pubKey, plainText);
  console.error("encryptText=======>" + buffer.from(encryptText.data).toString('hex'))

  //reslut 是加密后的密文数据
  let spec: cryptoFramework.SM2CipherTextSpec = cryptoFramework.SM2CryptoUtil.getCipherTextSpec(encryptText, 'C1C2C3');
  /*
  * C1 = spec.xCoordinate.toString(16) + spec.yCoordinate.toString(16)
  * C2 = buffer.from(spec.cipherTextData).toString('hex')
  * C3 = buffer.from(spec.hashData).toString('hex')
  * */
  let str = "04" + spec.xCoordinate.toString(16) + spec.yCoordinate.toString(16) + buffer.from(spec.cipherTextData).toString('hex') + buffer.from(spec.hashData).toString('hex')
  console.error("C1C2C3解码后16进制数据=======>" + str)

  let Base64Str = base64.encodeToStringSync(new Uint8Array(buffer.from(str, 'hex').buffer))
  console.error("C1C2C3解码后数据Base64Str=======>" + Base64Str)
}

@Entry
@Component
struct SM2Crypto {
  @State message: string = '点击开始';

  build() {
    Row() {
      Column() {
        Text(this.message)
          .fontSize(50)
          .fontWeight(FontWeight.Bold)
          .onClick(() => {
            main();
          })
      }
      .width('100%')
    }
    .height('100%')
  }
}

以上为c1c2c3 的解密模式

c1c3c2 的方式为

//reslut 是加密后的密文数据
let spec: cryptoFramework.SM2CipherTextSpec = cryptoFramework.SM2CryptoUtil.getCipherTextSpec(encryptText, 'C1C2C3');
/*
* C1 = spec.xCoordinate.toString(16) + spec.yCoordinate.toString(16)
* C2 = buffer.from(spec.cipherTextData).toString('hex')
* C3 = buffer.from(spec.hashData).toString('hex')
* */
let str = "04" + spec.xCoordinate.toString(16) + spec.yCoordinate.toString(16) + buffer.from(spec.hashData).toString('hex') + buffer.from(spec.cipherTextData).toString('hex')
console.error("C1C2C3解码后16进制数据=======>" + str)

let Base64Str = base64.encodeToStringSync(new Uint8Array(buffer.from(str, 'hex').buffer))
console.error("C1C2C3解码后数据Base64Str=======>" + Base64Str)
分享
微博
QQ
微信
回复
1天前
相关问题
HarmonyOS 如何进行全局初始化操作
49浏览 • 1回复 待解决
HarmonyOS XComponent初始化
109浏览 • 1回复 待解决
HarmonyOS struct初始化方法
75浏览 • 1回复 待解决
HarmonyOS Component初始化问题
487浏览 • 1回复 待解决
HarmonyOS export struct初始化参数
70浏览 • 1回复 待解决
初始化安全相机方法
429浏览 • 1回复 待解决
HarmonyOS泛型类属性如何初始化
481浏览 • 1回复 待解决
HarmonyOS 应用RDB初始化示例
444浏览 • 1回复 待解决
没法调试“已初始化”分支
269浏览 • 1回复 待解决
HarmonyOS 怎么监听Web初始化完成?
64浏览 • 1回复 待解决
如何初始化OceanBase服务器环境?
3716浏览 • 1回复 待解决
是否提供提前初始化webview能力
2381浏览 • 1回复 待解决