当前位置: 首页 > news >正文

Harmony应用 ArkTs AES 加密方法之GCM对称加密

加解密介绍

在数据存储或传输场景中,可以使用加解密操作用于保证数据的机密性,防止敏感数据泄露。

使用加解密操作中,典型的场景有:

  1. 使用对称密钥的加解密操作。

  2. 使用非对称密钥的加解密操作。

  3. 使用RSA(PKCS1_OAEP填充模式)时,获取、设置CipherSpecItem参数。

加解密算法规格 

  • 对称密钥加解密算法规格
  • 非对称密钥加解密算法规格
  • 分段加解密说明

 

使用AES对称密钥(GCM模式)加解密(ArkTS)

对应的算法规格请查看对称密钥加解密算法规格:AES。

加密

  1. 调用cryptoFramework.createSymKeyGenerator、SymKeyGenerator.generateSymKey,生成密钥算法为AES、密钥长度为128位的对称密钥(SymKey)。

    如何生成AES对称密钥,开发者可参考下文示例,并结合对称密钥生成和转换规格:AES和随机生成对称密钥理解,参考文档与当前示例可能存在入参差异,请在阅读时注意区分。

  2. 调用cryptoFramework.createCipher,指定字符串参数'AES128|GCM|PKCS7',创建对称密钥类型为AES128、分组模式为GCM、填充模式为PKCS7的Cipher实例,用于完成加解密操作。

  3. 调用Cipher.init,设置模式为加密(CryptoMode.ENCRYPT_MODE),指定加密密钥(SymKey)和GCM模式对应的加密参数(GcmParamsSpec),初始化加密Cipher实例。

  4. 调用Cipher.update,更新数据(明文)。

    当前单次update长度没有限制,开发者可以根据数据量判断如何调用update。

    • 当数据量较小时,可以在init完成后直接调用doFinal。
    • 当数据量较大时,可以多次调用update,即分段加解密。
  5. 调用Cipher.doFinal,获取加密后的数据。

    • 由于已使用update传入数据,此处data传入null。
    • doFinal输出结果可能为null,在访问具体数据前,需要先判断结果是否为null,避免产生异常。
  6. 读取GcmParamsSpec.authTag作为解密的认证信息。

    在GCM模式下,需要从加密后的数据中取出末尾16字节,作为解密时初始化的认证信息。示例中authTag恰好为16字节。

