HUKS的SM2签名验签的算法规格及开发步骤

1.首先指定密钥别名,初始化密钥属性集,调用generateKeyItem生成密钥,具体请参考密钥生成介绍及算法规格

2.获取密钥别名。指定待签名的明文数据。获取属性参数HuksOptions,包括两个字段properties和inData。inData传入明文数据,properties传入算法参数配置。调用initSession初始化密钥会话,并获取会话的句柄handle。调用finishSession结束密钥会话,获取签名signature。

3.获取密钥别名。获取待验证的签名signature。获取属性参数HuksOptions,包括两个字段properties和inData。

inData传入签名signature,properties传入算法参数配置。调用initSession初始化密钥会话,并获取会话的句柄handle。调用updateSession更新密钥会话。调用finishSession结束密钥会话,验证签名。


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

使用的核心API

签名验签算法规格

签名验签开发步骤

核心代码解释

核心代码如下:

import huks from '@ohos.security.huks'; 
import promptAction from '@ohos.promptAction'; 
import buffer from '@ohos.buffer'; 
import util from '@ohos.util'; 
import { BusinessError } from '@ohos.base'; 
  
  
let KeyAlias = 'KeyAlias'; 
let handle: number; 
let plainText = 'aaaaaaabbbbbbbbbjghjghfg'; 
let cipherData: Uint8Array; 
let signature: Uint8Array; 
  
// 字符串转成字节流 
function stringToUint8Array(str: string) { 
  return new Uint8Array(buffer.from(str,'utf-8').buffer); 
} 
// 字节流转成可理解的字符串 
function uint8ArrayToString(array: Uint8Array) { 
  // 将UTF-8编码转换成Unicode编码 
  let out: string = ""; 
  let index: number = 0; 
  let len: number = array.length; 
  while (index < len) { 
    let character = array[index++]; 
    switch (character >> 4) { 
      case 0: 
      case 1: 
      case 2: 
      case 3: 
      case 4: 
      case 5: 
      case 6: 
      case 7: 
        out += String.fromCharCode(character); 
        break; 
      case 12: 
      case 13: 
        out += String.fromCharCode(((character & 0x1F) << 6) | (array[index++] & 0x3F)); 
        break; 
      case 14: 
        out += String.fromCharCode(((character & 0x0F) << 12) | ((array[index++] & 0x3F) << 6) | ((array[index++] & 0x3F) << 0)); 
        break; 
      default: 
        break; 
    } 
  } 
  return out; 
} 
const TAG='Test--'; 
//生成RSA密钥属性信息 
function GetSm2GenerateProperties() { 
  let properties: Array<huks.HuksParam> = new Array(); 
  let index = 0; 
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 
    value: huks.HuksKeyAlg.HUKS_ALG_SM2 
  }; 
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 
    value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256 
  }; 
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_PURPOSE, 
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN | 
    huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY 
  } 
  return properties; 
} 
  
//RSA加密密钥属性信息 
function GetSm2EncryptProperties() { 
  let properties: Array<huks.HuksParam> = new Array(); 
  let index = 0; 
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 
    value: huks.HuksKeyAlg.HUKS_ALG_SM2 
  }; 
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 
    value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256 
  }; 
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_PURPOSE, 
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_SIGN 
  } 
  
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_PADDING, 
    value: huks.HuksKeyPadding.HUKS_PADDING_NONE 
  } 
  
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_DIGEST, 
    value: huks.HuksKeyDigest.HUKS_DIGEST_SM3 
  } 
  
  return properties; 
} 
  
