【鸿蒙实战开辟】HarmonyOS非对称加密-RSA

打印 上一主题 下一主题

主题 552|帖子 552|积分 1656

1. 先容

本篇将先容RSA非对称加密,官方也给出了一些样例使用代码,可供开辟者参考。
本篇从实践出发,完整的通过代码方式来深入相识HarmonyOS中的非对称加密用法。

2. 基础概念

字符串样例:RSA1024|PKCS1|MD5|MGF1_MD5
1.密钥算法 : RSA
2.密文组长度 : 1024
3.填充模式 : PKCS1
4.择要: MD5
5.择要掩码: MGF1_MD5
关于“RSA算法”,“填充模式”, “择要”, "择要掩码"的具体概念,可自行搜索。
3. 实践

加密使用的测试数据源有三个,具体见下图
1.“92字节” (即,占用了92个字节的字符串)
2.“117字节” (即,占用了117个字节的字符串)
3.“128字节” (即,占用了128个字节的字符串)
3.1 MMI入口




3.2 RSA加解密

●RSA加密算法密文分组长度有七种:512,718,1024,2048,3072,4096,8192;
●支持3种填充模式:NoPadding, PKCS1, PKCS1_OAEP;
●在PCKCS1_OAEP填充模式下,支持六种择要:MD5, SHA1, SHA224, SHA256, SHA384, SHA512;
●在PCKCS1_OAEP填充模式下,支持六种择要掩码:MGF1_MD5, MGF1_SHA1, MGF1_SHA224, MGF1_SHA256, MGF1_SHA384, MGF1_SHA512
本篇仅以1024密文组长度做为实践验证,默认选择“128字节”数据集
片段代码以 “RSA1024|PKCS1_OAEP|MD5|MGF1_MD5” 为例

3.2.1 加密

生成对动态密钥
  1. //导入加密框架
  2. import cryptoFramework from '@ohos.security.cryptoFramework';
  3. ......
  4. //创建密钥生成器,参数为(密钥算法+密文组长度+素数,如:RSA1024|PRIMES_2)
  5. let symKeyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024|PRIMES_2');
  6. //生成对称密钥
  7. let promiseSymKey = symKeyGenerator.generateKeyPair();
  8. //获取密钥
  9. promiseSymKey( key => {
  10.    
  11. //密钥对
  12. this.keyPair = rsaKeyPair;
  13. })
复制代码
初始化Cipher
  1. //创建Cipher
  2. globalCipher = cryptoFramework.createCipher('RSA1024|PKCS1_OAEP|MD5|MGF1_MD5');
  3. //使用公钥初始化Cipher
  4. let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE;
  5. globalCipher.init(mode, this.keyPair.pubKey, null)
复制代码
加密
  1. //文字转换为Uint8Array
  2. const encoder = new util.TextEncoder()
  3. let u8a_encoder = encoder.encodeInto('测试')
  4. //封装Uint8Array 数据,必须是一个带data属性的对象
  5. let plainText = { data: u8a_encoder };
  6. //开始加密
  7. let promiseUpdate = globalCipher.doFinal(plainText);
  8. //获取加密结果
  9. promiseUpdate( result => {
  10.    //密文
  11.    let this.cipherText = result.data
  12.    
  13. })
复制代码
至此,加密已经结束。
3.2.2 解密

生成密钥对象
  1. //创建密钥生成器,参数为(密钥算法+密文组长度+素数,如:RSA1024|PRIMES_2)
  2. let symKeyGenerator = cryptoFramework.createSymKeyGenerator('RSA1024|PRIMES_2');
  3. //密钥生成器使用密钥数据,开始生成密钥对象
  4. symKeyGenerator.convertKey(this.keyPair.pubKey.getEncoded(), this.keyPair.priKey.getEncoded()).then( key => {
  5.    //key 为生成的密钥对象
  6.    
  7. })