解密

  1. 调用Cipher.init,设置模式为解密(CryptoMode.DECRYPT_MODE),指定解密密钥(SymKey)和GCM模式对应的解密参数(GcmParamsSpec),初始化解密Cipher实例。

  2. 调用Cipher.update,更新数据(密文)。

  3. 调用Cipher.doFinal,获取解密后的数据。

  • 异步方法示例:

    import { cryptoFramework } from '@kit.CryptoArchitectureKit';
    import { buffer } from '@kit.ArkTS';function genGcmParamsSpec() {let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 12 byteslet dataIv = new Uint8Array(arr);let ivBlob: cryptoFramework.DataBlob = { data: dataIv };arr = [0, 0, 0, 0, 0, 0, 0, 0]; // 8 byteslet dataAad = new Uint8Array(arr);let aadBlob: cryptoFramework.DataBlob = { data: dataAad };arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 byteslet dataTag = new Uint8Array(arr);let tagBlob: cryptoFramework.DataBlob = {data: dataTag}; // GCM的authTag在加密时从doFinal结果中获取,在解密时填入init函数的params参数中let gcmParamsSpec: cryptoFramework.GcmParamsSpec = {iv: ivBlob,aad: aadBlob,authTag: tagBlob,algName: "GcmParamsSpec"};return gcmParamsSpec;
    }let gcmParams = genGcmParamsSpec();// 加密消息
    async function encryptMessagePromise(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {let cipher = cryptoFramework.createCipher('AES128|GCM|PKCS7');await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, gcmParams);let encryptUpdate = await cipher.update(plainText);// gcm模式加密doFinal时传入空,获得tag数据,并更新至gcmParams对象中。gcmParams.authTag = await cipher.doFinal(null);return encryptUpdate;
    }
    // 解密消息
    async function decryptMessagePromise(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {let decoder = cryptoFramework.createCipher('AES128|GCM|PKCS7');await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, gcmParams);let decryptUpdate = await decoder.update(cipherText);// gcm模式解密doFinal时传入空,验证init时传入的tag数据,如果验证失败会抛出异常。let decryptData = await decoder.doFinal(null);if (decryptData == null) {console.info('GCM decrypt success, decryptData is null');}return decryptUpdate;
    }
    async function genSymKeyByData(symKeyData: Uint8Array) {let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');let symKey = await aesGenerator.convertKey(symKeyBlob);console.info('convertKey success');return symKey;
    }
    async function main() {let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]);let symKey = await genSymKeyByData(keyData);let message = "This is a test";let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };let encryptText = await encryptMessagePromise(symKey, plainText);let decryptText = await decryptMessagePromise(symKey, encryptText);if (plainText.data.toString() === decryptText.data.toString()) {console.info('decrypt ok');console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8'));} else {console.error('decrypt failed');}
    }

  • 同步方法示例:

    import { cryptoFramework } from '@kit.CryptoArchitectureKit';
    import { buffer } from '@kit.ArkTS';function genGcmParamsSpec() {let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 12 byteslet dataIv = new Uint8Array(arr);let ivBlob: cryptoFramework.DataBlob = { data: dataIv };arr = [0, 0, 0, 0, 0, 0, 0, 0]; // 8 byteslet dataAad = new Uint8Array(arr);let aadBlob: cryptoFramework.DataBlob = { data: dataAad };arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 byteslet dataTag = new Uint8Array(arr);let tagBlob: cryptoFramework.DataBlob = {data: dataTag};// GCM的authTag在加密时从doFinal结果中获取,在解密时填入init函数的params参数中let gcmParamsSpec: cryptoFramework.GcmParamsSpec = {iv: ivBlob,aad: aadBlob,authTag: tagBlob,algName: "GcmParamsSpec"};return gcmParamsSpec;
    }let gcmParams = genGcmParamsSpec();// 加密消息
    function encryptMessage(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {let cipher = cryptoFramework.createCipher('AES128|GCM|PKCS7');cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, gcmParams);let encryptUpdate = cipher.updateSync(plainText);// gcm模式加密doFinal时传入空,获得tag数据,并更新至gcmParams对象中。gcmParams.authTag = cipher.doFinalSync(null);return encryptUpdate;
    }
    // 解密消息
    function decryptMessage(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {let decoder = cryptoFramework.createCipher('AES128|GCM|PKCS7');decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, gcmParams);let decryptUpdate = decoder.updateSync(cipherText);// gcm模式解密doFinal时传入空,验证init时传入的tag数据,如果验证失败会抛出异常。let decryptData = decoder.doFinalSync(null);if (decryptData == null) {console.info('GCM decrypt success, decryptData is null');}return decryptUpdate;
    }
    async function genSymKeyByData(symKeyData: Uint8Array) {let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');let symKey = await aesGenerator.convertKey(symKeyBlob);console.info('convertKey success');return symKey;
    }
    async function main() {let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]);let symKey = await genSymKeyByData(keyData);let message = "This is a test";let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };let encryptText = encryptMessage(symKey, plainText);let decryptText = decryptMessage(symKey, encryptText);if (plainText.data.toString() === decryptText.data.toString()) {console.info('decrypt ok');console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8'));} else {console.error('decrypt failed');}
    }

原文档参考:文档中心 

相关文章:

Harmony应用 ArkTs AES 加密方法之GCM对称加密

