【HarmonyOS NEXT】使用RSA非对称密钥分段加解密

加密

调用cryptoFramework.createAsyKeyGeneratorAsyKeyGenerator.generateKeyPair,生成RSA密钥类型为RSA1024、素数个数为2(不填默认)的非对称密钥对(KeyPair)。KeyPair对象中包括公钥PubKey、私钥PriKey。

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

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

调用Cipher.init,设置模式为加密(CryptoMode.ENCRYPT_MODE),指定加密密钥(KeyPair.PubKey),初始化加密Cipher实例。

多次调用Cipher.doFinal,传入明文,获取加密后的数据。

doFinal输出结果可能为null,在访问具体数据前,需要先判断结果是否为null,避免产生异常。

此处将明文按64个字节一组拆分,多次加密。使用1024位密钥,每次将生成128字节密文。

解密

由于RSA算法的Cipher实例不支持重复init操作,需要调用cryptoFramework.createCipher,重新生成Cipher实例。​​​​​​​

调用Cipher.init,设置模式为解密(CryptoMode.DECRYPT_MODE),指定解密密钥(KeyPair.PriKey)初始化解密Cipher实例。PKCS1模式无加密参数,直接传入null。​​​​​​​

多次调用Cipher.doFinal,传入密文,获取解密后的数据。

  • 异步方法示例:
  • import { cryptoFramework } from '@kit.CryptoArchitectureKit';
    import { buffer } from '@kit.ArkTS';
    // 分段加密消息
    async function rsaEncryptBySegment(pubKey: cryptoFramework.PubKey, plainText: cryptoFramework.DataBlob) {let cipher = cryptoFramework.createCipher('RSA1024|PKCS1');await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null);let plainTextSplitLen = 64;let cipherText = new Uint8Array();for (let i = 0; i < plainText.data.length; i += plainTextSplitLen ) {let updateMessage = plainText.data.subarray(i, i + plainTextSplitLen );let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };// 将原文按64字符进行拆分,循环调用doFinal进行加密,使用1024bit密钥时,每次加密生成128字节长度的密文let updateOutput = await cipher.doFinal(updateMessageBlob);let mergeText = new Uint8Array(cipherText.length + updateOutput.data.length);mergeText.set(cipherText);mergeText.set(updateOutput.data, cipherText.length);cipherText = mergeText;}let cipherBlob: cryptoFramework.DataBlob = { data: cipherText };return cipherBlob;
    }
    // 分段解密消息
    async function rsaDecryptBySegment(priKey: cryptoFramework.PriKey, cipherText: cryptoFramework.DataBlob) {let decoder = cryptoFramework.createCipher('RSA1024|PKCS1');await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, priKey, null);let cipherTextSplitLen = 128; // RSA密钥每次加密生成的密文字节长度计算方式:密钥位数/8let decryptText = new Uint8Array();for (let i = 0; i < cipherText.data.length; i += cipherTextSplitLen) {let updateMessage = cipherText.data.subarray(i, i + cipherTextSplitLen);let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };// 将密文按128字节进行拆分解密,得到原文后进行拼接let updateOutput = await decoder.doFinal(updateMessageBlob);let mergeText = new Uint8Array(decryptText.length + updateOutput.data.length);mergeText.set(decryptText);mergeText.set(updateOutput.data, decryptText.length);decryptText = mergeText;}let decryptBlob: cryptoFramework.DataBlob = { data: decryptText };return decryptBlob;
    }
    async function rsaEncryptLongMessage() {let message = "This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!";let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024"); // 创建非对称密钥生成器对象let keyPair = await asyKeyGenerator.generateKeyPair(); // 随机生成RSA密钥let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };let encryptText = await rsaEncryptBySegment(keyPair.pubKey, plainText);let decryptText = await rsaDecryptBySegment(keyPair.priKey, 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 rsaEncryptBySegment(pubKey: cryptoFramework.PubKey, plainText: cryptoFramework.DataBlob) {let cipher = cryptoFramework.createCipher('RSA1024|PKCS1');cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null);let plainTextSplitLen = 64;let cipherText = new Uint8Array();for (let i = 0; i < plainText.data.length; i += plainTextSplitLen ) {let updateMessage = plainText.data.subarray(i, i + plainTextSplitLen );let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };// 将原文按64字符进行拆分,循环调用doFinal进行加密,使用1024bit密钥时,每次加密生成128字节长度的密文let updateOutput = cipher.doFinalSync(updateMessageBlob);let mergeText = new Uint8Array(cipherText.length + updateOutput.data.length);mergeText.set(cipherText);mergeText.set(updateOutput.data, cipherText.length);cipherText = mergeText;}let cipherBlob: cryptoFramework.DataBlob = { data: cipherText };return cipherBlob;
    }
    // 分段解密消息
    function rsaDecryptBySegment(priKey: cryptoFramework.PriKey, cipherText: cryptoFramework.DataBlob) {let decoder = cryptoFramework.createCipher('RSA1024|PKCS1');decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, priKey, null);let cipherTextSplitLen = 128; // RSA密钥每次加密生成的密文字节长度计算方式:密钥位数/8let decryptText = new Uint8Array();for (let i = 0; i < cipherText.data.length; i += cipherTextSplitLen) {let updateMessage = cipherText.data.subarray(i, i + cipherTextSplitLen);let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage };// 将密文按128字节进行拆分解密,得到原文后进行拼接let updateOutput = decoder.doFinalSync(updateMessageBlob);let mergeText = new Uint8Array(decryptText.length + updateOutput.data.length);mergeText.set(decryptText);mergeText.set(updateOutput.data, decryptText.length);decryptText = mergeText;}let decryptBlob: cryptoFramework.DataBlob = { data: decryptText };return decryptBlob;
    }
    async function main() {let message = "This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!" +"This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!";let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator("RSA1024"); // 创建非对称密钥生成器对象let keyPair = await asyKeyGenerator.generateKeyPair(); // 随机生成RSA密钥let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) };let encryptText = rsaEncryptBySegment(keyPair.pubKey, plainText);let decryptText = rsaDecryptBySegment(keyPair.priKey, 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');}
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/30613.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【中南林业科技大学校园生存指南】序 | 大学之道

前言 本专栏所有内容来自同学们所提供的建议&#xff0c;已经征得收集者意见在此发布。 由于刚开始做&#xff0c;故后续内容会在积累一定程度时发布&#xff0c;感谢支持。 序 回顾大学四年&#xff0c;我仔细梳理了每一刻&#xff0c;把它们凝结成文字&#xff0c;记录下我…

Socket编程之多进程模型

一、多进程模型概述 基于最初的阻塞网络 I/O &#xff0c;若服务器要为多个客户端提供支持&#xff0c;在较为传统的手段中&#xff0c;多进程模型是常用的选择&#xff0c;即为每个客户端都分配一个进程来处理其请求。 服务器的主进程主要负责对客户连接的监听&#xff0c;一旦…

JSON 对象

JSON 对象 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成。它基于JavaScript编程语言的一个子集,但JSON是独立于语言的文本格式,代码中可以使用各种语言来解析和生成它。JSON格式通常用于数据交换、配置文件以…

vmware 虚拟机保留数据扩展C盘

1&#xff0c;在默认安装系统的时候&#xff0c;VMWARE一般给C盘50G&#xff0c;很多人想着够用了&#xff0c;但是后面慢慢的安装各种大型软件&#xff0c;游戏&#xff0c;才发现&#xff0c;悔时已晚。 2&#xff0c;有很多人虚拟机其实就是拿来游戏多开&#xff0c;但是当…

局域网共享文件夹怎么加密?方法很简单

局域网共享文件夹是企业内部信息、数据传递沟通的重要工具&#xff0c;而为了保护共享文件夹数据安全&#xff0c;我们需要使用专业的加密软件加密保护局域网共享文件夹。下面我们就来了解一下局域网共享文件夹加密方法。 局域网共享文件夹加密 在加密共享文件夹时&#xff0c…

PyCharm新手入门

前言 在之前《Python集成开发工具的选择》一文中介绍了python初学者可以使用Jupyter Notebook&#xff0c;Jupyter Notebook简单易用&#xff0c;可以用来练习代码编写&#xff0c;但是实际生产开发环境使用这个工具是远远不够用的&#xff0c;因为实际软件开发中需要软件调试…

计算机组成原理(Wrong Question)

目录 一、计算机系统概述 *1.1 计算机发展历程 1.2 计算机系统层次结构 1.3 计算机的性能指标 二、 数据的表示和运算 2.1 数制和编码 2.2 运算方法和运算电路 2.3 浮点数的表示与运算 三、存储系统 3.1 存储器概述 3.2 主存储器 3.3 主存储器与CPU的连接 3.4 外部…

面试技巧:正确回答JavaScript中Map和Object的选择问题

在JavaScript的面试中&#xff0c;对于何时使用Map和Object的选择问题&#xff0c;是一个常见的考察点。这两个数据结构都能存储键值对&#xff0c;但它们各有优势和适用场景。本文将深入探讨两者的区别&#xff0c;并通过实际代码示例来指导您如何选择。 基本概念 Map&#…

MFC扩展库BCGControlBar Pro v35.0

LINK : fatal error LNK1104: 无法打开文件“BCGCBPRO2800U140.lib” BCGControlBar v25.0版本 环境VS2015&#xff0c;在运行程序时出现提示错误 &#xff1a;LINK : fatal error LNK1104: 无法打开文件“BCGCBPRO2800U140.lib” 1、需要编译一下BGCControlBar&#xff0c;在…

串口rx + RAM + LCD

REVIEW 昨天摸鱼怪发现高两位的数据写入or读出存在问题&#xff1a; RAM 串口的简单应用-CSDN博客 1. 今日摸鱼任务 UART_RX RAM LCD 来显示一下是 rx or tx 的问题 2. 代码部分 rx_ram_lcd.v module rx_ram_lcd(input clk ,input reset_n ,input uart_rx ,output …

数据结构试题 20-21

真需要就死记吧 二叉树遍历-先序(非递归)【图解代码】_哔哩哔哩_bilibili 解释一下步骤&#xff1a; 一个循环为&#xff1a; 1.取节点 2.放右子树 3.放左子树 每次循环&#xff0c;都要从栈里取出一个节点 先放右子树&#xff0c;再放左子树 那这道题就是&#xff0c;先放1&am…

计算机组成原理必备知识点

计算机组成原理必备知识点 前言 本文档由本人复习计算机组成原理期末考试所总结&#xff0c;所有习题以及知识点的页数参考2025年王道计算机组成原理 中断处理过程 硬件完成 1.关中断 2.保存断点 3.中断服务程序寻址 中断程序完成 4.保存现场和屏蔽字 5.开中断 6.执…

【计算机网络仿真】b站湖科大教书匠思科Packet Tracer——实验2 MAC地址,IP地址,ARP协议

一、实验目的 1.掌握计算机网络的寻址问题&#xff1b; 2.验证MAC地址与IP地址的关系&#xff1b; 3.了解ARP协议的作用。 二、实验要求 1.使用Cisco Packet Tracer仿真平台&#xff1b; 2.观看B站湖科大教书匠仿真实验视频&#xff0c;完成对应实验。 三、实验内容 1.构建网络…

ASP.NET MVC企业级程序设计(增删,页面水平排列,字符串拼接,非空,添加框内默认提示)

目录 题目&#xff1a; 实现过程 控制器代码 DAL BLL Index Deile 题目&#xff1a; 实现过程 控制器代码 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using MvcApplication1.Models;namespac…

双通道-程控绝缘测试电阻箱的性能

双通道-程控绝缘测试电阻箱是高精度、高性能的电气测量设备&#xff0c;广泛应用于电力系统、电气设备、电子设备等领域。采用先进的数字式电阻测量技术&#xff0c;具有高精度、高稳定性的测量性能。其测量误差小于0.05%&#xff0c;能够满足各种精密测量的需求。 双通道-程控…

JAVA学习-练习试用Java实现“比较版本号”

问题&#xff1a; 给定两个版本号 version1 和 version2 &#xff0c;请比较它们。 版本号由一个或多个修订号组成&#xff0c;各修订号由一个 . 连接。每个修订号由 多位数字 组成&#xff0c;可能包含 前导零 。每个版本号至少包含一个字符。修订号从左到右编号&#xff0c;…

【ARMv8/ARMv9 硬件加速系列 3.5.2 -- SVE 向量寄存器 有多少位数?】

文章目录 SVE 向量寄存器SVE 向量寄存器大小SVE 可伸缩性的好处SVE 寄存器长度示例SVE 向量寄存器 在 ARMv9 架构中,包括其 Scalable Vector Extension (SVE) 和 Scalable Vector Extension 2 (SVE2) 的增强,向量寄存器(通常称为 Z 寄存器)的大小设计为可伸缩的,以便在不…

MacBook Air M3的电脑怎么样 新买MacBook Air提示内存不足 苹果电脑内存不够用怎么办

Apple的MacBook Air系列一直是轻薄便携笔记本电脑的代表&#xff0c;最新推出的MacBook Air M3因其出色的性能和优雅的设计而受到广泛关注。然而&#xff0c;许多用户在购买全新的MacBook Air后反应他们遇到了内存不足的提示。 本文将探讨MacBook Air M3的电脑怎么样&#xff0…

Java 集合框架:Vector、Stack 的介绍、使用、原理与源码解析

大家好&#xff0c;我是栗筝i&#xff0c;这篇文章是我的 “栗筝i 的 Java 技术栈” 专栏的第 015 篇文章&#xff0c;在 “栗筝i 的 Java 技术栈” 这个专栏中我会持续为大家更新 Java 技术相关全套技术栈内容。专栏的主要目标是已经有一定 Java 开发经验&#xff0c;并希望进…

设计模式——观察者模式(发布/订阅模式)

观察者模式(发布/订阅模式) 是一种行为模式&#xff0c;允许你定义一种订阅机制&#xff0c;可在对象事件发生时通知多个“观察”该对象的其他对象 观察者模式定义了一种一对多的依赖关系&#xff0c;让多个观察者对象同时监听某一主题对象。这个主题对象在状态发生变化时&am…