鸿蒙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.hqwc.cn/news/572724.html

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

相关文章

DevSecOps平台架构系列-互联网企业私有化DevSecOps平台典型架构

目录 一、概述 二、私有化DevSecOps平台建设思路 2.1 采用GitOps公有云建设 2.2 采用GitOps私有云建设 2.3 总结 三、GitOps及其生态组件 3.1 采用GitOps的好处 3.1.1 周边生态系统齐全 3.1.2 便于自动化的实现 3.1.3 开发人员属性GitOps 3.2 GitOps部分生态组件介绍…

苹果 WWDC 24 将举行;高通、谷歌、英特尔等联合开发 AI 软件;艺术家谈及使用 Sora 创作视频体验

▶ 苹果WWDC 24 将于当地时间 6 月 10 日召开 3 月 27 日凌晨&#xff0c;苹果官宣将于当地时间 6 月 10 日举行今年的全球开发者发布大会。 苹果全球营销高级副总裁 Greg Joswiak 在社交媒体上表示&#xff1a;「在您的日历标记上 WWDC24 吧。这场活动无疑会令人惊喜&#xf…

如何使用极狐GitLab 自定义 Pages 根域名

本文作者&#xff1a;徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了极狐GitLab Pages …

前端埋点全解及埋点SDK实现方式

一、什么是埋点 所谓“埋点”&#xff0c;是数据采集领域&#xff08;尤其是用户行为数据采集领域&#xff09;的术语&#xff0c;指的是针对特定用户行为或事件进行捕获、处理和发送的相关技术及其实施过程。比如用户某个icon点击次数、观看某个视频的时长等等。 埋点…

春秋云境CVE-2023-1313

简介 cockpit在2.4.1版本之前存在任意文件上传漏洞PS&#xff1a;通过在浏览器中打开/install来运行安装 正文 来到靶场&#xff0c;首先进行弱口令爆破&#xff0c;发现没用&#xff0c;那么只好老老实实的看靶场提示 先来访问/install 访问后就可以进行登录了&#xff0c…

【Bug-ModuleNotFoundError: No module named ‘models‘】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Python &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; 出现这个错误&#xff1a; 出现了ModuleNotFoundError: No module named models’的问题。 文件在Model…

【线上环境更换国产麒麟银河服务器之后FTP无法解析文件字符串的问题】

默认使用的 UnixFTPEntryParser没有办法解析麒麟系统下的文件字符串&#xff01;&#xff01;&#xff01; 所以通过设置FTPClientConfig设置系统编码解析类型 FTPClientConfig conf new FTPClientConfig(FTPClientConfig.SYST_NT);ftpClient.configure(conf);好了&#xff0c…

区块链食品溯源案例实现(一)

引言&#xff1a; 食品安全问题一直是社会关注的热点&#xff0c;而食品溯源作为解决食品安全问题的重要手段&#xff0c;其重要性不言而喻。传统的食品溯源系统往往存在数据易被篡改、信息不透明等问题&#xff0c;而区块链技术的引入&#xff0c;为食品溯源带来了革命性的变革…

持续集成与版本控制的相关概念

目录 一、持续集成 1.1 持续集成基本概念 1.1.1 持续集成的含义 1.1.1.1 持续集成流程是依赖产品版本迭代和版本分支而产生的 1.1.1.2 持续集成流程中包含的内容 1.1.2 传统打包模式说明 1.1.2.1 传统打包模式概述 1.1.2.2 传统打包模式问题 1.1.3 持续集成模式 1.1.…

腾讯云免费云服务器申请流程详解

随着云计算的普及&#xff0c;越来越多的企业和个人开始选择使用云服务器。腾讯云作为国内领先的云计算服务提供商&#xff0c;为用户提供了丰富的云产品和服务。本文将为大家详细介绍腾讯云免费云服务器的申请流程。 一、注册腾讯云账号 首先&#xff0c;需要注册一个腾讯云账…

TCP/IP协议族解析

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

蓝桥杯真题讲解:网络稳定性(Kruskal重构树+LCA)

蓝桥杯真题讲解&#xff1a;网络稳定性&#xff08;Kruskal重构树LCA&#xff09; 一、视频讲解二、正解代码 一、视频讲解 蓝桥杯真题讲解&#xff1a;网络稳定性&#xff08;Kruskal重构树LCA&#xff09; 二、正解代码 //kruskal重构树 lca #include<bits/stdc.h>…