当前位置:   article > 正文

【鸿蒙开发实战教程】HarmonyOS开发中的对称加密_createsymkeygenerator

createsymkeygenerator

前言

根据研究机构Counterpoint Research发布的最新数据,2024年第一季度,鸿蒙OS份额由去年一季度的8%上涨至17%,iOS份额则从20%下降至16%。

这意味着,华为鸿蒙OS在中国市场的份额超越苹果iOS,已成中国第二大操作系统。

随着鸿蒙市场份额的不断提升,相应的岗位也会迎来一个爆发式的增长。这对于想要换赛道的程序员来说是一个非常好的消息,话说大家最近有想法转型鸿蒙开发吗?

这篇文章主要是讲一下鸿蒙开发过程中的对称加密

1. 介绍

HarmonyOS(鸿蒙)SDK API9支持两种对称加密算法:a. AES(Advanced Encryption Standard) b.3DES(也称为 3DESede 或 TripleDES).
官方也给出了一些样例使用代码,可供开发者参考。
本篇从实践出发,完整的通过代码方式来深入了解HarmonyOS中的对称加密用法。
在这里插入图片描述

2. 基础概念

字符串样例:AES256|EBC|PKCS5

1.密钥算法 : AES
2.密文组长度 : 256
3.分组模式 : EBC
4.填充模式 : PCKCS5

关于“AES算法”,“分组模式”,“填充模式”的具体概念,可自行搜索。

3. 实践

加密使用的测试数据源有两个,具体见下图

1.“125字节” (即,占用了125个字节的字符串)
2.“128字节” (即,占用了128个字节的字符串)

3.1 MMI入口

在这里插入图片描述

3.2 AES加解密

3DES加密算法密文分组长度有三种:128,192,256;支持7种分组模式:ECB,CBC,OFB,CFB,CTR,GCM,CCM;支持3种填充模式:NoPadding, PKCS5, PKCS7

本篇仅以256密文组长度做为实践验证,默认选择“128字节”数据集

片段代码以 “AES256|ECB|PKCS5” 为例

3.2.1 加密

1.生成对动态密钥

//导入加密框架
import cryptoFramework from '@ohos.security.cryptoFramework';

......

//创建密钥生成器,参数为(密钥算法+密文组长度,如:AES256)
let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES256');

//生成对称密钥
let promiseSymKey = symKeyGenerator.generateSymKey();

//获取密钥
promiseSymKey( key => {
   
  //动态密钥 
  this.symBinKey = key.getEncoded().data;

})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

2.初始化Cipher

//创建Cipher
globalCipher = cryptoFramework.createCipher('AES256|ECB|PKCS5');

//初始化Cipher
let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE; 
globalCipher.init(mode, key, null)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3.加密

//文字转换为Uint8Array
const encoder = new util.TextEncoder()
let u8a_encoder = encoder.encodeInto('测试')

//封装Uint8Array 数据,必须是一个带data属性的对象
let plainText = { data: u8a_encoder };

//开始加密
let promiseUpdate = globalCipher.update(plainText);

