鸿蒙OS开发问题:(ArkTS)【 RSA加解密,解决中文乱码等现象】

RSA加解密开始构建工具类就是举步维艰,官方文档虽然很全,但是还是有很多小瑕疵,在自己经过几天的时间,彻底解决了中文乱码的问题、分段加密的问题。

首先看官方示例代码(以RSA非对称加解密(多次调用doFinal实现分段)为例:):

import cryptoFramework from "@ohos.security.cryptoFramework"function stringToUint8Array(str) {var arr = [];for (var i = 0, j = str.length; i < j; ++i) {arr.push(str.charCodeAt(i));}var tmpArray = new Uint8Array(arr);return tmpArray;
}// 字节流转成可理解的字符串
function uint8ArrayToString(array) {let arrayString = '';for (let i = 0; i < array.length; i++) {arrayString += String.fromCharCode(array[i]);}return arrayString;
}function encryptLongMessagePromise() {let globalPlainText = "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 globalCipherOutput;let globalDecodeOutput;var globalKeyPair;let plainTextSplitLen = 64; // RSA每次加解密允许的原文长度大小与密钥位数和填充模式等有关,详细规格内容见overview文档let cipherTextSplitLen = 128; // RSA密钥每次加密生成的密文数据长度计算方式:密钥位数/8let keyGenName = "RSA1024";let cipherAlgName = "RSA1024|PKCS1";let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(keyGenName); // 创建非对称密钥生成器对象let cipher = cryptoFramework.createCipher(cipherAlgName); // 创建加密Cipher对象let decoder = cryptoFramework.createCipher(cipherAlgName); // 创建解密Decoder对象return new Promise((resolve, reject) => {setTimeout(() => {resolve("testRsaMultiDoFinal");}, 10);}).then(() => {return asyKeyGenerator.generateKeyPair(); // 生成rsa密钥}).then(keyPair => {globalKeyPair = keyPair; // 保存到密钥对全局变量return cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, globalKeyPair.pubKey, null);}).then(async () => {globalCipherOutput = [];// 将原文按64字符进行拆分,循环调用doFinal进行加密,使用1024bit密钥时,每次加密生成128B长度的密文for (let i = 0; i < (globalPlainText.length / plainTextSplitLen); i++) {let tempStr = globalPlainText.substr(i * plainTextSplitLen, plainTextSplitLen);let tempBlob = { data : stringToUint8Array(tempStr) };let tempCipherOutput = await cipher.doFinal(tempBlob);globalCipherOutput = globalCipherOutput.concat(Array.from(tempCipherOutput.data));}console.info(`globalCipherOutput len is ${globalCipherOutput.length}, data is: ${globalCipherOutput.toString()}`);return;}).then(() =>{return decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, globalKeyPair.priKey, null);}).then(async() => {globalDecodeOutput = [];// 将密文按128B进行拆分解密,得到原文后进行拼接for (let i = 0; i < (globalCipherOutput.length / cipherTextSplitLen); i++) {let tempBlobData = globalCipherOutput.slice(i * cipherTextSplitLen, (i + 1) * cipherTextSplitLen);let message = new Uint8Array(tempBlobData);let tempBlob = { data : message };let tempDecodeOutput = await decoder.doFinal(tempBlob);globalDecodeOutput += uint8ArrayToString(tempDecodeOutput.data);}if (globalDecodeOutput === globalPlainText) {console.info(`encode and decode success`);} else {console.info(`encode and decode error`);}return;}).catch(error => {console.error(`catch error, ${error.code}, ${error.message}`);})
}
let plainTextSplitLen = 64; // RSA每次加解密允许的原文长度大小与密钥位数和填充模式等有关,详细规格内容见overview文档

注意点:在解密中,这句代码就是产生中文乱码的关键。

鸿蒙OS开发更多内容↓点击HarmonyOS与OpenHarmony技术
鸿蒙技术文档开发知识更新库gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md在这。或+mau123789学习,是v喔

搜狗高速浏览器截图20240326151450.png

 
globalDecodeOutput += uint8ArrayToString(tempDecodeOutput.data);