加解密介绍 在数据存储或传输场景中,可以使用加解密操作用于保证数据的机密性,防止敏感数据泄露。 使用加解密操作中,典型的场景有: 使用对称密钥的加解密操作。 使用非对称密钥的加解密操作。 使用RSA(PKCS1_OAEP…...

热成像在战场上的具体作用!!!

1. 探测和跟踪敌人 原理:人体和许多类型的军事设备都会发热,热成像技术通过探测这些红外辐射,能够在远距离探测和跟踪敌人的位置。 应用场景:这一功能在夜间或有覆盖物(如草丛、树林)的情况下尤为有效&am…...

2024年09月20日《每日一练》

1、 根据我国“十三五”规划纲要,()不属于新一代信息技术产业创新发展的重点。 A 人工智能 B 移动智能终端 C 先进传感器 D 4G D P13 此题考察的是新一代信息技术,必须掌握,高频考点 国在“十三五“规划纲要中&#x…...

使用 SSCB 保护现代高压直流系统的优势

在各种应用中,系统效率和功率密度不断提高,这导致了更高的直流系统电压。然而,传统的电路保护解决方案不足以在保持高可靠性和安全性的同时有效保护这些高压配电系统。 固态断路器 (SSCB) 和电熔断器具有众多优点&…...

Linux基础命令——文件系统的日常管理

目录 一.如何查看当前工作目录?(你现在所处的位置路径) 二.命令touch的用途是什么?还有别的方法新建文件吗? (1)创建空文件 (2)如果已经存在这个文件,就会更新创建时间。 (3…...

uniapp使用高德地图设置marker标记点,后续根据接口数据改变某个marker标记点,动态更新

最近写的一个功能属实把我难倒了,刚开始我请求一次数据获取所有标记点,然后设置到地图上,然后后面根据socket传来的数据对这些标记点实时更新,改变标记点的图片或者文字, 1:第一个想法是直接全量替换,事实证明这样不行,会很卡顿,有明显闪烁感,如果标记点比较少,就十几个可以用…...

坦白了,因为这个我直接爱上了 FreeBuds 6i

上个月,华为发布的 FreeBuds 6i 联名了泡泡玛特真的超级惊艳,不少宝子被这款耳机的颜值所吸引,而它的实力更是不容小觑的。FreeBuds 6i 是一款性能强大的降噪耳机,它一直在强调平均降噪深度,但是应该很多人对这个概念很…...

006.MySQL_查询数据

课 程 推 荐我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈虚 拟 环 境 搭 建 :&#x1…...

【C#生态园】从图像到视觉:Emgu.CV、AForge.NET、OpenCvSharp 全面解析

C#图像处理库大比拼:功能对比、安装配置、API概览 前言 图像处理和计算机视觉在现代软件开发中扮演着重要角色,而C#作为一种流行的编程语言,拥有许多优秀的图像处理库。本文将介绍几个用于C#的图像处理和计算机视觉库,包括Image…...

1、无线通信的发展概况

无线通信是指双方至少一方使用无线方式进行信息的交换与传输,包括移动体(行人、车辆、船舶以及飞机)和移动体之间的通信,也包括移动体与固定点(固定点的移动电台或有线通信)之间的通信。 随着无线通信的范围…...

虚拟机安装xubuntu

新建一个新的虚拟机,选择自定义安装 默认下一步 选择稍后安装操作系统 选择所要创建的系统及版本 填写虚拟机的名称及创建的虚拟机保存的位置 选择处理器和内核的数量 处理器数量指的是:虚拟的CPU数量。 每个处理器的内核数量指的是:虚拟CPU…...

携手鲲鹏,长亮科技加速银行核心系统升级

新经济周期下,银行净息差持续收窄、盈利压力加大、市场竞争日趋加剧。同时,国家相关政策不断出台,对金融科技的自主创新与安全可控提出了更高要求。 在这样的大背景下,银行业的数字化转型已经步入深水区。其中,核心系统…...

新鲜的Win11/10镜像,全系列下载!

下载:新鲜的Win11/10镜像,全系列下载! | 瑆箫博客 Windows每个月都来一次例行更新,大吉大利今晚装机!2024年9月份ISO镜像,来咯~我们不生产系统,我们只是大自然微软的搬运工本文提供Windows11、…...

iPhone 16系列:摄影艺术的全新演绎,探索影像新境界

在科技的浪潮中,智能手机摄影功能的进化从未停歇。 苹果公司即将推出的iPhone 16系列,以其卓越的相机升级和创新特性,再次站在了手机摄影的前沿。 从硬件到软件,从拍照体验到图像处理,iPhone 16系列都展现了其在移动…...

移动应用开发中的技术选择:优缺点全面解析

在移动应用开发领域,技术的快速演变和多样化使得开发者面临着多种选择。随着市场需求的不断变化,各种框架和工具应运而生。本文将分析当前主流应用开发技术的优势与劣势,帮助开发者选择最适合的技术栈。 一、原生开发 优势 性能卓越&#…...

宿舍管理系统的设计与实现 (含源码+sql+视频导入教程)

👉文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 宿舍管理系统拥有三个角色,分别为系统管理员、宿舍管理员以及学生。其功能如下: 管理员:宿舍管理员管理、学生管理、宿舍楼管理、缺勤记录管理、个人密…...

原生+jquery写自动消失的提示框

<!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title>自动消失消息提示</title> <style>/…...

Android14 蓝牙 BluetoothService 启动和相关代码介绍

Android14 蓝牙 BluetoothService 启动和相关代码 文章目录 Android14 蓝牙 BluetoothService 启动和相关代码一、前言二、代码分析介绍1、蓝牙 BluetoothService 启动和相关代码&#xff08;1&#xff09;蓝牙服务相关的有几个类有&#xff1a;&#xff08;2&#xff09;几个蓝…...

【秋招笔试-支持在线评测】9.19小米秋招(已改编)-三语言题解

🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集…...

动态IP与静态IP:哪种更适合用户使用?

在现代网络环境中&#xff0c;IP地址的管理对于网络的运行和安全至关重要。IP地址是网络中每一个设备的唯一标识符&#xff0c;通常分为动态IP和静态IP两种类型。每种类型都有其独特的优缺点&#xff0c;适用于不同的使用场景。本文将探讨动态IP和静态IP的特点&#xff0c;并分…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例

文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

基于Java+MySQL实现(GUI)客户管理系统

客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息&#xff0c;对客户进行统一管理&#xff0c;可以把所有客户信息录入系统&#xff0c;进行维护和统计功能。可通过文件的方式保存相关录入数据&#xff0c;对…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器

拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件&#xff1a; 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

【WebSocket】SpringBoot项目中使用WebSocket

1. 导入坐标 如果springboot父工程没有加入websocket的起步依赖&#xff0c;添加它的坐标的时候需要带上版本号。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dep…...

macOS 终端智能代理检测

&#x1f9e0; 终端智能代理检测&#xff1a;自动判断是否需要设置代理访问 GitHub 在开发中&#xff0c;使用 GitHub 是非常常见的需求。但有时候我们会发现某些命令失败、插件无法更新&#xff0c;例如&#xff1a; fatal: unable to access https://github.com/ohmyzsh/oh…...

PH热榜 | 2025-06-08

1. Thiings 标语&#xff1a;一套超过1900个免费AI生成的3D图标集合 介绍&#xff1a;Thiings是一个不断扩展的免费AI生成3D图标库&#xff0c;目前已有超过1900个图标。你可以按照主题浏览&#xff0c;生成自己的图标&#xff0c;或者下载整个图标集。所有图标都可以在个人或…...

Qt的学习(二)

1. 创建Hello Word 两种方式&#xff0c;实现helloworld&#xff1a; 1.通过图形化的方式&#xff0c;在界面上创建出一个控件&#xff0c;显示helloworld 2.通过纯代码的方式&#xff0c;通过编写代码&#xff0c;在界面上创建控件&#xff0c; 显示hello world&#xff1b; …...