鸿蒙开发5.0【对称加密】

1. 介绍

HarmonyOS(鸿蒙)SDK API9支持两种对称加密算法:a. AES(Advanced Encryption Standard) b.3DES(也称为 3DESede 或 TripleDES).

官方也给出了一些样例使用代码,可供开发者参考。

本篇从实践出发,完整的通过代码方式来深入了解HarmonyOS中的对称加密用法。

0

2. 基础概念

字符串样例:AES256|EBC|PKCS5

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

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

3. 实践

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

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

3.1 MMI入口

1
2
3

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. 初始化Cipher
//创建Cipher
globalCipher = cryptoFramework.createCipher('AES256|ECB|PKCS5');

//初始化Cipher
let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE; 
globalCipher.init(mode, key, null)
  1. 加密
//文字转换为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. 结束加密

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

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

//获取剩余结果
promiseFinal( finalResult => {
    
    if(finalResult != null){
        //剩余加密结果
        let authTag = finalResult.data    
    }
    
})

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. 初始化Cipher
//创建Cipher
globalCipher = cryptoFramework.createCipher('AES256|EBC|PKCS5');

//初始化Cipher,参数key由第一步生成
let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
globalCipher.init(mode, key, null)
  1. 解密
//mergeResult 代表密文,本篇文章中,此值来源于上述加密结果
let promiseUpdate = globalCipher.update({ data: mergeResult });
  1. 结束解密
//结束解密
let promiseFinal = globalCipher.doFinal(null);

//获取剩余结果
promiseFinal( finalResult => {
    
    if(finalResult != null){
        //有剩余解密结果
       
    } else {
       //无剩余解密结果
       
    }
    
})

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
 *    加密规格格式:密钥算法名称 + 密钥长度 + 分组模式 + 填充模式
 *    密钥长度&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值