好,加上我的代码

加密:

/*** 测试RSA加密*/
export function textRsaEncryption(value: string) {let keyGenName = "RSA1024";let cipherAlgName = "RSA1024|PKCS1";//64 RSA每次加解密允许的原文长度大小与密钥位数和填充模式等有关,详细规格内容见overview文档let plainTextSplitLen = 117;let globalKeyPair; //密钥对let globalEncryptionOutput; //加密输出let arrTest = StringUtils.string2Uint8Array1(value);//创建非对称密钥生成器对象let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(keyGenName);// 创建加密Cipher对象let cipherEncryption = cryptoFramework.createCipher(cipherAlgName);return new Promise((resolve, reject) => {setTimeout(() => {resolve("textRsaEncryption");}, 10);}).then(() => {let base64 = Base64.getInstance()let pubKeyBlob = { data: new Uint8Array(base64.decode(publicKey)) }let priKeyBlob = { data: new Uint8Array(base64.decode(privateKey)) }return asyKeyGenerator.convertKey(pubKeyBlob, priKeyBlob);}).then(keyPair => {globalKeyPair = keyPair; // 保存到密钥对全局变量return cipherEncryption.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, globalKeyPair.pubKey, null);}).then(async () => {globalEncryptionOutput = [];// 将原文按64字符进行拆分,循环调用doFinal进行加密,使用1024bit密钥时,每次加密生成128B长度的密文for (let i = 0; i < (arrTest.length / plainTextSplitLen); i++) {let tempArr = arrTest.slice(i * plainTextSplitLen, (i + 1) * plainTextSplitLen);let tempBlob = { data: tempArr };let tempCipherOutput = await cipherEncryption.doFinal(tempBlob);globalEncryptionOutput = globalEncryptionOutput.concat(Array.from(tempCipherOutput.data));}let base64 = Base64.getInstance()let enStr = base64.encode(globalEncryptionOutput)LogUtils.i("加密总长度:" + globalEncryptionOutput.length + "\n生成加密串:\n" + enStr)return enStr}).catch(error => {LogUtils.i(`加密异常, ${error.code}, ${error.message}`);})
}

解密:

/*** 测试RSA解密*/
export function textRsaDecryption(value: string) {let keyGenName = "RSA1024";let cipherAlgName = "RSA1024|PKCS1";// RSA密钥每次加密生成的密文数据长度计算方式:密钥位数/8let cipherTextSplitLen = 128;let globalKeyPair; //密钥对//创建非对称密钥生成器对象let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(keyGenName);// 创建解密Decoder对象let cipherDecryption = cryptoFramework.createCipher(cipherAlgName);return new Promise((resolve, reject) => {setTimeout(() => {resolve("textRsaEncryption");}, 10);}).then(() => {let base64 = Base64.getInstance()let pubKeyBlob = { data: new Uint8Array(base64.decode(publicKey)) }let priKeyBlob = { data: new Uint8Array(base64.decode(privateKey)) }return asyKeyGenerator.convertKey(pubKeyBlob, priKeyBlob);}).then(keyPair => {globalKeyPair = keyPair; // 保存到密钥对全局变量return cipherDecryption.init(cryptoFramework.CryptoMode.DECRYPT_MODE, globalKeyPair.priKey, null);}).then(async () => {let base64 = Base64.getInstance()let globalCipherOutput1 = new Uint8Array(base64.decode(value))let len = globalCipherOutput1.length//解密输出let globalDecryptionOutput = new Uint8Array(len);let globalOffset = 0// 将密文按128B进行拆分解密,得到原文后进行拼接for (let i = 0; i < (len / cipherTextSplitLen); i++) {let tempBlobData = globalCipherOutput1.subarray(i * cipherTextSplitLen, (i + 1) * cipherTextSplitLen);let message = new Uint8Array(tempBlobData);let tempBlob = { data: message };let tempDecodeOutput = await cipherDecryption.doFinal(tempBlob);//存入数组 解决边累加边转中文时 字节错乱出现乱码globalDecryptionOutput.set(tempDecodeOutput.data, globalOffset)//偏移量globalOffset += tempDecodeOutput.data.byteLength}let result = StringUtils.uint8Array2String(globalDecryptionOutput)LogUtils.i("解密串:cipherAlgName[" + cipherAlgName + "]\n" + result);}).catch(error => {LogUtils.i(`解密异常,cipherAlgName[${cipherAlgName}] ${error.code}, ${error.message}`);})
}

