【加密专栏】OpenHarmony应用开发-加解密之AES128_CBC_PKCS5

简介

该文主要提供AES128|CBC|PKCS5加解密的最佳实践示例。

开发环境

DevEco Studio: DevEco Studio 5.1.0 Release(Build Version: 5.1.0.128)

系统: OpenHarmony 5.0.3.135

设备: DAYU200(rk3568)

最佳实践示例

ts 复制代码
// AES128|CBC|PKCS5
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import { buffer, util } from '@kit.ArkTS';

@Entry
@Component
struct CryptoArchitectureTest2 {

  encryptText: string = ''
  iv = this.genIvParamsSpec();
  base64Helper = new util.Base64Helper()
  @State originMessage: string = '123123123123131312313123'
  @State finalMessage: string = ''

  generateRandom(len: number): cryptoFramework.DataBlob {
    let rand = cryptoFramework.createRandom();
    let generateRandSync = rand.generateRandomSync(len);
    return generateRandSync;
  }

  genIvParamsSpec() {
    let ivBlob = this.generateRandom(16);
    let ivParamsSpec: cryptoFramework.IvParamsSpec = {
      algName: "IvParamsSpec",
      iv: ivBlob
    };
    return ivParamsSpec;
  }

  async encryptMessagePromise(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
    let cipher = cryptoFramework.createCipher('AES128|CBC|PKCS5');
    await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, this.iv);
    let cipherData = await cipher.doFinal(plainText);
    return cipherData;
  }

  async decryptMessagePromise(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {
    let decoder = cryptoFramework.createCipher('AES128|CBC|PKCS5');
    await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, this.iv);
    let decryptData = await decoder.doFinal(cipherText);
    return decryptData;
  }

  async genSymKeyByData(symKeyData: Uint8Array) {
    let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
    let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
    let symKey = await aesGenerator.convertKey(symKeyBlob);
    return symKey;
  }

  // Uint8Array转化Base64
  uint8ArrayToBase64(fileData: Uint8Array): string {
    return this.base64Helper.encodeToStringSync(fileData);
  }

  // Base64转化Uint8Array
  base64ToUint8Array(fileData: string): Uint8Array {
    return this.base64Helper.decodeSync(fileData);
  }

  // 将UTF-8编码转换成Unicode编码
  uint8ArrayToString(array: Uint8Array) {
    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;
  }

  build() {
    Column({ space: 20 }) {
      Text('AES128|CBC|PKCS5')
        .fontSize(30)

      Button('加密')
        .fontSize(50)
        .onClick(async () => {
          try {
            let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]);
            let symKey = await this.genSymKeyByData(keyData);
            console.info(`originMessage: ${this.originMessage}`);
            let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(this.originMessage, 'utf-8').buffer) };
            console.info(`plainText: ${this.uint8ArrayToBase64(plainText.data)}`);
            let encryptText = await this.encryptMessagePromise(symKey, plainText);
            this.encryptText = this.uint8ArrayToBase64(encryptText.data);
            console.info(`encryptText: ${this.encryptText}`);
          } catch (error) {
            console.error(`AES CBC "${error}", error code: ${error.code}`);
          }
        })

      Text(`originMessage: ${this.originMessage}`)
        .fontSize(30)

      Button('解密')
        .fontSize(50)
        .onClick(async () => {
          try {
            let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]);
            let symKey = await this.genSymKeyByData(keyData);
            let decryptText = await this.decryptMessagePromise(symKey, { data: this.base64ToUint8Array(this.encryptText) });
            console.info(`decryptText: ${JSON.stringify(this.uint8ArrayToBase64(decryptText.data))}`);
            this.finalMessage = this.uint8ArrayToString(decryptText.data)
            console.info(`finalMessage: ${this.finalMessage}`);
          } catch (error) {
            console.error(`AES CBC "${error}", error code: ${error.code}`);
          }
        })

      Text(`finalMessage: ${this.finalMessage}`)
        .fontSize(30)
    }
    .justifyContent(FlexAlign.Center)
    .alignItems(HorizontalAlign.Center)
    .height('100%')
    .width('100%')
  }
}
相关推荐
AI多Agent协作实战派9 分钟前
AI多Agent协作系统实战(二十三):Agent读HEARTBEAT.md不读AGENTS.md——openclaw的文件加载之谜
前端·数据库·人工智能·uni-app
2601_955760071 小时前
如何用 Claude Opus 5 API 批量扩展长尾关键词和文章选题
前端·python·搜索引擎
KaMeidebaby1 小时前
卡梅德生物技术快报|bli亲和力检测gst:告别批量跑胶:BLI实时酶切监测技术加速GST融合蛋白下游流程优化
前端·网络·数据库·人工智能·算法
触底反弹2 小时前
🚀 删了数据刷新又回来?3 组件 × 4 回调 × 3 坑讲透 React 父子通信
前端·javascript·react.js
耳东小鹿3 小时前
对象常用方法
前端
程序员海军3 小时前
一个 AI 应用开发程序员的一天,都在屏幕前忙些什么?
前端·后端·程序员
程序员黑豆3 小时前
鸿蒙应用开发:Stack堆叠组件实战——实现微信消息角标效果
前端·harmonyos
夏幻灵3 小时前
浏览器原理深度解析:从输入 URL 到页面展现的全流程剖析
前端
闲猫4 小时前
Agent工程实践:从WorkFlow到多Agent协作的落地笔记
java·服务器·前端
带娃的IT创业者4 小时前
重新定义前端构建速度:深度解析 SWC 如何用 Rust 颠覆 JavaScript 工具链
前端·javascript·rust·前端构建·swc