鸿蒙系统开发【ASN.1密文转换】安全

news2024/9/24 7:26:09

ASN.1密文转换

介绍

本示例对使用@kit.CryptoArchitectureKit加密后的密文格式进行转换。@kit.CryptoArchitectureKit加密后的密文格式默认为以base64显示的ASN.1格式问题,通过对密文进行base64变换后得到字符数组,以16进制数字显示,再此基础上进行密文格式转换,从ASN.1格式转换为c1c3c2格式的裸密文,再以c1c3c2格式的裸密文进行解密,以验证密文转换的正确性。

效果预览

1

使用说明

  1. 点击主页面加密按钮,对原始数据使用SM2国密算法进行加密,其内容显示在加密数据文本框中, 此时解密按钮和base64转换按钮使能
  2. 点击主页面base64转换按钮,对原始密文进行base64转换,在加密数据文本框中显示转换后的密文 此时asn.1转换按钮使能
  3. 点击主页面asn.1转换按钮,对密文进行asn.1转换,在加密数据文本框中显示转换后的密文 此时加密按钮和base64转换按钮去使能
  4. 点击主页面解密按钮,对密文进行解密,在解密数据文本框中显示解密后的文本 此时解密按钮去使能

具体实现

  • 对文本加密:在[SM2.ets] 点击加密按钮,调用加密函数实现对文本内容进行加密。点击解密按钮,调用解密函数实现对文本内容进行解密. 对消息加密的过程中采用cryptoFramework.Cipher完成加解密操作。
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { print } from '@kit.BasicServicesKit';
import { buffer, util } from '@kit.ArkTS';
import { SM2CipherText } from './SM2CipherText';

async function genECCPubKey(key: string) {
  let mode: number = 1;
  let pk: cryptoFramework.Point = {
    x: BigInt(""),
    y: BigInt(""),
  };
  if ((mode & 0x01) != 0 && key != null) {
    pk = {
      x: BigInt("0x" + key.substring(0, 64)),
      y: BigInt("0x" + key.substring(64, 128)),
    }
  }
  let keyPairGenerator: cryptoFramework.AsyKeyGeneratorBySpec;
  let pubKeySpec: cryptoFramework.ECCPubKeySpec = {
    params: genSM2CommonSpec(),
    pk: pk,
    algName: "ECC",
    specType: cryptoFramework.AsyKeySpecType.PUBLIC_KEY_SPEC
  };
  keyPairGenerator = cryptoFramework.createAsyKeyGeneratorBySpec(pubKeySpec);
  return await keyPairGenerator.generatePubKey();
}

async function genECCPriKey(key: string) {
  let mode: number = 2;
  let sk: bigint = BigInt("");
  if ((mode & 0x02) != 0) {
    sk = BigInt("0x" + key);
  }
  let keyPairGenerator: cryptoFramework.AsyKeyGeneratorBySpec;
  let priKey: cryptoFramework.ECCPriKeySpec = {
    params: genSM2CommonSpec(),
    sk: sk,
    algName: "ECC",
    specType: cryptoFramework.AsyKeySpecType.PRIVATE_KEY_SPEC
  };
  keyPairGenerator = cryptoFramework.createAsyKeyGeneratorBySpec(priKey);
  return await keyPairGenerator.generatePriKey();
}

export function genSM2CommonSpec(): cryptoFramework.ECCCommonParamsSpec {
  let fieldFp: cryptoFramework.ECFieldFp = {
    fieldType: "Fp",
    p: BigInt("0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF")
  }

  let G: cryptoFramework.Point = {
    x: BigInt("0x32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7"),
    y: BigInt("0xBC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0")
  }

  let SM2CommonSpec: cryptoFramework.ECCCommonParamsSpec = {
    algName: "ECC",
    specType: cryptoFramework.AsyKeySpecType.COMMON_PARAMS_SPEC,
    field: fieldFp,
    a: BigInt("0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC"),
    b: BigInt("0x28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93"),
    g: G,
    n: BigInt("0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123"),
    h: 1
  }
  return SM2CommonSpec;
}

export async function genSM2Key(pubKey: cryptoFramework.DataBlob | null, priKey: cryptoFramework.DataBlob | null): Promise<cryptoFramework.KeyPair> {
  let generator = cryptoFramework.createAsyKeyGenerator("SM2_256");
  return await generator.convertKey(pubKey, priKey)
}