运行代码:

Text("RSA加解密联测").TextNormalStyle().fontSize(16).fontWeight(FontWeight.Normal).fontColor(Color.White).textAlign(TextAlign.Center).margin({ left: 5 }).layoutWeight(1).onClick(() => {let globalPlainText = ""globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "一二三四五六七八九十"globalPlainText += "123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/123456789/"globalPlainText += "SDK向DevEco Studio提供全量API,DevEco Studio识别开发者项目中选择的设备形态,找到该设备的支持能力集,筛选支持能力集包含的API并提供API联想"//textRsaEncryption(globalPlainText).then(enStr => {if (enStr) textRsaDecryption(enStr)})})}.width('100%').height(50).margin({ top: 10 }).padding(5)

运行结果:

cke_155247.png

终于大功告成!!

最后呢,很多开发朋友不知道需要学习那些鸿蒙技术?鸿蒙开发岗位需要掌握那些核心技术点?为此鸿蒙的开发学习必须要系统性的进行。

而网上有关鸿蒙的开发资料非常的少,假如你想学好鸿蒙的应用开发与系统底层开发。你可以参考这份资料,少走很多弯路,节省没必要的麻烦。由两位前阿里高级研发工程师联合打造《鸿蒙NEXT星河版OpenHarmony开发文档》里面内容包含了(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、Harmony南向开发、鸿蒙项目实战等等)鸿蒙(Harmony NEXT)技术知识点

如果你是一名Android、Java、前端等等开发人员,想要转入鸿蒙方向发展。可以直接领取这份资料辅助你的学习。下面是鸿蒙开发的学习路线图。

高清完整版请点击→《鸿蒙NEXT星河版开发学习文档》

针对鸿蒙成长路线打造的鸿蒙学习文档。话不多说,我们直接看详细资料鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开发入门教学视频,帮助大家在技术的道路上更进一步。

《鸿蒙 (OpenHarmony)开发学习视频》

图片

《鸿蒙生态应用开发V2.0白皮书》

图片

《鸿蒙 (OpenHarmony)开发基础到实战手册》

获取这份鸿蒙星河版学习资料,请点击→《鸿蒙NEXT星河版开发学习文档》

OpenHarmony北向、南向开发环境搭建

图片

《鸿蒙开发基础》

  1. ArkTS语言

  2. 安装DevEco Studio

  3. 运用你的第一个ArkTS应用

  4. ArkUI声明式UI开发

  5. .……

图片

《鸿蒙开发进阶》

  1. Stage模型入门

  2. 网络管理

  3. 数据管理

  4. 电话服务

  5. 分布式应用开发

  6. 通知与窗口管理

  7. 多媒体技术

  8. 安全技能

  9. 任务管理

  10. WebGL

  11. 国际化开发

  12. 应用测试

  13. DFX面向未来设计

  14. 鸿蒙系统移植和裁剪定制

  15. ……

图片

《鸿蒙开发实战》

  1. ArkTS实践

  2. UIAbility应用

  3. 网络案例

  4. ……

图片

 获取这份鸿蒙星河版学习资料,请点击→《鸿蒙NEXT星河版开发学习文档》

总结

鸿蒙—作为国家主力推送的国产操作系统。部分的高校已经取消了安卓课程,从而开设鸿蒙课程;企业纷纷跟进启动了鸿蒙研发

并且鸿蒙是完全具备无与伦比的机遇和潜力的;预计到年底将有 5,000 款的应用完成原生鸿蒙开发,未来将会支持 50 万款的应用那么这么多的应用需要开发,也就意味着需要有更多的鸿蒙人才鸿蒙开发工程师也将会迎来爆发式的增长,学习鸿蒙势在必行!

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

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

相关文章

TikTok养号怎么做?打破0播放的前提是做好这些

TikTok养号的重要性不必多少&#xff0c;不仅可以在创号初期保障账号安全&#xff0c;后期的账号流量也需要以前期养好账号为前提。下面就给大家分享如何养号的真实操作攻略&#xff01; 一、为什么要养号 &#xff08;1&#xff09;提高系统推荐精准度 系统不了解新账户人设…

spring boot 生成PDF模板文件

1、主要目录 2、maven依赖 <!--工具类依赖--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.19</version></dependency><dependency><groupId>com.alibaba&l…

56. 合并区间(力扣LeetCode)

文章目录 56. 合并区间题目描述思路贪心算法方法一&#xff1a;直接在res中修改代码逻辑梳理&#xff1a; 方法二&#xff1a;在原数组中插入一个超出题目范围的数组代码逻辑梳理&#xff1a; 56. 合并区间 题目描述 以数组 intervals 表示若干个区间的集合&#xff0c;其中单…

律甲法务OA平台:信鸥科技引领法律行业新篇章

随着信息技术的飞速发展&#xff0c;法律行业也迎来了数字化转型的重要时刻。在这个信息化、智能化的时代&#xff0c;如何运用科技手段提升法律服务的质量和效率&#xff0c;成为法律行业亟待解决的问题。信鸥科技&#xff0c;作为业界的佼佼者&#xff0c;凭借其深厚的技术积…

Kafka详细教程(一)

总体目录 1、什么是消息队列 消息队列&#xff0c;英文名&#xff1a;Message Queue&#xff0c;经常缩写为MQ。从字面上来理解&#xff0c;消息队列是一种用来存储消息的队列 。来看一下下面的代码 // 1.创建一个保存字符串的队列Queue<String> queue new LinkedList&…

使用patchelf解决vscode远程连接不支持低版本glibc的问题

使用patchelf解决vscode远程连接不支持低版本glibc的问题 目录 使用patchelf解决vscode远程连接不支持低版本glibc的问题1. 动态链接库下载2. 用 patchelf 修改 vscode-server 依赖的 glibc 版本 VScode 1.86 版本的 remote 要求 glibc 2.28 及以上&#xff0c;于是在各种旧版本…

基于RK3588多can口多串口机器人全功能板

RK3588机器人控制器有五大技术优势 1. 内置多种功能强大的嵌入式硬件引擎&#xff0c;支持8K60fps 的 H.265 和 VP9 解码器、8K30fps 的 H.264 解码器和 4K60fps 的 AV1 解码器&#xff1b;支持 8K30fps 的 H.264 和H.265 编码器&#xff0c;高质量的 JPEG 编码器/解码器&…

不显示excel中零值方法

excel中想让数字0不显示的方法如下&#xff1a; √去掉则数字格式0不再显示 。若找不到此项&#xff0c;运行以下代码即可&#xff1a; Sub 去除excel中零值() ActiveWindow.DisplayZeros False 不显示零值 End Sub altf11打开vba idea&#xff0c;插入->模块&#xff…

UniRepLKNet:一种用于音频、视频、点云、时间序列和图像识别的通用感知大核卷积神经网络

论文: https://arxiv.org/abs/2311.15599 模型: https://huggingface.co/DingXiaoH/UniRepLKNet/tree/main 主页&#xff1a;https://invictus717.github.io/UniRepLKNet/ contribution 提出了四条guide line用于设计大核CNN架构模型&#xff0c;用于图像识别&#xff0c;语…

elementui日期时间选择框自定义组件

1.需求场景 业务中需要&#xff0c;日期选择框方便客户对日期的选择&#xff08;比如近5天&#xff0c;本周&#xff0c;本月&#xff0c;本年等等&#xff09;&#xff0c;并按小时展示。 2.组件代码MyDateTimeChange.vue <template><el-date-pickerv-model"…

鸿蒙开发之ArkUI组件常用组件图片和文本

ArkUI即方舟开发框架是HarmonyOS应用的UI开发提供了完整的基础设施&#xff0c;包括简洁的UI语法、丰富的UI功能&#xff08;组件、布局、动画以及交互事件&#xff09;&#xff0c;以及实时界面预览工具等&#xff0c;可以支持开发者进行可视化界面开发。 开发文档地址 &…

国赛大纲解读

1. 第一部分,是针对5G基础知识的掌握,第二部分是人工智能基本算法的掌握,就是人工智能的应用,用5G+人工智能(AI算法)进行网络优化的问题,要有网络优化的基础知识,比如说:某个区域的覆盖问题,覆盖特别差,但有数据,覆盖电频,srp值这些数据给你,根据数据来判断是…

设计模式——行为型——策略模式Strategy

Q&#xff1a;策略模式的特点 A&#xff1a; 具体算法从具体的业务方法中独立出来策略模式是同行为的不同实现 Q&#xff1a;什么时候使用策略模式 A&#xff1a;多个if-else使用策略模式 收费对象类 public class CashContext {private CashStrategy cashStrategy;public…

【C++入门】 初见,单推,与C++的第一次约会

关注小庄 顿顿解馋(ᕑᗢᓫ∗)˒ 引言&#xff1a;本篇博客我们开始与C的第一次约会&#xff0c;C是兼容c的&#xff0c;本篇博客我们将了解到C关键字有哪些&#xff0c;C命名空间&#xff0c;C输入与输出和缺省参数的内容&#xff0c;请放心食用 ~ 文章目录 一 &#x1f3e0; C…

文献阅读工具-->Adobe pdf + 有道词典

Adobe pdf 有道词典 最近一直在考虑用什么文献阅读工具&#xff0c;痛点无非就是想用翻译功能&#xff0c;Adobe pdf的添加注释已经很好用了&#xff0c;使用了zotero&#xff0c;感觉不行&#xff08;不能直接对原文件修改&#xff0c;有副本&#xff0c;麻烦&#xff09;。…

excel匹配替换脱敏身份证等数据

假如excel sheet1中有脱敏的身份证号码和姓名&#xff0c;如&#xff1a; sheet2中有未脱敏的数据数据 做法如下&#xff1a; 1、在sheet2的C列用公式 LEFT(A2,6)&REPT("*",8)&RIGHT(A2,4) 做出脱敏数据&#xff0c;用来与sheet1的脱敏数据匹配 2、在sheet…

AWS基础网络产品及协同架构-Networking

简介 一个完整的AWS网络架构图&#xff0c;包含了如下能力&#xff1a; Users (用户): 表示使用AWS服务的用户或系统。 SaaS (软件即服务): 表示在AWS上运行的软件服务&#xff0c;如企业微信可能作为SaaS提供。 example.com?: 这可能是一个示例域名&#xff0c;用于展示如何…

快速上手Spring Cloud 十:Spring Cloud与微前端

快速上手Spring Cloud 一&#xff1a;Spring Cloud 简介 快速上手Spring Cloud 二&#xff1a;核心组件解析 快速上手Spring Cloud 三&#xff1a;API网关深入探索与实战应用 快速上手Spring Cloud 四&#xff1a;微服务治理与安全 快速上手Spring Cloud 五&#xff1a;Spring …

分享多种mfc100u.dll丢失的解决方法(一键修复DLL丢失的方法)

在使用电脑过程中&#xff0c;我们经常会遇到一些陌生的DLL文件&#xff0c;例如mfc100u.dll。这些DLL文件是动态链接库&#xff08;Dynamic Link Libraries&#xff09;的缩写&#xff0c;它们包含了可以被多个程序共享的代码和数据。今天&#xff0c;我们将深入探讨mfc100u.d…

深度学习:基于PyTorch的模型解释工具Captum

深度学习&#xff1a;基于PyTorch的模型解释工具Captum 引言简介示例安装解释模型的预测解释文本模型情绪分析问答 解释视觉模型特征分析特征消融鲁棒性 解释多模态模型 引言 当我们训练神经网络模型时&#xff0c;我们通常只关注模型的整体性能&#xff0c;例如准确率或损失函…