//RSA解密密钥属性信息 
function GetSm2DecryptProperties() { 
  let properties: Array<huks.HuksParam> = new Array(); 
  let index = 0; 
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_ALGORITHM, 
    value: huks.HuksKeyAlg.HUKS_ALG_SM2 
  }; 
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_KEY_SIZE, 
    value: huks.HuksKeySize.HUKS_SM2_KEY_SIZE_256 
  }; 
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_PURPOSE, 
    value: huks.HuksKeyPurpose.HUKS_KEY_PURPOSE_VERIFY 
  } 
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_PADDING, 
    value: huks.HuksKeyPadding.HUKS_PADDING_NONE 
  } 
  properties[index++] = { 
    tag: huks.HuksTag.HUKS_TAG_DIGEST, 
    value: huks.HuksKeyDigest.HUKS_DIGEST_SM3 
  } 
  return properties; 
} 
async function GenerateEccKey(keyAlias: string) { 
  let genProperties = GetSm2GenerateProperties(); 
  let options: huks.HuksOptions = { 
    properties: genProperties 
  } 
  await huks.generateKeyItem(keyAlias, options) 
    .then((data) => { 
      promptAction.showToast({ 
        message: "成功生成了一个别名为:"+ keyAlias + " 的密钥" , 
        duration: 2500, 
      }) 
    }).catch((err:BusinessError)=>{ 
      promptAction.showToast({ 
        message: "密钥生成失败,错误码是: " + err.code + " 错误吗信息: " + err.message, 
        duration: 6500, 
      }) 
    }) 
} 
async function Sign(keyAlias: string, plaintext: string) { 
  if (stringToUint8Array(plaintext) == null) { 
    promptAction.showToast({ 
      message: "签名验签数据为空,无法执行签名验签操作!", 
      duration: 6500, 
    }) 
    return; 
  } 
  let signProperties = GetSm2EncryptProperties(); 
  let options: huks.HuksOptions = { 
    properties: signProperties, 
    inData: stringToUint8Array(plaintext) 
  } 
  
  await huks.initSession(keyAlias, options) 
    .then((data) => { 
      handle = data.handle; 
    }).catch((err:BusinessError)=>{ 
      promptAction.showToast({ 
        message: "密钥初始化失败,错误码是: " + err.code + " 错误吗信息: " + err.message, 
        duration: 6500, 
      }) 
    }) 
  await huks.finishSession(handle, options) 
    .then((data) => { 
      promptAction.showToast({ 
        message: "验签完成, 验签结果是: " + uint8ArrayToString(data.outData), 
        duration: 6500, 
      }) 
      //signature = data.outData as Uint8Array; 
      signature = data.outData as Uint8Array; 
      console.log("test---signature"+signature) 
    }).catch((err:BusinessError)=>{ 
      promptAction.showToast({ 
        message: "签名验签finish阶段捕获了异常,错误码是: " + err.code + " 错误码信息: " + err.message, 
        duration: 6500, 
      }) 
    }) 
} 
async function Verify(keyAlias: string, signature: Uint8Array, plaintext: string) { 
  if (signature == null) { 
    promptAction.showToast({ 
      message: "签名验签数据为空,无法执行签名验签操作!", 
      duration: 6500, 
    }) 
    return; 
  } 
  let verifyProperties = GetSm2DecryptProperties() 
  let options: huks.HuksOptions = { 
    properties: verifyProperties, 
    inData: stringToUint8Array(plaintext) 
  } 
  await huks.initSession(keyAlias, options) 
    .then((data) => { 
      handle = data.handle; 
    }).catch((err:BusinessError)=>{ 
      promptAction.showToast({ 
        message: "密钥初始化失败,错误码是: " + err.code + " 错误吗信息: " + err.message, 
        duration: 6500, 
      }) 
    }) 
  await huks.updateSession(handle, options) 
    .then((data) => { 
      //console.info(`promise: update verify success, data is ` + uint8ArrayToString(data.outData as Uint8Array)); 
    }).catch((err:BusinessError)=>{ 
      promptAction.showToast({ 
        message: "验签update过程错误,错误码是: " + err.code + " 错误吗信息: " + err.message, 
        duration: 6500, 
      }) 
    }) 
  options.inData = signature 
  await huks.finishSession(handle, options) 
    .then((data) => { 
      promptAction.showToast({ 
        message: "验签通过", 
        duration: 6500, 
      }) 
    }).catch((err:BusinessError)=>{ 
      promptAction.showToast({ 
        message: "签名验签finish阶段捕获了异常,错误码是: " + err.code + " 错误码信息: " + err.message, 
        duration: 6500, 
      }) 
    }) 
} 
  