async function encryptByPrimalKey(message: string, key: string): Promise<string> {
  let base64Helper = new util.Base64Helper();
  console.log(`key len: ${key.length}`);
  let pubKey = await genECCPubKey(key);
  let keyPair = await genSM2Key(pubKey.getEncoded(), null);
  let cipher = cryptoFramework.createCipher("SM2_256|SM3");
  await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyPair.pubKey, null);
  let plainTextBlob: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };
  let encryptBlob = await cipher.doFinal(plainTextBlob);
  return base64Helper.encodeToStringSync(encryptBlob.data);
}

export async function encryptSM2(message: string) {
  let pubKey: string = "5A033A9DBEF84C0784C897D070E6608C5AEED39B806DF82853D64E2A686A3794" + "F9233D20DD878F642D61C2B0344988AE284646226767A1631BBB0DBB6DF40D07"
  return encryptByPrimalKey(message, pubKey);
}

async function decryptByPrimalKeyArray(messageArray: Uint8Array, key: string): Promise<string> {
  let priKey = await genECCPriKey(key);
  let keyPair = await genSM2Key(null, priKey.getEncoded());
  let cipher = cryptoFramework.createCipher("SM2_256|SM3");
  await cipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null);
  let plainTextBlob: cryptoFramework.DataBlob = { data: messageArray };
  let decryptBlob = await cipher.doFinal(plainTextBlob);
  return buffer.from(decryptBlob.data).toString('utf-8');
}

export async function decryptSM2(encryptedStr: string, isc1c3c2: Boolean = false): Promise<string> {
  let priKey: string = "3629EFF03FBC86711F6695CBF5590F0F2FCAAA3C269A1CA9BD64FB4C70DF9C9F"

  if (isc1c3c2) {
    let hexStr = new SM2CipherText().i2dSM2CipherText(encryptedStr);
    let encryptedArray = new Uint8Array(buffer.from(hexStr, 'hex').buffer);
    return decryptByPrimalKeyArray(encryptedArray, priKey);
  }
  else {
    let base64Helper = new util.Base64Helper;
    let message = base64Helper.decodeSync(encryptedStr);
    return decryptByPrimalKeyArray(message, priKey);
  }
}



  • 对密文格式进行转换:在[SM2CipherText.ets]点击asn.1按钮,调用密文转换函数实现对密文内容进行转换。 完成密文转换操作。
import { SM2Sequence } from './SM2Sequence';
import { hilog } from '@kit.PerformanceAnalysisKit';

export class ASN1Util {
  static readonly BOOLEAN: string = "01";
  static readonly INTEGER: string = "02";
  static readonly BIT_STRING: string = "03";
  static readonly OCTEN_STRING: string = "04";
  static readonly NULL: string = "05";
  static readonly REAL: string = "09";
  static readonly ENUMERATED: string = "0a";
  static readonly SEQUENCE: string = "30";
  static readonly SET: string = "31";
}

export class SM2CipherText {
  i2dSM2CipherText(primal_data: string): string {
    let sm2_sequence = new SM2Sequence();
    sm2_sequence.C1x = primal_data.slice(0, 64);
    primal_data = primal_data.slice(64, primal_data.length);
    sm2_sequence.C1y = primal_data.slice(0, 64);
    primal_data = primal_data.slice(64, primal_data.length);
    sm2_sequence.C3 = primal_data.slice(0, 64);
    primal_data = primal_data.slice(64, primal_data.length);
    sm2_sequence.C2 = primal_data;

    let C1x_title: string = (Number.parseInt("0x" + sm2_sequence.C1x.slice(0, 2)) > 127) ? "022100" : "0220";
    let C1y_title: string = (Number.parseInt("0x" + sm2_sequence.C1y.slice(0, 2)) > 127) ? "022100" : "0220";
    let C3_title: string = "0420";
    let C2_title: string = "04" + this.genLenHex(sm2_sequence.C2);
    let sequence_message: string = C1x_title + sm2_sequence.C1x + C1y_title + sm2_sequence.C1y + C3_title + sm2_sequence.C3 + C2_title + sm2_sequence.C2;
    let sequence_lenHex: string = this.genLenHex(sequence_message);

    let standard_data = "30" + sequence_lenHex + sequence_message;
    return standard_data;
  }

  d2iSM2CipherText(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_lexHex: string = this.getLenHex(message);
    message = message.slice(sequence_lexHex.length, message.length);
    let sequence_len: number = this.lenHex2number(sequence_lexHex);
    if (sequence_len != message.length / 2) {
      this.ciphertextErr();
    }

    let sm2_sequence = new SM2Sequence();
    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;
  }

