• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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}