//获取加密结果
promiseUpdate( result => {

   //密文
   let this.cipherText = result.data
   
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

4.结束加密

上述虽然已经完成了加密,但是需要加密的文字字节长度不一定是128的整数倍,所以使用填充模式会弥补不足位的数据,并且在update之后,采用doFinal的方式结束最终加密

//结束加密
let promiseFinal = globalCipher.doFinal(null);

//获取剩余结果
promiseFinal( finalResult => {
    
    if(finalResult != null){
        //剩余加密结果
        let authTag = finalResult.data    
    }
    
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

3.2.2 解密

1.生成密钥对象

我们这里使用加密过程中产生的密钥数据。注意此密钥数据不能直接用来构建Key对象(即 密钥对象),正确的方法是通过API来生成密钥对象

//准备密钥数据,this.symBinKey 是上述过程生成的密钥
let keyMaterialBlob: cryptoFramework.DataBlob = { data: this.symBinKey };


//创建密钥生成器,参数为(密钥算法+密文组长度,如:AES256)
let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES256');

//密钥生成器使用密钥数据,开始生成密钥对象
symKeyGenerator.convertKey(keyMaterialBlob).then( key => {

   //key 为生成的密钥对象
   
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2.初始化Cipher

//创建Cipher
globalCipher = cryptoFramework.createCipher('AES256|EBC|PKCS5');

//初始化Cipher,参数key由第一步生成
let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
globalCipher.init(mode, key, null)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

3.解密

//mergeResult 代表密文,本篇文章中,此值来源于上述加密结果
let promiseUpdate = globalCipher.update({ data: mergeResult });
  • 1
  • 2

4.结束解密

//结束解密
let promiseFinal = globalCipher.doFinal(null);

//获取剩余结果
promiseFinal( finalResult => {
    
    if(finalResult != null){
        //有剩余解密结果
       
    } else {
       //无剩余解密结果
       
    }
    
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

3.2.3 注意点

1.采用GCM分组模式时,需要设置 ‘GcmParamsSpec’ 参数
2.采用CCM分组模式时,需要设置 ‘CcmParamsSpec’ 参数
3.采用CBC,OFB,CFB,CTR模式时,可以使用 ‘IvParamsSpec’ 参数
4.如果选择了"NoPadding"填充模式,需要明文的字节长度如果不是128的整数倍,则会出现截断现象,这种情况算做正常。
5.不要并发加密
6.加密/解密行为之间需要有时间间隔

3.2.4 源码

import cryptoFramework from '@ohos.security.cryptoFramework';
import util from '@ohos.util';
import Logger from '../../common/Logger';
import OriginData from './OriginData';
import emitter from "@ohos.events.emitter";

/**
 * 对称密钥
 *    密钥算法:AES
 *    密钥规格格式:密钥算法名称 + 密钥长度
 *    密钥长度:128,192,256
 *    密钥规格列表:AES128, AES192, AES256
 *
 * 对称加密
 *    加密算法:AES
 *    加密规格格式:密钥算法名称 + 密钥长度 + 分组模式 + 填充模式
 *    密钥长度:128,192,256
 *    分组模式:ECB、CBC、OFB、CFB、CTR、GCM和CCM
 *    填充模式:NoPadding,PKCS5,PKCS7
 *    加密规格样例:AES256|GCM|PKCS5
 *
 *
 *
 */
class TestSymmetricAESEncryptDecrypt {
  private symBinKey: Uint8Array;
  private cipherText: Uint8Array;
  private authTag: Uint8Array;

  private algorithmWithLength: string = 'AES256'
  private blockCipherMode: string = 'ECB' //ECB、CBC、OFB、CFB、CTR、GCM和CCM
  private paddingMode: string = 'NoPadding' //NoPadding,PKCS5,PKCS7

  //对称加密:AES256|GCM|PKCS5
  testSymAESEncryptWith256GCMPKCS5(blockCipherMode: string, paddingMode: string, dataSource128:boolean) {

    this.authTag = null

    let originData: string = OriginData.CONTENT_128

    if(dataSource128){
      originData = OriginData.CONTENT_128
    } else {
      originData = OriginData.CONTENT_125
    }

    this.blockCipherMode = blockCipherMode
    this.paddingMode = paddingMode

    let symKeyGenerator = cryptoFramework.createSymKeyGenerator(this.algorithmWithLength);

    let promiseSymKey = symKeyGenerator.generateSymKey();

    let globalCipher: cryptoFramework.Cipher

    promiseSymKey.then(key => {

      console.log('密钥已生成',key.format, key.algName, key.getEncoded().data.toString())
      Logger.d(this.algorithmWithLength, this.blockCipherMode, this.paddingMode)

      this.symBinKey = key.getEncoded().data;

      return key;

    }).then( key => {

      globalCipher = cryptoFramework.createCipher(this.algorithmWithLength + '|'
      + this.blockCipherMode + '|'
      + this.paddingMode);

        let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE;

        if (this.blockCipherMode == 'GCM') {
          return globalCipher.init(mode, key, this.genGcmParamsSpec());
        } else if(this.blockCipherMode == 'CCM') {
          return globalCipher.init(mode, key, this.genCcmParamsSpec());
        } else if(this.blockCipherMode == 'CBC' || this.blockCipherMode == 'CTR' || this.blockCipherMode == 'OFB'|| this.blockCipherMode == 'CFB'){
          return globalCipher.init(mode, key, this.genIvParamsSpec());
        } else {
          return globalCipher.init(mode, key, null);
        }

    }).then(() => {

        const encoder = new util.TextEncoder()
        let u8a_encoder = encoder.encodeInto(originData)

        Logger.d('开始加密')

        let plainText = { data: u8a_encoder };
        let promiseUpdate = globalCipher.update(plainText);

        return promiseUpdate;

      }).then(updateOutput => {

        if(updateOutput != null && updateOutput.data != null){
          this.cipherText = updateOutput.data
        }

        if (this.paddingMode != 'NoPadding') {

          Logger.d('加密分组之后的剩余数据')
          let promiseFinal = globalCipher.doFinal(null);
          return promiseFinal;

        } else {
          return null
        }

      }).then( authTag => {

        if(authTag != null && authTag.data != null){
          console.log('authTag:', authTag.data.toString())
          this.authTag = authTag.data
        } else {
          this.authTag = null
          console.log('authTag == null')
        }

        console.log('加密结束')

        return

      }).then(() => {

        this.testSymAESDecrypt()
        return

      }).catch( error => {
         console.error(`catch error, ${error.code}, ${error.message}`);
         this.notificationStatus('加密中-error',  error.code + '-' +  error.message)
      })

  }

  //对称解密: AES256|GCM|PKCS5
  testSymAESDecrypt() {

    // 二进制密钥数据
    let keyEncode = [242, 202, 181, 197, 174, 191, 60, 94, 138, 7, 53, 123, 64, 30, 32, 236, 93, 165, 234, 21, 136, 142, 12, 161, 238, 9, 56, 211,
      192, 134, 39, 236];
    let keyMaterialBlob: cryptoFramework.DataBlob = { data: this.symBinKey };

    //即将被解密的二进制数据,
    let willDecryptData = [209, 124, 163, 117, 73, 39, 230, 52, 162, 77, 46, 28, 39, 82, 32, 123, 177, 15, 218, 22, 206, 49, 167, 61]

    // GCM auth参数
    let authOriginData = [125, 81, 34, 43, 37, 200, 200, 251, 207, 183, 121, 185, 59, 143, 212, 128];
    let authBlob = { data: this.authTag };
    let gcmParamsSpec = null

    if(this.blockCipherMode == 'GCM'){
      console.log('配置'+this.blockCipherMode+'解密参数')

      gcmParamsSpec = this.genGcmParamsSpec()
      if(this.authTag != null){
        gcmParamsSpec.authTag = authBlob
      }

    } else if(this.blockCipherMode == 'CCM'){

      console.log('配置'+this.blockCipherMode+'解密参数')
       gcmParamsSpec = this.genCcmParamsSpec()
      if(this.authTag != null){
        gcmParamsSpec.authTag = authBlob
      }

    } else if(this.blockCipherMode == 'CBC' || this.blockCipherMode == 'CTR' || this.blockCipherMode == 'OFB'|| this.blockCipherMode == 'CFB'){

      console.log('配置'+this.blockCipherMode+'解密参数')
      gcmParamsSpec = this.genIvParamsSpec()
    }

    let globalCipher: cryptoFramework.Cipher

    let symKeyGenerator = cryptoFramework.createSymKeyGenerator(this.algorithmWithLength);

    let first: Uint8Array = null

    // 根据指定的二进制密钥数据,生成对称密钥对象
    symKeyGenerator.convertKey(keyMaterialBlob)
      .then(key => {

        console.log('解密-初始化Cipher')
        globalCipher = cryptoFramework.createCipher(this.algorithmWithLength + '|'
        + this.blockCipherMode + '|'
        + this.paddingMode);

        let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;

        if (this.blockCipherMode == 'GCM' || this.blockCipherMode == 'CCM'
          || this.blockCipherMode == 'CBC' || this.blockCipherMode == 'CTR'
          || this.blockCipherMode == 'OFB'|| this.blockCipherMode == 'CFB') {
          globalCipher.init(mode, key, gcmParamsSpec)
        } else {
          globalCipher.init(mode, key, null);
        }

        return

      })
      .then(() => {

        let mergeResult: Uint8Array

        if ((this.authTag != null)
          && ((this.blockCipherMode == 'ECB') || (this.blockCipherMode == 'CBC'))) {
            mergeResult = new Uint8Array([...this.cipherText, ...this.authTag])
            console.log('开始解密', '密文+authTag')
        } else {
            mergeResult = this.cipherText
            console.log('开始解密', '密文')
        }

        let promiseUpdate = globalCipher.update({ data: mergeResult });
        return promiseUpdate;

      })
      .then(updateOutput => {

        Logger.d('解密分组之后的剩余数据')
        first = updateOutput.data

        if(this.blockCipherMode == 'GCM'){
           if(this.paddingMode == 'NoPadding'){
             return
           }
        }
        let promiseFinal = globalCipher.doFinal(null);
        return promiseFinal;

      })
      .then( finalOutput => {

        if (finalOutput == null) { // 使用finalOutput.data前,先判断结果是否为null
          let textDecoder = util.TextDecoder.create()
          let key = textDecoder.decodeWithStream(first);

          Logger.d('解密完成1: ', key);

          this.notificationStatus('解密完成', key)
        } else {
          let textDecoder = util.TextDecoder.create()
          let key = textDecoder.decodeWithStream(new Uint8Array([...first, ...finalOutput.data]));

          Logger.d('解密完成2: ', key);
          this.notificationStatus('解密完成', key)
        }

        console.log('解密结束')

      })
      .catch(error => {
        console.error(`catch error, ${error.code}, ${error.message}`);
        this.notificationStatus('解密中-error',  error.code + '-' +  error.message)
      })

  }

  //https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/js-apis-cryptoframework-0000001477981409-V2#ZH-CN_TOPIC_0000001523488570__gcmparamsspec
  genGcmParamsSpec() {
    let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 12 bytes
    let dataIv = new Uint8Array(arr);
    let ivBlob = { data: dataIv };

    arr = [0, 0, 0, 0, 0, 0, 0, 0]; // 8 bytes
    let dataAad = new Uint8Array(arr);
    let aadBlob = { data: dataAad };

    arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 bytes
    let dataTag = new Uint8Array(arr);
    let tagBlob = { data: dataTag };

    let gcmParamsSpec = { iv: ivBlob, aad: aadBlob, authTag: tagBlob, algName: "GcmParamsSpec" };
    return gcmParamsSpec;
  }

  //https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/js-apis-cryptoframework-0000001477981409-V2#ZH-CN_TOPIC_0000001523488570__ccmparamsspec
  genCcmParamsSpec() {
    let arr = [0, 0, 0, 0, 0, 0, 0]; // 7 bytes
    let dataIv = new Uint8Array(arr);
    let ivBlob = { data: dataIv };

    arr = [0, 0, 0, 0, 0, 0, 0, 0]; // 8 bytes
    let dataAad = new Uint8Array(arr);
    let aadBlob = { data: dataAad };

    arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 12 bytes
    let dataTag = new Uint8Array(arr);
    let tagBlob = { data: dataTag };

    let ccmParamsSpec = { iv: ivBlob, aad: aadBlob, authTag: tagBlob, algName: "CcmParamsSpec" };
    return ccmParamsSpec;
  }

  //https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V2/js-apis-cryptoframework-0000001477981409-V2#ZH-CN_TOPIC_0000001523488570__ivparamsspec
  genIvParamsSpec() {
    let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 bytes
    let dataIv = new Uint8Array(arr);
    let ivBlob = { data: dataIv };

    let gcmParamsSpec = { iv: ivBlob, algName: "IvParamsSpec" };
    return gcmParamsSpec;
  }


   notificationStatus(status:string, result: string){
     // 定义一个eventId为1的事件,事件优先级为Low
     let event = {
       eventId: 202404063287,
       priority: emitter.EventPriority.HIGH
     };

     let eventData = {
       data: {
         "content": result,
         'status': status,
       }
     };

     // 发送eventId为1的事件,事件内容为eventData
     emitter.emit(event, eventData);
   }
}

export default new TestSymmetricAESEncryptDecrypt();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327

3.3 3DES加解密

3DES加密算法密文分组长度仅有一种:192; 支持3种分组模式:ECB,CBC,OFB; 支持3种填充模式:NoPadding, PKCS5, PKCS7

3DES加解密的流程与 “3.2 AES加解密”流程是一致的。

API使用概括起来如下

1.创建密钥生成器: createSymKeyGenerator
2.生成密钥对象:generateSymKey 或 convertKey
3.创建Cipher: createCipher
4.初始化Cipher: init
5.加密/解密:update
6.结束加密/解密:doFinal

3.3.1 源码

import cryptoFramework from '@ohos.security.cryptoFramework';
import util from '@ohos.util';
import Logger from '../../common/Logger';
import OriginData from './OriginData';
import emitter from "@ohos.events.emitter";

/**
 * 对称密钥
 *    密钥算法:3DES
 *    密钥规格格式:密钥算法名称 + 密钥长度
 *    密钥长度:192
 *    密钥规格列表:3DES
 *
 * 对称加密
 *    加密算法:3DES
 *    加密规格格式:密钥算法名称 + 密钥长度 + 分组模式 + 填充模式
 *    密钥长度:192
 *    分组模式:ECB、CBC、OFB
 *    填充模式:NoPadding,PKCS5,PKCS7
 *    加密规格样例:3DES192|ECB|NoPadding
 *
 *
 *
 */
class TestSymmetric3DESEncryptDecrypt {
  private symBinKey: Uint8Array = null;
  private cipherText: Uint8Array = null;
  private authTag: Uint8Array = null;
  private algorithmWithLength: string = '3DES192'
  private blockCipherMode: string = 'ECB' //ECB、CBC、OFB
  private paddingMode: string = 'NoPadding' //NoPadding,PKCS5,PKCS7


  //对称加密:3DES192|ECB|PKCS5
  testSym3DESEncryptWith192ECBPKCS5(blockCipherMode: string, paddingMode: string, dataSource128:boolean) {

    let originData: string = OriginData.CONTENT_128

    if(dataSource128){
      originData = OriginData.CONTENT_128
    } else {
      originData = OriginData.CONTENT_125
    }

    this.blockCipherMode = blockCipherMode
    this.paddingMode = paddingMode

    let symKeyGenerator = cryptoFramework.createSymKeyGenerator(this.algorithmWithLength);

    let promiseSymKey = symKeyGenerator.generateSymKey();

    let globalCipher: cryptoFramework.Cipher

    promiseSymKey.then( key => {

      console.log(key.format, key.algName, key.getEncoded().data.toString())
      Logger.d(this.algorithmWithLength, this.blockCipherMode, this.paddingMode)

      this.symBinKey = key.getEncoded().data;

      globalCipher = cryptoFramework.createCipher(this.algorithmWithLength + '|'
      + this.blockCipherMode + '|'
      + this.paddingMode);

      let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE;

      let initResult = globalCipher.init(mode, key, null);

      return initResult;

    }).then(async () => {

        const encoder = new util.TextEncoder()
        let u8a_encoder = encoder.encodeInto(originData)

        Logger.d('原文:' + u8a_encoder.toString())

        let plainText = { data: u8a_encoder };
        let promiseUpdate = globalCipher.update(plainText);

        return promiseUpdate;

      }).then( updateOutput => {

        if(updateOutput.data != null){
          Logger.d('编码后: ' + updateOutput.data.toString())
        }

        this.cipherText = updateOutput.data

        if (this.paddingMode != 'NoPadding') {
          let promiseFinal = globalCipher.doFinal(null);
          return promiseFinal;
        } else {
          return null
        }

      }).then(authTag => {

        if ((authTag != null) && (authTag.data != null)) {
          console.log('authTag:', authTag.data.toString())
          this.authTag = authTag.data
        } else {
          this.authTag = null
        }
        return

      }) .then(() => {

        this.testSym3DESDecrypt()
        return

      }).catch( error => {
         console.error(`catch error, ${error.code}, ${error.message}`);
         this.notificationStatus('加密中-error',  error.code + '-' +  error.message)
      })

  }

  //对称解密: 3DES192|ECB|PKCS5
  testSym3DESDecrypt() {

    // 二进制密钥数据
    let keyMaterialBlob: cryptoFramework.DataBlob = { data: this.symBinKey };

    let globalCipher: cryptoFramework.Cipher

    let symKeyGenerator = cryptoFramework.createSymKeyGenerator(this.algorithmWithLength);

    let first: Uint8Array = null

    // 根据指定的二进制密钥数据,生成对称密钥对象
    symKeyGenerator.convertKey(keyMaterialBlob)
      .then(key => {

        globalCipher = cryptoFramework.createCipher(this.algorithmWithLength + '|'
        + this.blockCipherMode + '|'
        + this.paddingMode);

        let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
        globalCipher.init(mode, key, null)

        return

      }).then(() => {

        let mergeResult: Uint8Array

        if ((this.authTag != undefined) && (this.authTag != null)) {
          mergeResult = new Uint8Array([...this.cipherText, ...this.authTag])
        } else {
          mergeResult = this.cipherText
        }

        let promiseUpdate = globalCipher.update({ data: mergeResult });
        return promiseUpdate;

      })
      .then( updateOutput => {

        first = updateOutput.data

        let promiseFinal = globalCipher.doFinal(null);
        return promiseFinal;

      })
      .then( finalOutput => {

        if (finalOutput == null) {

          let textDecoder = util.TextDecoder.create()
          let key = textDecoder.decodeWithStream(first);

          Logger.d('解密完成1: ', key);
          this.notificationStatus('解密完成', key)

        } else {

          let textDecoder = util.TextDecoder.create()
          let key = textDecoder.decodeWithStream(new Uint8Array([...first, ...finalOutput.data]));

          Logger.d('解密完成2: ', key);
          this.notificationStatus('解密完成', key)
        }

        console.log('解密结束')

      })
      .catch(error => {
        console.error(`catch error, ${error.code}, ${error.message}`);
        this.notificationStatus('解密中-error',  error.code + '-' +  error.message)
      })

  }

  notificationStatus(status:string, result: string){
    // 定义一个eventId为1的事件,事件优先级为Low
    let event = {
      eventId: 202404063287,
      priority: emitter.EventPriority.HIGH
    };

    let eventData = {
      data: {
        "content": result,
        'status': status,
      }
    };

    // 发送eventId为1的事件,事件内容为eventData
    emitter.emit(event, eventData);
  }

}

export default new TestSymmetric3DESEncryptDecrypt();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216

实践结果

以256长度分组,“128字节”作为数据源

数据集

export default class OriginData {

  //125字节 * 8
  public static readonly  CONTENT_125: string =
    "hello...iot...modbus,"
    + "加解密算法库框架是,全随机数等相关功能测开发者测可以通过调用加解密1024。"


  //128字节 * 8
  public static readonly  CONTENT_128: string =
    "hello...iot...modbus,"
    + "加解密算法库框架是,安全随机数等相关功能测开发者测可以通过调用加解密1024。"

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

组合实验结果

T:成功,F:失败

AES256

在这里插入图片描述

3DES

在这里插入图片描述

结束

本篇没有演示分段加密和分段解密,原始:代码没有实验成功
既然已经有了密文分组模式和长度,理论上在执行update时,其内部已经完成了分组加密,感觉也没有必要单独分段加密。

写在最后

有很多小伙伴不知道该从哪里开始学习鸿蒙开发技术?也不知道鸿蒙开发的知识点重点掌握的又有哪些?自学时频繁踩坑,导致浪费大量时间。结果还是一知半解。所以有一份实用的鸿蒙(HarmonyOS NEXT)全栈开发资料用来跟着学习是非常有必要的。

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开发必掌握的核心知识要点,内容包含了

最新鸿蒙全栈开发学习线路在这里插入图片描述

鸿蒙HarmonyOS开发教学视频

在这里插入图片描述
在这里插入图片描述

大厂面试真题

在这里插入图片描述

在这里插入图片描述

鸿蒙OpenHarmony源码剖析

在这里插入图片描述

这份资料能帮住各位小伙伴理清自己的学习思路,更加快捷有效的掌握鸿蒙开发的各种知识。有需要的小伙伴自行领取,,先到先得~无套路领取!!

获取这份完整版高清学习路线,请点击→[鸿蒙全栈开发学习资料]

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/925767
推荐阅读
相关标签
  

闽ICP备14008679号