复制代码
初始化Cipher
  1. //创建Cipher
  2. globalCipher = cryptoFramework.createCipher('RSA1024|PKCS1_OAEP|MD5|MGF1_MD5');
  3. //初始化Cipher,参数keyPair.priKey由第一步生成的
  4. let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
  5. globalCipher.init(mode, keyPair.priKey
  6. , null)
复制代码
解密
  1. //this.cipherText 代表密文,本篇文章中,此值来源于上述加密结果
  2. globalCipher.doFinal({ data: this.cipherText })
复制代码
3.2.3 留意点

这些是基于RSA1024场景下,实践出的结论
1.NoPadding填充模式下,明文字节长度必须为128个字节长度
2.PKCS1填充模式下,明文字节长度最大为117个字节
3.PKCS1_OAEP填充模式下,明文字节长度最大为92个字节
4.择要和择要掩码只有在PKCS1_OAEP填充模式下,才会出现在初始化Cipher参数中
3.2.4 源码

  1. import cryptoFramework from '@ohos.security.cryptoFramework';
  2. import util from '@ohos.util';
  3. import Logger from '../../common/Logger';
  4. import OriginData from './OriginData';
  5. import emitter from "@ohos.events.emitter";
  6. /**
  7. * 非对称密钥
  8. *    密钥算法:RSA
  9. *    密钥规格格式:(密钥算法名称 + 密钥长度) | 素数
  10. *    密钥长度:512,718,1024, 2048, 3072, 4096, 8192
  11. *    密钥规格列表:AES512|PRIMES_2, RSA768|PRIMES_2, RSA1024|PRIMES_2, RSA1024|PRIMES_3, RSA2048|PRIMES_2
  12. *               RSA2048|PRIMES_3, RSA3072|PRIMES_2, RSA3072|PRIMES_3, RSA4096|PRIMES_2, RSA4096|PRIMES_3
  13. *               RSA4096|PRIMES_4, RSA8192|PRIMES_2, RSA8192|PRIMES_3, RSA8192|PRIMES_4, RSA8192|PRIMES_5
  14. *
  15. * 非对称对称加密
  16. *    加密算法:RSA
  17. *    加密规格格式:密钥算法名称 + 密钥长度 + 填充模式 + [摘要 + 摘要掩码]
  18. *    密钥长度:512,718,1024, 2048, 3072, 4096, 8192
  19. *    填充模式:NoPadding,PKCS1,PKCS1_OAEP
  20. *    摘要: MD5, SHA1, SHA224, SHA256, SHA384, SHA512
  21. *    摘要掩码: MGF1_MD5, MGF1_SHA1, MGF1_SHA224, MGF1_SHA256, MGF1_SHA384, MGF1_SHA512
  22. *    加密规格样例:RSA512|NoPadding,RSA512|PKCS1,RSA512|PKCS1_OAEP|MD5|MGF1_SHA224
  23. *
  24. *
  25. */
  26. class TestAsyRSAEncryptDecrypt {
  27.   private  keyPair: cryptoFramework.KeyPair;
  28.   private cipherText: Uint8Array;
  29.   private algorithmWithLength: string = 'RSA1024'
  30.   private paddingMode: string = 'NoPadding' //NoPadding,PKCS5,PKCS1_OAEP
  31.   private digest: string = 'MD5' //MD5、SHA1、SHA224、SHA256、SHA384、SHA512
  32.   private digestMask: string = 'MGF1_MD5' //MGF1_MD5、MGF1_SHA1、MGF1_SHA224、MGF1_SHA256、MGF1_SHA384、MGF1_SHA512
  33.   //对称加密:RSA1024|PKCS1_OAEP|MD5|MGF1_MD5
  34.   testAsyRASEncrypt(paddingMode: string, digest: string, digestMask, dataSource:number) {
  35.     let globalCipher: cryptoFramework.Cipher
  36.     let originData: string
  37.     if(dataSource == 92){
  38.       originData = OriginData.RSA_1024_CONTENT_92
  39.     } else if(dataSource == 117){
  40.       originData = OriginData.RSA_1024_CONTENT_117
  41.     } else {
  42.       originData = OriginData.RSA_1024_CONTENT_128
  43.     }
  44.     this.paddingMode = paddingMode
  45.     this.digest = digest
  46.     this.digestMask = digestMask
  47.     let symKeyGenerator = cryptoFramework.createAsyKeyGenerator(this.algorithmWithLength+'|PRIMES_2');
  48.     let promiseSymKey = symKeyGenerator.generateKeyPair();
  49.     promiseSymKey.then( rsaKeyPair => {
  50.       this.keyPair = rsaKeyPair;
  51.       let p: string = ''
  52.       for(let a of rsaKeyPair.priKey.getEncoded().data){
  53.         p = p.concat(a+',')
  54.       }
  55.       Logger.d('原始私钥',p)
  56.       let spec = ''
  57.       if(this.paddingMode == 'PKCS1_OAEP'){
  58.         spec = this.algorithmWithLength + '|' + this.paddingMode + '|' + this.digest + '|' + this.digestMask
  59.       } else {
  60.         spec = this.algorithmWithLength + '|' + this.paddingMode
  61.       }
  62.       console.log('加密规格:', spec)
  63.       globalCipher = cryptoFramework.createCipher(spec);
  64.       let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE;
  65.       return globalCipher.init(mode, this.keyPair.pubKey, null);
  66.     }).then(() => {
  67.         const encoder = new util.TextEncoder()
  68.         let u8a_encoder = encoder.encodeInto(originData)
  69.         Logger.d('开始加密')
  70.         let plainText = { data: u8a_encoder };
  71.         let promiseUpdate = globalCipher.doFinal(plainText);
  72.         return promiseUpdate;
  73.       }).then(updateOutput => {
  74.         if(updateOutput != null && updateOutput.data != null){
  75.           this.cipherText = updateOutput.data
  76.           console.log('密文:', this.cipherText)
  77.         }
  78.       }).then(() => {
  79.         this.testSymAESDecrypt()
  80.         return
  81.       }).catch( error => {
  82.          console.error(`catch error, ${error.code}, ${error.message}`);
  83.          this.notificationStatus('加密中-error',  error.code + '-' +  error.message)
  84.       })
  85.   }
  86.   //非对称解密: RSA1024|PKCS1_OAEP|MD5|MGF1_MD5
  87.   testSymAESDecrypt() {
  88.     let globalCipher: cryptoFramework.Cipher
  89.     let symKeyGenerator = cryptoFramework.createAsyKeyGenerator(this.algorithmWithLength);
  90.     // 根据指定的二进制密钥数据,生成对称密钥对象
  91.     symKeyGenerator.convertKey(this.keyPair.pubKey.getEncoded(), this.keyPair.priKey.getEncoded())
  92.       .then( keyPair => {
  93.         console.log('解密-初始化Cipher')
  94.         let spec = ''
  95.         if(this.paddingMode == 'PKCS1_OAEP'){
  96.           spec = this.algorithmWithLength + '|' + this.paddingMode + '|' + this.digest + '|' + this.digestMask
  97.         } else {
  98.           spec = this.algorithmWithLength + '|' + this.paddingMode
  99.         }
  100.         globalCipher = cryptoFramework.createCipher(spec);
  101.         let mode = cryptoFramework.CryptoMode.DECRYPT_MODE;
  102.         let p: string = ''
  103.         for(let a of keyPair.priKey.getEncoded().data){
  104.           p = p.concat(a+',')
  105.         }
  106.         Logger.d('解密私钥',p)
  107.         globalCipher.init(mode, keyPair.priKey, null);
  108.         return
  109.       })
  110.       .then(() => {
  111.         console.log('开始解密', '密文')
  112.         return globalCipher.doFinal({ data: this.cipherText });
  113.       })
  114.       .then( updateOutput => {
  115.         let textDecoder = util.TextDecoder.create()
  116.         let key = textDecoder.decodeWithStream(updateOutput.data);
  117.         Logger.d('解密完成1: ', key);
  118.         this.notificationStatus('解密完成', key)
  119.       })
  120.       .catch(error => {
  121.         console.error(`catch error, ${error.code}, ${error.message}`);
  122.         this.notificationStatus('解密中-error',  error.code + '-' +  error.message)
  123.       })
  124.   }
  125.    notificationStatus(status:string, result: string){
  126.      // 定义一个eventId为1的事件,事件优先级为Low
  127.      let event = {
  128.        eventId: 202404063287,
  129.        priority: emitter.EventPriority.HIGH
  130.      };
  131.      let eventData = {
  132.        data: {
  133.          "content": result,
  134.          'status': status,
  135.        }
  136.      };
  137.      // 发送eventId为1的事件,事件内容为eventData
  138.      emitter.emit(event, eventData);
  139.    }
  140. }
  141. export default new TestAsyRSAEncryptDecrypt();