  genLenHex(content: string): string {
    let size: number = content.length / 2;
    let lenHex: string;
    if (size.toString(16).length % 2 == 1) {
      lenHex = '0' + size.toString(16);
    } else {
      lenHex = size.toString(16);
    }

    if (size < 0x80) {
      return lenHex;
    }
    let lenHex_size: number = lenHex.length / 2;
    return (lenHex_size | 0x80).toString(16) + lenHex;
  }

  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);
  }

  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: SM2Sequence, 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: SM2Sequence, data:string): string {
    if (data.startsWith(ASN1Util.OCTEN_STRING)) {
      data = data.slice(ASN1Util.OCTEN_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: SM2Sequence, 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;
  }
}

以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线,展示如下:
1

除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下

内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!

鸿蒙【北向应用开发+南向系统层开发】文档

鸿蒙【基础+实战项目】视频

鸿蒙面经

在这里插入图片描述

为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1971674.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

看完这几本大模型书籍,你就是LLM大师,非常详细收藏我这一篇就够了

以下是几本关于大模型和人工智能领域的经典书籍&#xff0c;它们各自具有独特的特点和适用人群&#xff1a; 《深度学习》&#xff08;Deep Learning&#xff09; 作者&#xff1a;伊恩古德费洛&#xff08;Ian Goodfellow&#xff09;、约书亚本吉奥&#xff08;Yoshua Bengi…

刀具磨损预测工器具磨损预测-RIME-CNN-SVM霜冰算法优化-完整代码数据

直接看项目演示: 刀具磨损预测工器具磨损预测-RIME-CNN-SVM霜冰算法优化_哔哩哔哩_bilibili 效果演示: 代码: import numpy as np import torch import torch.nn as nn import torch.nn.functional as F import torch.optim as optim from torch.utils.data import DataLo…

算法第十七天:leetcode242.有效的字母异位词

一、有效的字母异位词的题目描述与链接 242.有效的字母异位词如下表所示&#xff0c;您可以直接复制下面网址进入力扣学习&#xff0c;在观看下面的内容之前您一定要先做一遍哦&#xff0c;以便让你印象更加深刻&#xff01; https://leetcode.cn/problems/valid-anagram/desc…

curl wget介绍

0 Preface/Foreword 1 curl介绍 curl&#xff1a;transfer a URL synopsis&#xff1a; curl [options] [URL...] 描述&#xff1a; curl is a tool to transfer data from or to a server, using one of the supported protocols (DICT, FILE, HTTP, HTTPS, IMAP, FTP, FT…

【JavaEE初阶】懒汉模式与饿汉模式及指令重排序问题

目录 &#x1f4d5; 单例模式 &#x1f333; 饿汉模式 &#x1f6a9; 线程安全 &#x1f38d; 懒汉模式 &#x1f6a9; 懒汉模式-单线程版 &#x1f6a9; 懒汉模式-多线程版 &#x1f384; 指令重排序 &#x1f4d5; 单例模式 单例模式是一种经典的设计模式&#xff0c;…

Python | Leetcode Python题解之第312题戳气球

题目&#xff1a; 题解&#xff1a; class Solution:def maxCoins(self, nums: List[int]) -> int:n len(nums)rec [[0] * (n 2) for _ in range(n 2)]val [1] nums [1]for i in range(n - 1, -1, -1):for j in range(i 2, n 2):for k in range(i 1, j):total v…

文档编辑协作神器,全方位解决方案,灵活部署赋能个人与企业-onlyoffice

文章目录 1. 引言2. 免费畅享&#xff0c;个人的编辑利器2.1 PDF直接修改功能2.2 插件支持&#xff0c;应对多种工作场景2.3 AI助手智慧办公 3. 私有部署&#xff0c;开发者的自定义编辑器3.1 开发者版本介绍3.2 私有部署&#xff0c;解决数据安全问题3.3 实用功能丰富&#xf…

基于SpringBoot+Vue的流浪猫狗救助救援网站(带1w+文档)

基于SpringBootVue的流浪猫狗救助救援网站(带1w文档) 基于SpringBootVue的流浪猫狗救助救援网站(带1w文档) 该流浪猫狗救助救援网站在Windows平台下完成开发&#xff0c;采用java编程语言开发&#xff0c;将应用程序部署于Tomcat上&#xff0c;加之MySQL接口来实现交互式响应服…

LKEB-4030电阻器LKEB4030模块可议价

LKEB-4030电阻器LKEB4030模块可议价 LKEB-4030电阻器LKEB4030模块可议价 LKEB-4030电阻器LKEB4030模块可议价 LKEB-4030电阻器LKEB4030模块说明书 LKEB-4030电阻器LKEB4030模块接线图 LKEB-4030电阻器LKEB4030模块线路图 LKEB-4030电阻器&#xff08;Resistor&#xff09…

新手如何参加护网行动?一篇带你零基础入门到精通

前言 1、什么是护网行动 “护网行动”是指国家组织的网络安全防护演练行动。 护网行动通常由国家相关部门组织&#xff0c;旨在模拟真实的网络攻击情况&#xff0c;检验和提升关键信息基础设施、重要信息系统和大数据的安全防护能力。 在护网行动中&#xff0c;会有专业的攻…

基于微信小程序的搬家服务系统(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝10W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌ 涉及技术栈&#xff1a;SpringBoot、Vue、SSM、H…

SEO域名篇—如何选择一个好域名

SEO 域名选择误区 很多做站的大佬都告诉新入行的SEO优化员&#xff0c;选择域名一定要选择老域名&#xff0c;这里也是一个误区&#xff0c;很多新手在听了大佬的话后去就选择一些5年-15年的老域名直接做站&#xff0c;不去查查这个域名是否被360、QQ、微信等等一切搜索引擎拦…

Unity | Shader基础知识(第二十集:应用-简易流光、LOD)

目录 一、前言 二、LOD 1.什么是LOD 2.代码如何调节LOD 三、流光 1.资源准备 2.uv移动 3.获取图片中的uv 4.改变uv去取流光的颜色&#xff08;时间的应用&#xff09; 5.图片叠加 6.透明图片的叠加 四、纯净代码 五、作者的碎碎念 一、前言 有小伙伴问&#xf…

使用腾讯云域名解析实现网站重定向

前言 最近&#xff0c;在CSDN平台上我写了一系列博客&#xff0c;希望能与同学分享一些技术心得。然而&#xff0c;每当需要向他人推荐我的博客时&#xff0c;那串复杂且缺乏规律的CSDN博客首页域名总让我感到不便。这让我开始思考&#xff0c;如果能将这一域名替换为一个既个…

技术速递|VS Code Java 7月更新 - Gradle 支持增强!用户体验改进与 Spring 新功能

作者&#xff1a;Nick Zhu 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎来到 Visual Studio Code 7月份的 Java 更新&#xff01;本博客将覆盖最新的 Gradle 功能增强、用户体验改进以及新的 Spring 功能&#xff0c;让我们开始吧&#xff01; Gradle 功能增强 支持 Gr…

算法强训day19

一、小易的升级之路 链接&#xff1a;小易的升级之路_牛客题霸_牛客网 简单题 #include<iostream> using namespace std; long long gcd(long long m, long long x) {long long n ;while(x>0){n m % x;m x;x n;}return m; } int main() {int n;long long m;cin &…

文件上传漏洞--之upload-labs靶场(第6-10关)专栏更新ing......

注意&#xff1a; 为避免执行之前关卡的上传了的php文件代码&#xff0c;可以将upload文件夹下的文件清空 第六关&#xff1a; 第一步&#xff1a;查看源码 对比前面的几个关卡&#xff0c;里面没有文件去空格语句&#xff0c;可以使用后缀名加空格绕过 第二步&#xff1a;…

Python初学者必须掌握的基础知识点

Python初学者必须掌握的基础知识点包括数据类型与变量、控制结构&#xff08;条件语句和循环语句&#xff09;、基本数据结构&#xff08;列表、元组、字典、集合&#xff09;、函数与模块、以及字符串处理等。以下是对这些基础知识点及其对应代码的详细介绍&#xff1a; 1. …

Git常用命

转自&#xff1a;https://blog.csdn.net/ahjxhy2010/article/details/80047553 1.查看某个文件或目录的修改历史 git log filename #查看fileName相关的commit记录 git log -p filenam # 显示每次提交的diff#只看某次提交中的某个文件变化&#xff0c;commit-id  文件名…

【视频讲解】CatBoost、LightGBM和随机森林的海域气田开发特征分类研究

原文链接&#xff1a;https://tecdat.cn/?p37208 原文出处&#xff1a;拓端数据部落公众号 分析师&#xff1a;Changlin Li 本文将通过视频讲解&#xff0c;展示如何用CatBoost、LightGBM和随机森林的海域气田开发特征智能分类&#xff0c;并结合一个python分类预测职员离…