鸿蒙开发之AES加解密

news/2024/7/7 22:16:08

        密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。

简介

        这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院 (NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一 [1]。

        该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijdael之名命之,投稿高级加密标准的甄选流程。(Rijdael的发音近于 "Rhine doll"。)

剖析

        高级加密标准算法从很多方面解决了令人担忧的问题。实际上,攻击数据加密标准的那些手段对于高级加密标准算法本身并没有效果。如果采用真正的128位加密技术甚至256位加密技术,蛮力攻击要取得成功需要耗费相当长的时间。

        虽然高级加密标准也有不足的一面,但是,它仍是一个相对新的协议。因此,安全研究人员还没有那么多的时间对这种加密方法进行破解试验。我们可能会随时发现一种全新的攻击手段会攻破这种高级加密标准。至少在理论上存在这种可能性。

AES加密模式

        对称/分组密码一般分为流加密(如OFB、CFB等)和块加密(如ECB、CBC等)。对于流加密,需要将分组密码转化为流模式工作。对于块加密(或称分组加密),如果要加密超过块大小的数据,就需要涉及填充和链加密模式。

ECB(Electronic Code Book电子密码本)模式

ECB模式是最早采用和最简单的模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密。

优点:

        1.简单; 2.有利于并行计算; 3.误差不会被传送; 缺点: 1.不能隐藏明文的模式; 2.可能对明文进行主动攻击; 因此,此模式适于加密小消息。

CBC(Cipher Block Chaining,加密块链)模式

优点:

        1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。 缺点: 1.不利于并行计算; 2.误差传递; 3.需要初始化向量IV

CFB(Cipher FeedBack Mode,加密反馈)模式

优点:

1.隐藏了明文模式; 2.分组密码转化为流模式; 3.可以及时加密传送小于分组的数据; 缺点: 1.不利于并行计算; 2.误差传送:一个明文单元损坏影响多个单元; 3.唯一的IV;

OFB(Output FeedBack,输出反馈)模式

优点:

1.隐藏了明文模式; 2.分组密码转化为流模式; 3.可以及时加密传送小于分组的数据; 缺点: 1.不利于并行计算; 2.对明文的主动攻击是可能的; 3.误差传送:一个明文单元损坏影响多个单元 [4]。

鸿蒙加密

        首先引用 import cryptoFramework from '@ohos.security.cryptoFramework' 在cryptoFramework 创建 createSymKeyGenerator(通过指定算法名称的字符串,获取相应的对称密钥生成器实例。) 本例以AES 256为准。

注:AES 256的key和iv 都是32位为准 如果是AES 128的key 和 iv 是16位。

AES 256 加密 实例如下:

  /**
   * 加密
   * @param key
   * @param source
   */
  encrypt(source: String, key: string, iv: string): Promise<String> {
    let cipherAlgName = 'AES256|CBC|PKCS7';

    let symKeyGenerator = cryptoFramework.createSymKeyGenerator(AES256);
    let ivParam: cryptoFramework.IvParamsSpec = {
      iv: { data: SecurityCommon.stringToUint8Array(iv, 32) },
      algName: "IvParamsSpec"
    }
    let cipher;
    return new Promise((resolve, reject) => {
      symKeyGenerator.convertKey({ data: SecurityCommon.stringToUint8Array(iv, 32) }).then(symKey => {
        try {
          cipher = cryptoFramework.createCipher(cipherAlgName)
          console.info(`xx cipher algName: ${cipher.algName}`)
        } catch (error) {
          console.error(`xx createCipher failed, ${error.code}, ${error.message}`);
          return null
        }
        //创建cipher之后才能初始化
        return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, ivParam)
          .then(() => {
            //创建cipher且初始化之后才能执行doFinal
            return cipher.doFinal({
              data: SecurityCommon.stringToUint8Array(source)
            })
          })
          .then(output => {
            let base64 = new util.Base64Helper();
            let result = base64.encodeToStringSync(output.data);
            return new Promise((resolve) => {
              resolve(result)
            })
          }).catch(e => {
            return new Promise((_, reject) => {
              reject(e)
            })
          })
      }).catch(e => {
        return new Promise((_, reject) => {
          reject(e)
        })

      }).then(result => {
        resolve(result)
      })
    })

  }

鸿蒙解密

        首先引用 import cryptoFramework from '@ohos.security.cryptoFramework' 在cryptoFramework 创建 createSymKeyGenerator(通过指定算法名称的字符串,获取相应的对称密钥生成器实例。) 本例以AES 256为准。

注:AES 256的key和iv 都是32位为准 如果是AES 128的key 和 iv 是16位。