复制代码
3.4 实践结果

以1024长度分组,“92字节”,“117字节”, “128字节”作为数据源
数据集
  1. //117字节,PKCS1 M最大
  2. public static readonly RSA_1024_CONTENT_117: string =
  3.         "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567"
  4. //92字节,PKCS1_OAEP 最大
  5. public static readonly RSA_1024_CONTENT_92: string =
  6.   "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012"
  7. //128字节,RSA|NoPadding 固定
  8. public static readonly RSA_1024_CONTENT_128: string =
  9.   "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
  10.   + "1234567890123456789012345678"
复制代码
组合实验结果

1.NoPadding填充模式下,使用“128字节”数据源, ✅
2.PKCS1填充模式下,使用“117字节”数据源 ,✅
3.PKCS1_OAEP填充模式下,使用“92字节”数据源 ,组合所有择要和择要掩码,✅
写在最后

有许多小搭档不知道学习哪些鸿蒙开辟技术?不知道需要重点掌握哪些鸿蒙应用开辟知识点?而且学习时频仍踩坑,终极浪费大量时间。所以有一份实用的鸿蒙(HarmonyOS NEXT)资料用来跟着学习是非常有须要的。

这份鸿蒙(HarmonyOS NEXT)资料包含了鸿蒙开辟必掌握的焦点知识要点,内容包含了(ArkTS、ArkUI开辟组件、Stage模型、多端部署、分布式应用开辟、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、openHarmony南向开辟、鸿蒙项目实战等等)鸿蒙(HarmonyOS NEXT)技术知识点。
希望这一份鸿蒙学习资料可以大概给大家带来资助,有需要的小搭档自行领取,限时开源,先到先得~无套路领取!!

