HarmonyOS鸿蒙Next中国密SM2算法如何得到ASN.1解码后裸密文数据

HarmonyOS鸿蒙Next中国密SM2算法如何得到ASN.1解码后裸密文数据 国密SM2算法如何得到ASN.1解码后裸密文数据

4 回复

SM2_Ciphertext

i2d_SM2_Ciphertext

import { SM2_SEQUENCE } from '../crypto/SM2/sm2Sequence';
import { ASN1Util } from './asn1Util';
import hilog from '@ohos.hilog';

export class SM2_Ciphertext {

  /**
   用于将SM2裸密文数据序列化
   @param primal_data SM2裸密钥数据,长度为96+明文长度(字节),输入格式为C1C3C2的Hex字符串
   @returns 返回序列化后的标准密文数据,输出格式为Hex字符串
   */
  i2d_SM2_Ciphertext(primal_data: string): string {
    let standard_data: string = "";
    return standard_data;
  }

  /**
  用于将标准SM2密文数据解码
  @param standard_data 标准SM2密文数据,符合ASN.1编码标准,输入格式为Hex字符串
  @returns 返回ASN.1解码后的SM2密文数据
  */
  d2i_SM2_Ciphertext(standard_data: string): string {
    let message: string = standard_data;

    if (!message.startsWith(ASN1Util.SEQUENCE)) {
      this.ciphertextErr();
    }
    message = message.slice(ASN1Util.SEQUENCE.length, message.length);

    let sequence_lenHex: string = this.getLenHex(message);
    message = message.slice(sequence_lenHex.length, message.length);

    let sequence_len: number = this.lenHex2number(sequence_lenHex);
    if (sequence_len != message.length / 2) {
      this.ciphertextErr();
    }

    let sm2_sequence = new SM2_SEQUENCE();
    message = this.readC1(sm2_sequence, message);
    message = this.readC3(sm2_sequence, message);
    message = this.readC2(sm2_sequence, message);

    console.log(sm2_sequence.toString());
    let primal_data: string = sm2_sequence.C1x + sm2_sequence.C1y + sm2_sequence.C3 + sm2_sequence.C2;

    return primal_data;
  }

  // 提取表示长度的字符串
  getLenHex(data: string): string {
    let byte: number = Number.parseInt("0x" + data.slice(0, 2));
    let len_size: number = byte > 127 ? byte - 0x80 + 1 : 1;
    return data.slice(0, len_size * 2);
  }

  // 将表示长度的Hex字符串转为整型
  lenHex2number(lenHex: string): number {
    if (lenHex.length == 2) {
      return Number.parseInt("0x" + lenHex);
    }
    return Number.parseInt("0x" + lenHex.slice(2, lenHex.length));
  }

  ciphertextErr() {
    hilog.error(0, "d2i_SM2_Ciphertext", "密文格式错误");
    throw new Error("SM2 ciphertext error!")
  }

  readC1(sm2_sequence: SM2_SEQUENCE, data: string): string {
    let xy: string[] = [];
    for (let i = 0; i < 2; i++) {
      if (data.startsWith("0220")) {
        xy[i] = data.slice(4, 68);
        data = data.slice(68, data.length);
      } else if (data.startsWith("022100")) {
        xy[i] = data.slice(6, 70);
        data = data.slice(70, data.length);
      } else {
        this.ciphertextErr();
      }
    }
    sm2_sequence.C1x = xy[0];
    sm2_sequence.C1y = xy[1];
    return data;
  }

  readC2(sm2_sequence: SM2_SEQUENCE, data: string): string {
    if (data.startsWith(ASN1Util.OCTET_STRING)) {
      data = data.slice(ASN1Util.OCTET_STRING.length, data.length);
      let C2_lenHex = this.getLenHex(data);
      data = data.slice(C2_lenHex.length, data.length)
      if (this.lenHex2number(C2_lenHex) != data.length / 2) {
        this.ciphertextErr()
      }
      sm2_sequence.C2 = data;
    } else {
      this.ciphertextErr();
    }
    return data;
  }

  readC3(sm2_sequence: SM2_SEQUENCE, data: string): string {
    if (data.startsWith("0420")) {
      sm2_sequence.C3 = data.slice(4, 68);
      data = data.slice(68, data.length);
    } else {
      this.ciphertextErr();
    }
    return data;
  }
}

ASN1Util

export class ASN1Util {

  static BOOLEAN: string = "01";
  static INTEGER: string = "02";
  static BIT_STRING: string = "03";
  static OCTET_STRING: string = "04";
  static NULL: string = "05";
  static REAL: string = "09";
  static ENUMERATED: string = "0a";
  static SEQUENCE: string = "30";
  static SET: string = "31";

}

SM2_SEQUENCE

import { formToJSON } from '@ohos/axios';

export class SM2_SEQUENCE {

  private _C1x: string = "";
  private _C1y: string = "";
  private _C2: string = "";
  private _C3: string = "";

  public set C1x(value: string) {
    this._C1x = value;
  }

  public get C1x(): string {
    return this._C1x;
  }

  public set C1y(value: string) {
    this._C1y = value;
  }

  public get C1y(): string {
    return this._C1y;
  }

  public set C2(value: string) {
    this._C2 = value;
  }

  public get C2(): string {
    return this._C2;
  }

  public set C3(value: string) {
    this._C3 = value;
  }

  public get C3(): string {
    return this._C3;
  }

  public toString(): string {
    return JSON.stringify(this);
  }

}

更多关于HarmonyOS鸿蒙Next中国密SM2算法如何得到ASN.1解码后裸密文数据的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


asn1Util工具类是自己实现的吗

在HarmonyOS鸿蒙Next中,使用中国密SM2算法获取ASN.1解码后的裸密文数据,可以通过以下步骤实现:

  1. 获取密文数据:首先,从SM2加密操作中获取密文数据。SM2加密后的密文通常包含ASN.1编码的结构,其中包括公钥、密文等部分。

  2. 解析ASN.1结构:使用鸿蒙提供的ASN.1解析库,对密文数据进行解码。ASN.1编码的密文数据通常包含多个字段,如加密的椭圆曲线点、密文长度等。

  3. 提取裸密文:在解码后的ASN.1结构中,找到密文部分。通常,密文部分是ASN.1结构中的一个特定字段,提取该字段即可得到裸密文数据。

  4. 验证数据完整性:在处理过程中,确保提取的裸密文数据与原始密文数据一致,避免数据丢失或错误。

具体代码示例如下:

import { Asn1Decoder } from '@ohos.security.asn1';
import { Sm2Cipher } from '@ohos.security.sm2';

// 假设sm2Cipher是SM2加密后的密文
let sm2Cipher: Uint8Array = ...;

// 使用ASN.1解码器解析密文
let decoder = new Asn1Decoder();
let decodedData = decoder.decode(sm2Cipher);

// 提取裸密文数据
let rawCipherText = decodedData.getField('cipherText').value;

// rawCipherText即为ASN.1解码后的裸密文数据

在HarmonyOS鸿蒙Next中,若需获取SM2算法ASN.1解码后的裸密文数据,首先应使用ASN.1解码库对密文进行解码。解码后,您将获得一个包含多个字段的结构体,其中包含裸密文数据。裸密文数据通常位于结构体的特定字段中,您需通过访问该字段来提取裸密文数据。提取后,即可进行后续处理或分析。请确保操作符合相关安全规范。

回到顶部