1/* 2 * Copyright (c) 2025 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { cryptoFramework } from '@kit.CryptoArchitectureKit'; 17import { buffer } from '@kit.ArkTS'; 18 19// 分段加密消息 20async function rsaEncryptBySegment(pubKey: cryptoFramework.PubKey, plainText: cryptoFramework.DataBlob) { 21 let cipher = cryptoFramework.createCipher('RSA1024|PKCS1'); 22 await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, pubKey, null); 23 let plainTextSplitLen = 64; 24 let cipherText = new Uint8Array(); 25 for (let i = 0; i < plainText.data.length; i += plainTextSplitLen) { 26 let updateMessage = plainText.data.subarray(i, i + plainTextSplitLen); 27 let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; 28 // 将原文按64字符进行拆分,循环调用doFinal进行加密,使用1024bit密钥时,每次加密生成128字节长度的密文 29 let updateOutput = await cipher.doFinal(updateMessageBlob); 30 let mergeText = new Uint8Array(cipherText.length + updateOutput.data.length); 31 mergeText.set(cipherText); 32 mergeText.set(updateOutput.data, cipherText.length); 33 cipherText = mergeText; 34 } 35 let cipherBlob: cryptoFramework.DataBlob = { data: cipherText }; 36 return cipherBlob; 37} 38 39// 分段解密消息 40async function rsaDecryptBySegment(priKey: cryptoFramework.PriKey, cipherText: cryptoFramework.DataBlob) { 41 let decoder = cryptoFramework.createCipher('RSA1024|PKCS1'); 42 await decoder.init(cryptoFramework.CryptoMode.DECRYPT_MODE, priKey, null); 43 let cipherTextSplitLen = 128; // RSA密钥每次加密生成的密文字节长度计算方式:密钥位数/8 44 let decryptText = new Uint8Array(); 45 for (let i = 0; i < cipherText.data.length; i += cipherTextSplitLen) { 46 let updateMessage = cipherText.data.subarray(i, i + cipherTextSplitLen); 47 let updateMessageBlob: cryptoFramework.DataBlob = { data: updateMessage }; 48 // 将密文按128字节进行拆分解密,得到原文后进行拼接 49 let updateOutput = await decoder.doFinal(updateMessageBlob); 50 let mergeText = new Uint8Array(decryptText.length + updateOutput.data.length); 51 mergeText.set(decryptText); 52 mergeText.set(updateOutput.data, decryptText.length); 53 decryptText = mergeText; 54 } 55 let decryptBlob: cryptoFramework.DataBlob = { data: decryptText }; 56 return decryptBlob; 57} 58 59async function rsaEncryptLongMessage() { 60 let message = 'This is a long plainTest! This is a long plainTest! This is a long plainTest!' + 61 'This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!' + 62 'This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!' + 63 'This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!' + 64 'This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!' + 65 'This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!' + 66 'This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!' + 67 'This is a long plainTest! This is a long plainTest! This is a long plainTest! This is a long plainTest!'; 68 let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024'); // 创建非对称密钥生成器对象 69 let keyPair = await asyKeyGenerator.generateKeyPair(); // 随机生成RSA密钥 70 let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buffer.from(message, 'utf-8').buffer) }; 71 let encryptText = await rsaEncryptBySegment(keyPair.pubKey, plainText); 72 let decryptText = await rsaDecryptBySegment(keyPair.priKey, encryptText); 73 if (plainText.data.toString() === decryptText.data.toString()) { 74 console.info('decrypt ok'); 75 console.info('decrypt plainText: ' + buffer.from(decryptText.data).toString('utf-8')); 76 } else { 77 console.error('decrypt failed'); 78 } 79} 80 81@Entry 82@Component 83struct Index { 84 @State message: string = 'RSA Segmentation Async'; 85 86 build() { 87 Column({ space: 5 }) { 88 Text(this.message) 89 .fontSize(25) 90 .fontWeight(FontWeight.Bold) 91 Button($r('app.string.call_rsa_segmentation_async')) 92 .onClick(async () => { 93 try { 94 await rsaEncryptLongMessage(); 95 this.message = 'RSA Segmentation Async Success'; 96 } catch (error) { 97 console.error(error); 98 this.message = 'RSA Segmentation Async Fail'; 99 } 100 }) 101 } 102 .height('100%') 103 .width('100%') 104 } 105}