获取这份完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

鸿蒙(HarmonyOS NEXT)最新学习路线


有了路线图,怎么能没有学习资料呢,小编也准备了一份联合鸿蒙官方发布笔记整理收纳的一套系统性的鸿蒙(OpenHarmony )学习手册(共计1236页)与鸿蒙(OpenHarmony )开辟入门讲授视频,内容包含:ArkTS、ArkUI、Web开辟、应用模型、资源分类…等知识点。

获取以上完整版高清学习路线,请点击→纯血版全套鸿蒙HarmonyOS学习资料

《鸿蒙 (OpenHarmony)开辟入门讲授视频》


《鸿蒙生态应用开辟V3.0白皮书》


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

OpenHarmony北向、南向开辟情况搭建

《鸿蒙开辟基础》

●ArkTS语言
●安装DevEco Studio
●运用你的第一个ArkTS应用
●ArkUI声明式UI开辟
.……

《鸿蒙开辟进阶》

●Stage模型入门
●网络管理
●数据管理
●电话服务
●分布式应用开辟
●关照与窗口管理
●多媒体技术
●安全技能
●使命管理
●WebGL
●国际化开辟
●应用测试
●DFX面向未来设计
●鸿蒙系统移植和裁剪定制
……

《鸿蒙进阶实战》

●ArkTS实践
●UIAbility应用
●网络案例
……

获取以上完整鸿蒙HarmonyOS学习资料,请点击→纯血版全套鸿蒙HarmonyOS学习资料


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊雷无声

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表