async function DeleteEccKey(keyAlias: string) { 
  let emptyOptions: huks.HuksOptions = { 
    properties: [] 
  } 
  await huks.deleteKeyItem(keyAlias, emptyOptions) 
    .then((data) => { 
      console.info(`promise: delete data success`); 
    }).catch((err:BusinessError)=>{ 
      console.error(`promise: delete data failed`); 
    }) 
} 
  
async function exportPuk(){ 
  let emptyOptions: huks.HuksOptions = { 
    properties: [] 
  }; 
  try { 
    huks.exportKeyItem(KeyAlias, emptyOptions, (error, data) => { 
      if (error) { 
        console.error(`test---callback: exportKeyItem failed`); 
      } else { 
        let base64=new util.Base64Helper 
        let pukBase=base64.encodeToStringSync(data.outData) 
        console.info(`test---callback: exportKeyItem success, data = ${JSON.stringify(data)}`,pukBase); 
      } 
    }); 
  } catch (error) { 
    console.error(`callback: exportKeyItem input arg invalid`); 
  } 
} 
  
  
  
@Entry 
@Component 
struct Index { 
  @State message: string = 'Hello Huks' 
  controller: TextInputController = new TextInputController(); 
  build() { 
    Column() { 
      Row() { 
        Button({ type: ButtonType.Normal, stateEffect: true }) { 
          Text('GenerateKey') 
            .fontColor(Color.White) 
            .fontSize(20) 
        } 
        .borderRadius(8) 
        .width('45%') 
        .height('5%') 
        .backgroundColor(0x317aff) 
        .onClick(async () => { 
          let str=stringToUint8Array(plainText) 
          console.log("test---str"+str) 
          await GenerateEccKey(KeyAlias); 
          await exportPuk(); 
        }) 
        .margin(10) 
  
        Button({ type: ButtonType.Normal, stateEffect: true }) { 
          Text('SignKey') 
            .fontColor(Color.White) 
            .fontSize(20) 
        } 
        .borderRadius(8) 
        .width('45%') 
        .height('5%') 
        .backgroundColor(0x317aff) 
        .onClick(() => { 
          Sign(KeyAlias,plainText); 
        }) 
        .margin(10) 
      } 
  
      Row() { 
        Button({ type: ButtonType.Normal, stateEffect: true }) { 
          Text('VerifyKey') 
            .fontColor(Color.White) 
            .fontSize(20) 
        } 
        .borderRadius(8) 
        .width('45%') 
        .height('5%') 
        .backgroundColor(0x317aff) 
        .onClick(() => { 
          Verify(KeyAlias,signature,plainText); 
        }) 
        .margin(10) 
      } 
    } 
  } 
}

实现效果

适配的版本信息

  • IDE:DevEco    Studio 4.1.3.500
  • SDK:API11
已于2024-5-29 22:40:15修改
分享
微博
QQ
微信
回复
2024-05-29 22:39:42
相关问题
如何使用国密SM2算法进行加解密
879浏览 • 1回复 待解决
huks ECC指纹认证签名签报错
272浏览 • 1回复 待解决
基于加解密算法框架规格问题
208浏览 • 1回复 待解决
4.1.0(11) fluterr 无法通过
502浏览 • 1回复 待解决
SM3摘要算法对明文进行编码转换
358浏览 • 1回复 待解决
Huks如何导入AES密钥?
271浏览 • 1回复 待解决
关于无限步骤数据库表设计
702浏览 • 1回复 待解决