AES 256 解密 实例如下:


  /**
   * aes 解密
   * @param message
   * @param key
   * @param iv
   * @param callback
   */
  decrypt(message: string, key: string, iv: string): Promise<String> {
    let cipherAlgName = 'AES256|CBC|PKCS7';

    let symKeyGenerator = cryptoFramework.createSymKeyGenerator(AES256);
    let ivParam: cryptoFramework.IvParamsSpec = {
      iv: { data: SecurityCommon.stringToUint8Array(iv, 32) },
      algName: "IvParamsSpec"
    }
    let cipher;
    return new Promise((resolve, reject) => {
      return symKeyGenerator.convertKey({
        data: SecurityCommon.stringToUint8Array(iv, 32)
      }).then(symKey => {
        try {
          cipher = cryptoFramework.createCipher(cipherAlgName);
          console.info(`xx cipher algName: ${cipher.algName}`);
        } catch (error) {
          console.error(`xx createCipher failed, ${error.code}, ${error.message}`);
          return null
        }
        return cipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, ivParam)
          .then(() => {
            let base64 = new util.Base64Helper();
            let result = base64.decodeSync(message);
            return cipher.doFinal({
              data: result
            })
          })
          .then(output => {
            let result = SecurityCommon.uint8ArrayToString(output.data)
            return new Promise((resolve) => {
              resolve(result)
            })
          }).catch(e => {
            return new Promise((_, reject) => {
              reject(e)
            })
          })
      }).catch(e => {
        reject(e)
      }).then(result => {
        resolve(result)
      })
    })

  }

字符串转无符号字节数组(Uint8Array)的方法 


  /**
   * 把String 转换为Uint8 数组
   * @param str
   * @returns
   */
  stringToUint8Array(str, len = null): Uint8Array {
    let arr = [];
    if (len == null) {
      len = str.length
    }
    for (let i = 0; i < len; i++) {
      if (str.length > i) {
        arr.push(str.charCodeAt(i))
      } else {
        arr.push(0)
      }
    }
    return new Uint8Array(arr);
  }

无符号字节数组 转换为字符串

  uint8ArrayToString(array: Uint8Array) {
    let arrayString = '';
    for (let i = 0; i < array.length; i++) {
      arrayString += String.fromCharCode(array[i]);
    }
    return arrayString;
  }


http://lihuaxi.xjx100.cn/news/2131106.html

相关文章

代码随想录阅读笔记-二叉树【翻转二叉树】

题目 翻转一棵二叉树。 思路 如果要从整个树来看&#xff0c;翻转还真的挺复杂&#xff0c;整个树以中间分割线进行翻转&#xff0c;如图&#xff1a; 可以发现想要翻转它&#xff0c;其实就把每一个节点的左右孩子交换一下就可以了。 关键在于遍历顺序&#xff0c;前中后序应…

【Python】python+requests+excel+unittest+ddt实现接口自动化实例

目录 测试需求实现思路框架代码实例1. 环境准备和配置文件2. Excel接口数据及测试结果3. API封装4. 读取Excel数据5. 测试用例6. 日志和配置文件处理7. HTMLTestRunner生成可视化的html报告8. 报告通过飞书/邮件发送报告通过飞书发送报告通过邮件发送9. 入口函数10. 飞书Webhoo…

​如何用“Dreamina”进行文生图​

文生图&#xff0c;顾名思义&#xff0c;就是用文字描述来生成图片。近年来&#xff0c;随着人工智能技术的进步&#xff0c;文生图技术也逐渐成熟&#xff0c;并逐渐应用于各种领域&#xff0c;例如设计、创作、娱乐等等。 本文将介绍如何使用“Dreamina”进行文生图。 步骤…

dnf手游:如何利用副本和任务快速积累泰拉财富?

DNF手游中&#xff0c;搬砖赚钱的方式多种多样&#xff0c;其中利用副本和任务是一种快速赚取泰拉的有效途径。本攻略将介绍如何通过参与副本和任务来获取泰拉&#xff0c;帮助玩家在游戏中获得更多的经济收益。 一、认识游戏中的泰拉 在DNF手游中&#xff0c;泰拉是一种主要的…

Zabbix6 - Centos7源码编译部署HA高可用集群手册

Zabbix6 - Centos7源码编译部署HA高可用集群手册 HA高可用集群 总所周知,在我们IT运维的圈圈中,HA高可用集群服务算是逼格最高的吧也是运维里保障力度最大的环境。 HA是HighlyAvailable缩写,是双机集群系统简称,提高可用性集群,是保证业务连续性的有效解决方案,一般有两个…

Doris删除数据工具

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 对于Doris的 Unique 模型&#xff0c;在删除数据的时候只能根据key删除&#xff0c;如果使用其他条件就会报错 整体架构流程 先获得表的key&#xff0c;然后在通过输入的条件获得key的所有值&#xff0c;最后通过key的…

智能数据建模软件DTEmpower 2024R1新版本功能介绍

DTEmpower是由天洑软件自主研发的一款通用的智能数据建模软件&#xff0c;致力于帮助工程师及工科专业背景学生&#xff0c;利用工业领域中的仿真、试验、测量等各类数据进行挖掘分析&#xff0c;建立高质量的数据模型&#xff0c;实现快速设计评估、实时仿真预测、系统参数预警…

3.亿级积分数据分库分表:ShardingSphere官方提供的平滑数据迁移方案介绍,有什么缺点呢?

前面的 2.亿级积分数据分库分表&#xff1a;增量数据同步之代码双写&#xff0c;为什么没用Canal&#xff1f; 博客中介绍了实现平滑数据迁移的两种方案&#xff1a;Canal监听MySQL的binlog、代码双写&#xff0c;也分别介绍了两种方案的实现原理及优缺点&#xff0c;最后基于…