加解密算法库框架
介绍
本示例使用@ohos.security.cryptoFramework相关接口实现了对文本文件的加解密、签名验签操作。
实现场景如下:
1)软件需要加密存储本地文本文件,需要调用加解密算法库框架选择密钥文本文件,对本地文本文件进行加密,其中密钥文本文件可由加解密算法库生成。
2)软件需要解密存储本地文本文件,需要调用加解密算法库框架选择密钥文本文件,对本地文本文件进行解密,其中密钥文本文件可由加解密算法库生成。
3)软件需要对存储本地文本文件签名,调用加解密算法库框架选择密钥文本文件,对本地文本文件进行完整性签名,其中密钥文本文件可由加解密算法库生成。
4)软件需要验证存储本地文本文件的签名完整性,需要调用加解密算法库框架选择密钥文本文件与签名文件,对文件进行验签,其中密钥文本文件可由加解密算法库生成。
效果预览
使用说明
1.点击主页面tab栏的加密 ,在加密界面点击打开文件 ,通过文件选择器选择文本文件,选择完毕自动返回加密界面, 其内容显示在文件内容 文本框中, 点击选择密钥 ,选择密钥文件,如果没有密钥文件,可以通过在加密界面点击随机生成AES密钥 ,生成并通过文件选择器保存密钥文件。 选择完文本文件和密钥文件后,点击加密 按钮,完成加密,并通过文件选择器保存密文文件。 下方加密内容文本框中显示加密后的消息内容。
2.点击主页面tab栏的解密 ,在解密界面点击打开文件 ,通过文件选择器选择文本文件,选择完毕自动返回解密界面, 其内容显示在文件内容 文本框中, 点击选择密钥 ,选择和加密相同 的密钥文件。 选择完文本文件和密钥文件后,点击解密 按钮,完成解密,并通过文件选择器保存明文文件。 下方解密内容文本框中显示解密后的消息内容。
3.点击主页面tab栏的签名 ,在签名界面点击打开文件 ,通过文件选择器选择文本文件,选择完毕自动返回签名界面, 其内容显示在文件内容 文本框中, 点击选择密钥 ,选择密钥文件,如果没有密钥文件,可以通过在签名界面点击随机生成RSA密钥 ,生成并通过文件选择器保存密钥文件,注意RSA密钥生成耗时较长。 选择完文本文件和密钥文件后,点击签名按钮,完成完整性签名,并通过文件选择器保存签名文件。
4.点击主页面tab栏的验签 ,在验签界面点击打开文件 ,通过文件选择器选择文本文件,选择完毕自动返回验签界面, 其内容显示在文件内容 文本框中, 点击选择密钥 ,选择和签名一致的密钥文件。点击选择签名文件 ,通过文件选择器选择签名时保存的签名文件, 选择完文本文件、密钥文件和签名文件后,点击验签按钮,完成验签。
具体实现
-
进行对文本文件进行加解密、签名验签的功能接口封装在CryptoOperation中,源码参考:[CryptoOperation.ts]
/*
- Copyright (c) 2023 Huawei Device Co., Ltd.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
*/
import { cryptoFramework } from '@kit.CryptoArchitectureKit';
import Logger from '../util/Logger';const TAG: string = '[Crypto_Framework]';
const BASE_16: number = 16;
const SLICE_NUMBER: number = -2;// 字节流以16进制字符串输出
function uint8ArrayToShowStr(uint8Array: Uint8Array): string {
let ret: string = Array.prototype.map
.call(uint8Array, (x) => ('00' + x.toString(BASE_16)).slice(SLICE_NUMBER)).join('');
return ret;
}// 16进制字符串转字节流
function fromHexString(hexString: string): Uint8Array {
let ret: Uint8Array = new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, BASE_16)));
return ret;
}// 字节流转字符串
function arrayBufferToString(buffer: ArrayBuffer): string {
let ret: string = String.fromCharCode.apply(null, new Uint8Array(buffer));
return ret;
}// 可理解的字符串转成字节流
function stringToUint8Array(str: string): Uint8Array {
let arr = [];
for (let i = 0, j = str.length; i < j; ++i) {
arr.push(str.charCodeAt(i));
}
let ret: Uint8Array = new Uint8Array(arr);
return ret;
}function genGcmParamsSpec(): cryptoFramework.GcmParamsSpec {
let arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 12 bytes
let dataIv = new Uint8Array(arr);
let ivBlob = { data: dataIv };arr = [0, 0, 0, 0, 0, 0, 0, 0]; // 8 bytes let dataAad = new Uint8Array(arr); let aadBlob = { data: dataAad }; arr = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; // 16 bytes let dataTag = new Uint8Array(arr); let tagBlob = { data: dataTag }; // GCM的authTag在加密时从doFinal结果中获取,在解密时填入init函数的params参数中 let gcmParamsSpec = { iv: ivBlob, aad: aadBlob, authTag: tagBlob, algName: 'GcmParamsSpec' }; return gcmParamsSpec;
}
export class CryptoOperation {
async generateAesKey(): Promise<string> {
let symKeyGenerator;
let encodedKey;
// 创建对称密钥生成器
try {
symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES256');
} catch (error) {
Logger.error(TAG, 'create generator failed');
return null;
}// 通过密钥生成器随机生成对称密钥 try { let symKey = await symKeyGenerator.generateSymKey(); // 获取对称密钥的二进制数据,输出长度为256bit的字节流 encodedKey = symKey.getEncoded(); let data: Uint8Array = encodedKey.data; Logger.info('success, key bytes: ' + data); Logger.info('success, key hex:' + uint8ArrayToShowStr(data)); // 将二进制数据转为16进制string。 return uint8ArrayToShowStr(data); } catch (error) { Logger.error(TAG, 'create symKey failed'); return null; } } async convertAesKey(aesKeyBlobString: string): Promise<cryptoFramework.SymKey> { let symKeyGenerator = cryptoFramework.createSymKeyGenerator('AES256'); Logger.info(TAG, 'success, read key string' + aesKeyBlobString); Logger.info(TAG, 'success, blob key ' + fromHexString(aesKeyBlobString)); let symKeyBlob = { data: fromHexString(aesKeyBlobString) }; try { let key = await symKeyGenerator.convertKey(symKeyBlob); let aesKey: cryptoFramework.SymKey = key; return aesKey; } catch (error) { Logger.error(TAG, `convert aes key failed, ${error.code}, ${error.message}`); return null; } } async aesGcmEncrypt(globalKey, textString: string): Promise<string> { let cipherAlgName = 'AES256|GCM|PKCS7'; let cipher; let cipherText: string; let globalGcmParams = genGcmParamsSpec(); let aesEncryptJsonStr = null; try { cipher = cryptoFramework.createCipher(cipherAlgName); Logger.info(TAG, `cipher algName: ${cipher.algName}`); } catch (error) { Logger.error(TAG, `createCipher failed, ${error.code}, ${error.message}`); return aesEncryptJsonStr; } let mode = cryptoFramework.CryptoMode.ENCRYPT_MODE; try { await cipher.init(mode, globalKey, globalGcmParams); } catch (error) { Logger.error(TAG, `init cipher failed, ${error.code}, ${error.message}`); return aesEncryptJsonStr; } let plainText = { data: stringToUint8Array(textString) }; Logger.info(TAG, `plain text: ${plainText.data}`); try { let cipherTextBlob = await cipher.update(plainText); let tmpArr: Uint8Array = cipherTextBlob.data; cipherText = uint8ArrayToShowStr(tmpArr); Logger.info(TAG, `cipher text: ${cipherText}`); } catch (error) { Logger.error(TAG, `update cipher failed, ${error.code}, ${error.message}`); return aesEncryptJsonStr; } try { let authTag = await cipher.doFinal(null); let tmoTagArr: Uint8Array = authTag.data; let aesEncryptJson = ({ aesGcmTag: uint8ArrayToShowStr(tmoTagArr), encryptedText: cipherText }); aesEncryptJsonStr = JSON.stringify(aesEncryptJson); Logger.info(TAG, `success, authTag blob ${authTag.data}`); Logger.info(TAG, `success, authTag blob.length = ${authTag.data.length}`); return aesEncryptJsonStr; } catch (error) { Logger.error(TAG, `doFinal cipher failed, ${error.code}, ${error.message}`); return aesEncryptJsonStr; } } async aesGcmDecrypt(globalKey, aesEncryptJsonStr: string): Promise<string> { let cipherAlgName = 'AES256|GCM|PKCS7'; let decode; let plainTextBlob; let plainText: string; let aesEncryptJson; try { aesEncryptJson = JSON.parse(aesEncryptJsonStr); } catch (error) { Logger.error(TAG, `trans from json string failed, ${error.code}, ${error.message}`); return null; } let authTagStr: string = aesEncryptJson.aesGcmTag; let textString: string = aesEncryptJson.encryptedText; let globalGcmParams = genGcmParamsSpec(); globalGcmParams.authTag = { data: fromHexString(authTagStr) }; Logger.info(TAG, 'success, decrypt authTag string' + authTagStr); Logger.info(TAG, 'success, decrypt authTag blob' + globalGcmParams.authTag.data); Logger.info(TAG, 'success, decrypt authTag blob.length = ' + globalGcmParams.authTag.data.length); try { decode = cryptoFramework.createCipher(cipherAlgName); } catch (error) { Logger.error(TAG, `createCipher failed, ${error.code}, ${error.message}`); return null; } let mode = cryptoFramework.CryptoMode.DECRYPT_MODE; try { await decode.init(mode, globalKey, globalGcmParams); } catch (error) { Logger.error(TAG, `init decode failed, ${error.code}, ${error.message}`); return null; } let cipherText = { data: fromHexString(textString) }; Logger.info(TAG, `success, cipher text: ${cipherText.data}`); try { plainTextBlob = await decode.update(cipherText); let tmpArr: Uint8Array = plainTextBlob.data; plainText = arrayBufferToString(tmpArr); Logger.info(TAG, `success, plain text: ${plainText}`); } catch (error) { Logger.error(TAG, `update decode failed, ${error.code}, ${error.message}`); return null; } try { let finalOut = await decode.doFinal(null); } catch (error) { Logger.error(TAG, `doFinal decode failed, ${error.code}, ${error.message}`); return null; } return plainText; } async aesConvertAndEncrypt(aesKeyBlobString: string, textString: string): Promise<string> { let aesEncryptJsonStr = ''; try { let key = await this.convertAesKey(aesKeyBlobString); try { aesEncryptJsonStr = await this.aesGcmEncrypt(key, textString); } catch (error) { Logger.error(TAG, `encrypt error, ${error.code}, ${error.message}`); } } catch (error) { Logger.error(TAG, `convert key error, ${error.code}, ${error.message}`); return null; } return aesEncryptJsonStr; } async aesConvertAndDecrypt(aesKeyBlobString: string, textString: string): Promise<string> { let plainText = ''; try { let key = await this.convertAesKey(aesKeyBlobString); try { plainText = await this.aesGcmDecrypt(key, textString); } catch (error) { Logger.error(TAG, `encrypt error, ${error.code}, ${error.message}`); } } catch (error) { Logger.error(TAG, `convert key error, ${error.code}, ${error.message}`); return null; } return plainText; } async generateRsaKey(): Promise<string> { // 创建非对称密钥生成器 let rsaKeyGenerator; let jsonStr; // 创建对称密钥生成器 try { rsaKeyGenerator = cryptoFramework.createAsyKeyGenerator('RSA3072'); } catch (error) { Logger.error(TAG, 'create generator failed'); return null; } // 通过密钥生成器随机生成非对称密钥 try { // 通过密钥生成器随机生成非对称密钥 let keyPair = await rsaKeyGenerator.generateKeyPair(); // 获取非对称密钥的二进制数据 let encodedPriKey = keyPair.priKey.getEncoded(); let priKeyData: Uint8Array = encodedPriKey.data; let encodedPubKey = keyPair.pubKey.getEncoded(); let pubKeyData: Uint8Array = encodedPubKey.data; let rsaKeyJson = ({ priKey: uint8ArrayToShowStr(priKeyData), pubKey: uint8ArrayToShowStr(pubKeyData) }); jsonStr = JSON.stringify(rsaKeyJson); Logger.info(TAG, 'success, key string: ' + jsonStr.length); return jsonStr; } catch (error) { Logger.error(TAG, 'create symKey failed'); return null; } } async convertRsaKey(rsaJsonString: string): Promise<cryptoFramework.KeyPair> { let rsaKeyGenerator = cryptoFramework.createAsyKeyGenerator('RSA3072'); Logger.info(TAG, 'success, read key string' + rsaJsonString.length); let jsonRsaKeyBlob; try { jsonRsaKeyBlob = JSON.parse(rsaJsonString); } catch (error) { Logger.error(TAG, `trans from json string failed, ${error.code}, ${error.message}`); return null; } let priKeyStr: string = jsonRsaKeyBlob.priKey; let pubKeyStr: string = jsonRsaKeyBlob.pubKey; Logger.info(TAG, 'success, read rsa pri str ' + priKeyStr.length); Logger.info(TAG, 'success, read rsa pub str ' + pubKeyStr.length); let priKeyBlob = fromHexString(priKeyStr); let pubKeyBlob = fromHexString(pubKeyStr); Logger.info(TAG, 'success, read rsa pri blob key ' + priKeyBlob.length); Logger.info(TAG, 'success, read rsa pub blob key ' + pubKeyBlob.length); try { let key: cryptoFramework.KeyPair = await rsaKeyGenerator.convertKey({ data: pubKeyBlob }, { data: priKeyBlob }); return key; Logger.info(TAG, 'success, read and convert key'); } catch (error) { Logger.error(TAG, `convert rsa key failed, ${error.code}, ${error.message}`); return null; } } async rsaSign(globalKey, textString: string): Promise<string> { let signer = cryptoFramework.createSign('RSA3072|PKCS1|SHA256'); let keyPair = globalKey; try { await signer.init(keyPair.priKey); let signBlob = stringToUint8Array(textString); try { let signedBlob = await signer.sign({ data: signBlob }); let tmpArr: Uint8Array = signedBlob.data; Logger.info(TAG, 'success,RSA sign output is' + signedBlob.data.length); let rsaSignedBlobString = uint8ArrayToShowStr(tmpArr); Logger.info(TAG, 'success,RSA sign string is' + rsaSignedBlobString); return rsaSignedBlobString; } catch (error1) { Logger.error(TAG, `sign text failed, ${error1.code}, ${error1.message}`); return null; } } catch (error) { Logger.error(TAG, `sign init failed, ${error.code}, ${error.message}`); return null; } } async rsaVerify(globalKey, textString: string, rsaSignedText: string): Promise<Boolean> { let verifyer = cryptoFramework.createVerify('RSA3072|PKCS1|SHA256'); let keyPair = globalKey; let signBlob = stringToUint8Array(textString); let signedBlob = fromHexString(rsaSignedText); Logger.info('success,RSA sign input is ' + signBlob); Logger.info('success,RSA signed file length ' + signedBlob.length); try { await verifyer.init(keyPair.pubKey); try { let result: Boolean = await verifyer.verify({ data: signBlob }, { data: signedBlob }); if (result === false) { // flag = false; Logger.error(TAG, 'RSA Verify result = fail'); } else { Logger.info(TAG, 'success, RSA Verify result = success'); } return result; } catch (error) { Logger.error(TAG, `verify dofinal failed, ${error.code}, ${error.message}`); } } catch (err) { Logger.error(TAG, `verify init failed, ${err.code}, ${err.message}`); } return null; } async rsaConvertAndSign(rsaJsonString: string, textString: string): Promise<string> { let rsaSignString; try { let key = await this.convertRsaKey(rsaJsonString); try { rsaSignString = await this.rsaSign(key, textString); } catch (error) { Logger.error(TAG, `sign error, ${error.code}, ${error.message}`); return null; } } catch (error) { Logger.error(TAG, `convert rsa key error, ${error.code}, ${error.message}`); return null; } return rsaSignString; } async rsaConvertAndVerify(rsaJsonString: string, textString: string, rsaSignedText: string): Promise<Boolean> { let rsaVerifyRes; try { let key = await this.convertRsaKey(rsaJsonString); try { rsaVerifyRes = await this.rsaVerify(key, textString, rsaSignedText); } catch (error) { Logger.error(TAG, `sign error, ${error.code}, ${error.message}`); return null; } } catch (error) { Logger.error(TAG, `convert rsa key error, ${error.code}, ${error.message}`); return null; } return rsaVerifyRes; }
}
-
对文本文件加密:在[Encrypt.ets](文件中依次点击打开文件、选择密钥,通过filePicker选择明文文本文件和密钥文件,点击加密按钮,调用加密函数实现对文本内容进行加密,并将密文文件通过filePicker保存。 需要生成密钥文本文件时,可以点击随机生成AES密钥,通过调用cryptoFramework.symKeyGenerator生成用于加密的AES密钥,并通过filePicker保存密钥文本文件。 对消息加密的过程中采用cryptoFramework.Cipher完成加密操作。
/*
- Copyright (c) 2023 Huawei Device Co., Ltd.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
*/
import { promptAction } from '@kit.ArkUI';
import Logger from '../util/Logger';
import { picker } from '@kit.CoreFileKit';
import { CryptoOperation } from '../cryptoframework/CryptoOperation';
import TextFileManager from '../textfilemanager/TextFileManager';const TAG: string = '[Crypto_Framework]';
@Component
export struct Encrypt {
@State keyFileName: string = '';
@State keyFileUri: string = '';
@State textFileUri: string = '';
@State textFileName: string = '';
@State keyString: string = '';
@State cipherText: string = '';
@State plainText: string = '';
@State message: string = '';
@State createKeyUri: string = '';
@State encryptedFileUri: string = '';
private CryptoOperation: CryptoOperation = new CryptoOperation();build() { Stack({ alignContent: Alignment.Center }) { Column() { GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { List() { ListItem() { Row() { Text($r('app.string.open_file')) .fontSize(16) .textAlign(TextAlign.Start) .lineHeight(22) Blank() Text(this.textFileName === '' ? $r('app.string.please_choose') : this.textFileName) .fontSize(14) .textAlign(TextAlign.Start) .lineHeight(19) Image($r('app.media.right_arrow')) .height('19vp') .width('10vp') .margin({ left: 9, right: 9, top: 6, bottom: 6 }) } .backgroundColor(0xFFFFFF) .width('100%') .height('52vp') .padding({ top: 4, left: 12, right: 12 }) }.onClick(() => { this.selectTextFileAndRead(); }) ListItem() { Row() { Text($r('app.string.select_key_file')) .fontSize(16) .textAlign(TextAlign.Start) .lineHeight(22) Blank() Text(this.keyFileName === '' ? $r('app.string.please_choose') : this.keyFileName) .fontSize(14) .textAlign(TextAlign.Start) .lineHeight(19) Image($r('app.media.right_arrow')) .height('19vp') .width('10vp') .margin({ left: 9, right: 9, top: 6, bottom: 6 }) } .backgroundColor(0xFFFFFF) .width('100%') .height('48vp') .padding({ left: 12, right: 12 }) }.onClick(() => { this.selectAesKeyFileAndRead(); }) } .width('100%') .height('100%') .borderRadius(16) } } } .height('100vp') .margin({ left: 12, right: 12, bottom: 12 }) GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Column() { Row() { Text($r('app.string.text_context')) .fontSize(16) .textAlign(TextAlign.Start) .fontWeight(500) .lineHeight(22) } .padding({ left: 12, right: 12 }) .width('100%') .height('48vp') Row() { Text() { Span(this.plainText) .fontSize(16) .fontWeight(400) .fontColor('#182431') }.textAlign(TextAlign.Start) } .padding({ left: 12, right: 12, bottom: 4 }) .width('100%') .height('52vp') } .borderRadius(16) .width('100%') .height('100') .backgroundColor(0xFFFFFF) } } } .height('100vp') .margin({ left: 12, right: 12, bottom: 12 }) GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Column() { Row() { Text($r('app.string.encrypted_context')) .fontSize(16) .textAlign(TextAlign.Start) .fontWeight(500) .lineHeight(22) } .padding({ left: 12, right: 12 }) .width('100%') .height('48vp') Row() { Text() { Span(this.cipherText) .fontSize(16) .fontWeight(400) .fontColor('#182431') }.textAlign(TextAlign.Start) } .padding({ left: 12, right: 12, bottom: 4 }) .width('100%') .height('80vp') } .borderRadius(16) .width('100%') .height('100') .backgroundColor(0xFFFFFF) } } } .height('100vp') .margin({ left: 12, right: 12, bottom: 12 }) Column() { GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Column() { Button() { Text($r('app.string.generate_aes_key_randomly')).fontSize(16).fontWeight(500) .lineHeight(22) .fontColor('#FFFFFF') } .id('encryptAesGenKey') .borderRadius(20) .type(ButtonType.Capsule) .width('100%') .height('40vp') .margin({ bottom: 16 }) .backgroundColor('#007DFF') .onClick(() => { this.genAesKey(); }); Button() { Text($r('app.string.encrypt')).fontSize(16).fontWeight(500) .lineHeight(22) .fontColor('#FFFFFF') } .borderRadius(20) .id('encryptionBtn') .type(ButtonType.Capsule) .margin({ left: 24, right: 24 }) .width('100%') .height('40vp') .backgroundColor('#007DFF') .onClick(() => { if (this.textFileUri === '' || this.keyFileUri === '') { promptAction.showToast({ message: $r('app.string.null_message') }); } else { this.encryptFunc(); } }); } } }.margin({ left: 24, right: 24 }) }.width('100%').height('296vp').justifyContent(FlexAlign.End) } .width('100%') .height('100%') } } async selectAesKeyFileAndRead() { let documentSelectOptions = new picker.DocumentSelectOptions(); documentSelectOptions.fileSuffixFilters = ['.txt']; documentSelectOptions.maxSelectNumber = 1; let uri: string = ''; let documentViewPicker = new picker.DocumentViewPicker(); await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => { uri = documentSelectResult[0]; console.info('documentViewPicker.select to text file succeed and uris are:' + uri); }).catch((err: Error) => { console.error(`Invoke documentViewPicker.select failed, code is ${err}, message is ${err.message}`); }) this.keyFileUri = uri; await TextFileManager.readTextFile(this.keyFileUri); this.keyFileName = TextFileManager.getName(); this.keyString = TextFileManager.getString(); } async selectTextFileAndRead() { let documentSelectOptions = new picker.DocumentSelectOptions(); documentSelectOptions.fileSuffixFilters = ['.txt']; documentSelectOptions.maxSelectNumber = 1; let uri: string = ''; let documentViewPicker = new picker.DocumentViewPicker(); await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => { uri = documentSelectResult[0]; console.info('documentViewPicker.select to text file succeed and uris are:' + uri); }).catch((err: Error) => { console.error(`Invoke documentViewPicker.select failed, code is ${err}, message is ${err.message}`); }) this.textFileUri = uri; await TextFileManager.readTextFile(this.textFileUri); this.textFileName = TextFileManager.getName(); this.plainText = TextFileManager.getString(); } async createTextFileAndWrite() { let documentSaveOptions = new picker.DocumentSaveOptions(); documentSaveOptions.newFileNames = ['cipherText.txt']; let documentPicker = new picker.DocumentViewPicker(); let documentSaveResult = await documentPicker.save(documentSaveOptions); this.encryptedFileUri = documentSaveResult[0]; await TextFileManager.writeTextFile(this.encryptedFileUri, this.cipherText); } async createKeyFileAndWrite() { let documentSaveOptions = new picker.DocumentSaveOptions(); documentSaveOptions.newFileNames = ['aesKey.txt']; let documentPicker = new picker.DocumentViewPicker(); let documentSaveResult = await documentPicker.save(documentSaveOptions); this.createKeyUri = documentSaveResult[0]; await TextFileManager.writeTextFile(this.createKeyUri, this.keyString); } async encryptFunc() { if (this.plainText === '' || this.keyFileUri === '') { promptAction.showToast({ message: $r('app.string.null_message') }); return; } try { this.cipherText = await this.CryptoOperation.aesConvertAndEncrypt(this.keyString, this.plainText); } catch (error) { Logger.error(TAG, `encrypt failed, ${error}`); promptAction.showToast({ message: $r('app.string.encrypt_fail') }); } if (this.cipherText === '' || this.cipherText === undefined || this.cipherText === null) { promptAction.showToast({ message: $r('app.string.encrypt_fail') }); return; } else { try { await this.createTextFileAndWrite(); } catch (error) { Logger.error(TAG, `encrypt failed, ${error}`); } } if (this.encryptedFileUri === '' || typeof (this.encryptedFileUri) == 'undefined') { promptAction.showToast({ message: $r('app.string.encrypt_fail') }); } else { promptAction.showToast({ message: $r('app.string.encrypt_success') }); } } async genAesKey() { try { this.keyString = await this.CryptoOperation.generateAesKey(); } catch (error) { Logger.error(TAG, `gen aes key failed, ${error}`); } if (this.keyString === '' || typeof (this.keyString) == 'undefined') { promptAction.showToast({ message: $r('app.string.gen_key_fail') }); return; } else { try { await this.createKeyFileAndWrite(); } catch (error) { Logger.error(TAG, `write aes key failed, ${error}`); } } if (this.createKeyUri === '' || typeof (this.createKeyUri) == 'undefined') { promptAction.showToast({ message: $r('app.string.gen_key_fail') }); } else { promptAction.showToast({ message: $r('app.string.gen_key_success') }); } }
}
-
对文本文件解密:在[Decrypt.ets] 文件中依次点击打开文件、选择密钥,通过filePicker选择密文文本文件和密钥文件,点击解密按钮,调用解密函数实现对文本内容进行解密,并将明文文件通过filePicker保存。 对消息解密的过程中采用cryptoFramework.Cipher完成解密操作。
/*
- Copyright (c) 2023 Huawei Device Co., Ltd.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
*/
import { promptAction } from '@kit.ArkUI';
import Logger from '../util/Logger';
import { picker } from '@kit.CoreFileKit';
import { CryptoOperation } from '../cryptoframework/CryptoOperation';
import TextFileManager from '../textfilemanager/TextFileManager';const TAG: string = '[Crypto_Framework]';
@Component
export struct Decrypt {
@State keyFileName: string = '';
@State keyFileUri: string = '';
@State textFileUri: string = '';
@State textFileName: string = '';
@State keyString: string = '';
@State cipherText: string = '';
@State plainText: string = '';
@State message: string = '';
@State decryptedFileUri: string = '';
private CryptoOperation: CryptoOperation = new CryptoOperation();build() { Stack({ alignContent: Alignment.Center }) { Column() { GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { List() { ListItem() { Row() { Text($r('app.string.open_file')) .fontSize(16) .textAlign(TextAlign.Start) .lineHeight(22) Blank() Text(this.textFileName === '' ? $r('app.string.please_choose') : this.textFileName) .fontSize(14) .textAlign(TextAlign.Start) .lineHeight(19) Image($r('app.media.right_arrow')) .height('19vp') .width('10vp') .margin({ left: 9, right: 9, top: 6, bottom: 6 }) } .backgroundColor(0xFFFFFF) .width('100%') .height('52vp') .padding({ top: 4, left: 12, right: 12 }) }.onClick(() => { this.selectTextFileAndRead(); }) ListItem() { Row() { Text($r('app.string.select_key_file')) .fontSize(16) .textAlign(TextAlign.Start) .lineHeight(22) Blank() Text(this.keyFileName === '' ? $r('app.string.please_choose') : this.keyFileName) .fontSize(14) .textAlign(TextAlign.Start) .lineHeight(19) Image($r('app.media.right_arrow')) .height('19vp') .width('10vp') .margin({ left: 9, right: 9, top: 6, bottom: 6 }) } .backgroundColor(0xFFFFFF) .width('100%') .height('48vp') .padding({ left: 12, right: 12 }) }.onClick(() => { this.selectAesKeyFileAndRead(); }) } .width('100%') .height('100%') .borderRadius(16) } } } .height('100vp') .margin({ left: 12, right: 12, bottom: 12 }) GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Column() { Row() { Text($r('app.string.text_context')) .fontSize(16) .textAlign(TextAlign.Start) .fontWeight(500) .lineHeight(22) } .padding({ left: 12, right: 12 }) .width('100%') .height('48vp') Row() { Text() { Span(this.cipherText) .fontSize(16) .fontWeight(400) .fontColor('#182431') }.textAlign(TextAlign.Start) } .padding({ left: 12, right: 12, bottom: 4 }) .width('100%') .height('52vp') } .borderRadius(16) .width('100%') .height('100') .backgroundColor(0xFFFFFF) } } } .height('100vp') .margin({ left: 12, right: 12, bottom: 12 }) GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Column() { Row() { Text($r('app.string.decrypted_context')) .fontSize(16) .textAlign(TextAlign.Start) .fontWeight(500) .lineHeight(22) } .padding({ left: 12, right: 12 }) .width('100%') .height('48vp') Row() { Text() { Span(this.plainText) .fontSize(16) .fontWeight(400) .fontColor('#182431') }.textAlign(TextAlign.Start) } .padding({ left: 12, right: 12, bottom: 4 }) .width('100%') .height('52vp') } .borderRadius(16) .width('100%') .height('100') .backgroundColor(0xFFFFFF) } } } .height('100vp') .margin({ left: 12, right: 12, bottom: 12 }) Column() { GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Column() { Button() { Text($r('app.string.decrypt')).fontSize(16).fontWeight(500) .lineHeight(22) .fontColor('#FFFFFF') } .borderRadius(20) .id('decryptionBtn') .type(ButtonType.Capsule) .margin({ left: 24, right: 24 }) .width('100%') .height('40vp') .backgroundColor('#007DFF') .onClick(() => { if (this.textFileUri === '' || this.keyFileUri === '') { promptAction.showToast({ message: $r('app.string.null_message') }); } else { this.decryptFunc(); } }); } } }.margin({ left: 24, right: 24 }) }.width('100%').height('296vp').justifyContent(FlexAlign.End) } .width('100%') .height('100%') } } async selectAesKeyFileAndRead() { let documentSelectOptions = new picker.DocumentSelectOptions(); documentSelectOptions.fileSuffixFilters = ['.txt']; documentSelectOptions.maxSelectNumber = 1; let uri: string = ''; let documentViewPicker = new picker.DocumentViewPicker(); await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => { uri = documentSelectResult[0]; console.info('documentViewPicker.select to text file succeed and uris are:' + uri); }).catch((err: Error) => { console.error(`Invoke documentViewPicker.select failed, code is ${err}, message is ${err.message}`); }) this.keyFileUri = uri; await TextFileManager.readTextFile(this.keyFileUri); this.keyFileName = TextFileManager.getName(); this.keyString = TextFileManager.getString(); } async selectTextFileAndRead() { let documentSelectOptions = new picker.DocumentSelectOptions(); documentSelectOptions.fileSuffixFilters = ['.txt']; documentSelectOptions.maxSelectNumber = 1; let uri: string = ''; let documentViewPicker = new picker.DocumentViewPicker(); await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => { uri = documentSelectResult[0]; console.info('documentViewPicker.select to text file succeed and uris are:' + uri); }).catch((err: Error) => { console.error(`Invoke documentViewPicker.select failed, code is ${err}, message is ${err.message}`); }) this.textFileUri = uri; await TextFileManager.readTextFile(this.textFileUri); this.textFileName = TextFileManager.getName(); this.cipherText = TextFileManager.getString(); } async createTextFileAndWrite() { let documentSaveOptions = new picker.DocumentSaveOptions(); documentSaveOptions.newFileNames = ['plainText.txt']; let documentPicker = new picker.DocumentViewPicker(); let documentSaveResult = await documentPicker.save(documentSaveOptions); this.decryptedFileUri = documentSaveResult[0]; await TextFileManager.writeTextFile(this.decryptedFileUri, this.plainText); } async decryptFunc() { if (this.cipherText === '' || this.keyFileUri === '') { promptAction.showToast({ message: $r('app.string.null_message') }); return; } try { this.plainText = await this.CryptoOperation.aesConvertAndDecrypt(this.keyString, this.cipherText); } catch (error) { Logger.error(TAG, `decrypt failed, ${error}`); promptAction.showToast({ message: $r('app.string.decrypt_fail') }); return; } if (this.plainText === '' || this.plainText === null || this.plainText === undefined) { promptAction.showToast({ message: $r('app.string.decrypt_fail') }); return; } else { try { await this.createTextFileAndWrite(); } catch (error) { Logger.error(TAG, `decrypt failed, ${error}`); } } if (this.decryptedFileUri === '' || typeof (this.decryptedFileUri) == 'undefined') { promptAction.showToast({ message: $r('app.string.decrypt_fail') }); } else { promptAction.showToast({ message: $r('app.string.decrypt_success') }); } }
}
-
对文本文件签名:在[Sign.ets] 文件中依次点击打开文件、选择密钥,通过filePicker选择待签名文本文件和密钥文件,点击签名按钮,调用签名函数实现对文本内容进行加密,并将签名文件通过filePicker保存。 需要生成密钥文本文件时,可以点击随机生成RSA密钥,通过调用cryptoFramework.asyKeyGenerator生成用于签名的RSA密钥,并通过filePicker保存密钥文本文件。 对消息签名的过程中采用cryptoFramework.Sign完成加密操作。
/*
- Copyright (c) 2023 Huawei Device Co., Ltd.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
*/
import { promptAction } from '@kit.ArkUI';
import Logger from '../util/Logger';
import { picker } from '@kit.CoreFileKit';
import { CryptoOperation } from '../cryptoframework/CryptoOperation';
import TextFileManager from '../textfilemanager/TextFileManager';const TAG: string = '[Crypto_Framework]';
@Component
export struct Sign {
@State keyFileName: string = '';
@State keyFileUri: string = '';
@State textFileUri: string = '';
@State textFileName: string = '';
@State keyString: string = '';
@State cipherText: string = '';
@State plainText: string = '';
@State message: string = '';
@State signFileUri: string = '';
@State createKeyUri: string = '';
private CryptoOperation: CryptoOperation = new CryptoOperation();build() { Stack({ alignContent: Alignment.Center }) { Column() { GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { List() { ListItem() { Row() { Text($r('app.string.open_file')) .fontSize(16) .textAlign(TextAlign.Start) .lineHeight(22) Blank() Text(this.textFileName === '' ? $r('app.string.please_choose') : this.textFileName) .fontSize(14) .textAlign(TextAlign.Start) .lineHeight(19) Image($r('app.media.right_arrow')) .height('19vp') .width('10vp') .margin({ left: 9, right: 9, top: 6, bottom: 6 }) } .backgroundColor(0xFFFFFF) .width('100%') .height('52vp') .padding({ top: 4, left: 12, right: 12 }) }.onClick(() => { this.selectTextFileAndRead(); }) ListItem() { Row() { Text($r('app.string.select_key_file')) .fontSize(16) .textAlign(TextAlign.Start) .lineHeight(22) Blank() Text(this.keyFileName === '' ? $r('app.string.please_choose') : this.keyFileName) .fontSize(14) .textAlign(TextAlign.Start) .lineHeight(19) Image($r('app.media.right_arrow')) .height('19vp') .width('10vp') .margin({ left: 9, right: 9, top: 6, bottom: 6 }) } .backgroundColor(0xFFFFFF) .width('100%') .height('48vp') .padding({ left: 12, right: 12 }) }.onClick(() => { this.selectRsaKeyFileAndRead(); }) } .width('100%') .height('100%') .borderRadius(16) } } } .height('100vp') .margin({ left: 12, right: 12, bottom: 12 }) GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Column() { Row() { Text($r('app.string.text_context')) .fontSize(16) .textAlign(TextAlign.Start) .fontWeight(500) .lineHeight(22) } .padding({ left: 12, right: 12 }) .width('100%') .height('48vp') Row() { Text() { Span(this.plainText) .fontSize(16) .fontWeight(400) .fontColor('#182431') }.textAlign(TextAlign.Start) } .padding({ left: 12, right: 12, bottom: 4 }) .width('100%') .height('52vp') } .borderRadius(16) .width('100%') .height('100') .backgroundColor(0xFFFFFF) } } } .height('100vp') .margin({ left: 12, right: 12, bottom: 12 }) Column() { GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Column() { Button() { Text($r('app.string.generate_rsa_key_randomly')).fontSize(16).fontWeight(500) .lineHeight(22) .fontColor('#FFFFFF') } .id('encryptRsaGenKey') .borderRadius(20) .type(ButtonType.Capsule) .width('100%') .height('40vp') .margin({ bottom: 16 }) .backgroundColor('#007DFF') .onClick(() => { this.genRsaKey(); }); Button() { Text($r('app.string.sign')).fontSize(16).fontWeight(500) .lineHeight(22) .fontColor('#FFFFFF') } .borderRadius(20) .id('signBtn') .type(ButtonType.Capsule) .margin({ left: 24, right: 24 }) .width('100%') .height('40vp') .backgroundColor('#007DFF') .onClick(() => { if (this.textFileUri === '' || this.keyFileUri === '') { promptAction.showToast({ message: $r('app.string.null_message') }); } else { this.signFunc(); } }); } } }.margin({ left: 24, right: 24 }) }.width('100%').height('412vp').justifyContent(FlexAlign.End) } .width('100%') .height('100%') } } async selectRsaKeyFileAndRead() { let documentSelectOptions = new picker.DocumentSelectOptions(); documentSelectOptions.fileSuffixFilters = ['.txt']; documentSelectOptions.maxSelectNumber = 1; let uri: string = ''; let documentViewPicker = new picker.DocumentViewPicker(); await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => { uri = documentSelectResult[0]; console.info('documentViewPicker.select to text file succeed and uris are:' + uri); }).catch((err: Error) => { console.error(`Invoke documentViewPicker.select failed, code is ${err}, message is ${err.message}`); }) this.keyFileUri = uri; // 获取到密钥文档文件的文件名称 await TextFileManager.readTextFile(this.keyFileUri); this.keyFileName = TextFileManager.getName(); this.keyString = TextFileManager.getString(); } async selectTextFileAndRead() { let documentSelectOptions = new picker.DocumentSelectOptions(); documentSelectOptions.fileSuffixFilters = ['.txt']; documentSelectOptions.maxSelectNumber = 1; let uri: string = ''; let documentViewPicker = new picker.DocumentViewPicker(); await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => { uri = documentSelectResult[0]; console.info('documentViewPicker.select to text file succeed and uris are:' + uri); }).catch((err: Error) => { console.error(`Invoke documentViewPicker.select failed, code is ${err}, message is ${err.message}`); }) // 获取到文档文件的URI this.textFileUri = uri; // 获取到文档文件的文件名称 await TextFileManager.readTextFile(this.textFileUri); this.textFileName = TextFileManager.getName(); this.plainText = TextFileManager.getString(); } async createTextFileAndWrite() { let documentSaveOptions = new picker.DocumentSaveOptions(); documentSaveOptions.newFileNames = ['signText.txt']; let documentPicker = new picker.DocumentViewPicker(); let documentSaveResult = await documentPicker.save(documentSaveOptions); this.signFileUri = documentSaveResult[0]; await TextFileManager.writeTextFile(this.signFileUri, this.cipherText); } async createKeyFileAndWrite() { let documentSaveOptions = new picker.DocumentSaveOptions(); documentSaveOptions.newFileNames = ['rsaKey.txt']; let documentPicker = new picker.DocumentViewPicker(); try { let documentSaveResult = await documentPicker.save(documentSaveOptions); this.createKeyUri = documentSaveResult[0]; await TextFileManager.writeTextFile(this.createKeyUri, this.keyString); } catch (error) { Logger.error(TAG, `save key failed, ${error}`); } } async signFunc() { if (this.plainText === '' || this.keyFileUri === '') { promptAction.showToast({ message: $r('app.string.null_message') }); return; } try { this.cipherText = await this.CryptoOperation.rsaConvertAndSign(this.keyString, this.plainText); } catch (error) { promptAction.showToast({ message: $r('app.string.sign_fail') }); Logger.error(TAG, `sign failed, ${error}`); } if (this.cipherText === '' || this.cipherText === null || this.cipherText === undefined) { promptAction.showToast({ message: $r('app.string.sign_fail') }); return; } else { await this.createTextFileAndWrite(); } if (this.signFileUri === '' || typeof (this.signFileUri) == 'undefined') { promptAction.showToast({ message: $r('app.string.sign_fail') }); } else { promptAction.showToast({ message: $r('app.string.sign_success') }); } } async genRsaKey() { promptAction.showToast({ message: $r('app.string.slow_rsa_key_gen') }); try { this.keyString = await this.CryptoOperation.generateRsaKey(); } catch (error) { Logger.error(TAG, `gen rsa key failed, ${error}`); } if (this.keyString === '' || typeof (this.keyString) == 'undefined') { promptAction.showToast({ message: $r('app.string.gen_key_fail') }); return; } else { try { await this.createKeyFileAndWrite(); } catch (error) { Logger.error(TAG, `write rsa key failed, ${error}`); } } if (this.createKeyUri === '' || typeof (this.createKeyUri) == 'undefined') { promptAction.showToast({ message: $r('app.string.gen_key_fail') }); } else { promptAction.showToast({ message: $r('app.string.gen_key_success') }); } }
}
-
对文本文件验签:在[Verify.ets]文件中依次点击打开文件、选择密钥、选择签名文件,通过filePicker选择密文文本文件、密钥文件和签名文件,点击验签按钮,调用验签函数实现对文本内容进行验签,并显示验签结果。 对消息验签的过程中采用cryptoFramework.Verify完成验签操作。
/*
- Copyright (c) 2023 Huawei Device Co., Ltd.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
*/
import { promptAction } from '@kit.ArkUI';
import Logger from '../util/Logger';
import { picker } from '@kit.CoreFileKit';
import { CryptoOperation } from '../cryptoframework/CryptoOperation';
import TextFileManager from '../textfilemanager/TextFileManager';const TAG: string = '[Crypto_Framework]';
@Component
export struct Verify {
@State keyFileName: string = '';
@State keyFileUri: string = '';
@State textFileUri: string = '';
@State textFileName: string = '';
@State keyString: string = '';
@State plainText: string = '';
@State message: string = '';
@State signFileUri: string = '';
@State signFileName: string = '';
@State signText: string = '';
@State createKeyUri: string = '';
private CryptoOperation: CryptoOperation = new CryptoOperation();build() { Stack({ alignContent: Alignment.Center }) { Column() { GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { List() { ListItem() { Row() { Text($r('app.string.open_file')) .fontSize(16) .textAlign(TextAlign.Start) .lineHeight(22) Blank() Text(this.textFileName === '' ? $r('app.string.please_choose') : this.textFileName) .fontSize(14) .textAlign(TextAlign.Start) .lineHeight(19) Image($r('app.media.right_arrow')) .height('19vp') .width('10vp') .margin({ left: 9, right: 9, top: 6, bottom: 6 }) } .backgroundColor(0xFFFFFF) .width('100%') .height('52vp') .padding({ top: 4, left: 12, right: 12 }) }.onClick(() => { this.selectTextFileAndRead(); }) ListItem() { Row() { Text($r('app.string.select_key_file')) .fontSize(16) .textAlign(TextAlign.Start) .lineHeight(22) Blank() Text(this.keyFileName === '' ? $r('app.string.please_choose') : this.keyFileName) .fontSize(14) .textAlign(TextAlign.Start) .lineHeight(19) Image($r('app.media.right_arrow')) .height('19vp') .width('10vp') .margin({ left: 9, right: 9, top: 6, bottom: 6 }) } .backgroundColor(0xFFFFFF) .width('100%') .height('48vp') .padding({ left: 12, right: 12 }) }.onClick(() => { this.selectRsaKeyFileAndRead(); }) } .width('100%') .height('100%') .borderRadius(16) } } } .height('100vp') .margin({ left: 12, right: 12, bottom: 12 }) GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { List() { ListItem() { Row() { Text($r('app.string.select_signature_file')) .fontSize(16) .textAlign(TextAlign.Start) .lineHeight(22) Blank() Text(this.signFileName === '' ? $r('app.string.please_choose') : this.signFileName) .fontSize(14) .textAlign(TextAlign.Start) .lineHeight(19) Image($r('app.media.right_arrow')) .height('19vp') .width('10vp') .margin({ left: 9, right: 9, top: 6, bottom: 6 }) } .backgroundColor(0xFFFFFF) .width('100%') .height('56vp') .padding({ left: 12, right: 12, top: 4, bottom: 4 }) }.onClick(() => { this.selectSignFileAndRead(); }) } .width('100%') .borderRadius(16) } } } .height('56vp') .margin({ left: 12, right: 12, bottom: 12 }) GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Column() { Row() { Text($r('app.string.text_context')) .fontSize(16) .textAlign(TextAlign.Start) .fontWeight(500) .lineHeight(22) } .padding({ left: 12, right: 12 }) .width('100%') .height('48vp') Row() { Text() { Span(this.plainText) .fontSize(16) .fontWeight(400) .fontColor('#182431') }.textAlign(TextAlign.Start) } .padding({ left: 12, right: 12, bottom: 4 }) .width('100%') .height('52vp') } .borderRadius(16) .width('100%') .height('100') .backgroundColor(0xFFFFFF) } } } .height('100vp') .margin({ left: 12, right: 12, bottom: 12 }) Column() { GridRow() { GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { Column() { Button() { Text($r('app.string.verify')).fontSize(16).fontWeight(500) .lineHeight(22) .fontColor('#FFFFFF') } .borderRadius(20) .id('verifyBtn') .type(ButtonType.Capsule) .margin({ left: 24, right: 24 }) .width('100%') .height('40vp') .backgroundColor('#007DFF') .onClick(() => { if (this.textFileUri === '' || this.keyFileUri === '' || this.signFileUri === '') { promptAction.showToast({ message: $r('app.string.null_message') }); } else { this.verifyFunc(); } }); } } }.margin({ left: 24, right: 24 }) }.width('100%').height('340vp').justifyContent(FlexAlign.End) } .width('100%') .height('100%') } } async selectRsaKeyFileAndRead() { let documentSelectOptions = new picker.DocumentSelectOptions(); documentSelectOptions.fileSuffixFilters = ['.txt']; documentSelectOptions.maxSelectNumber = 1; let uri: string = ''; let documentViewPicker = new picker.DocumentViewPicker(); await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => { uri = documentSelectResult[0]; console.info('documentViewPicker.select to text file succeed and uris are:' + uri); }).catch((err: Error) => { console.error(`Invoke documentViewPicker.select failed, code is ${err}, message is ${err.message}`); }) // 获取到密钥文档文件的URI this.keyFileUri = uri; // 获取到密钥文档文件的文件名称 await TextFileManager.readTextFile(this.keyFileUri); this.keyFileName = TextFileManager.getName(); this.keyString = TextFileManager.getString(); } async selectTextFileAndRead() { let documentSelectOptions = new picker.DocumentSelectOptions(); documentSelectOptions.fileSuffixFilters = ['.txt']; documentSelectOptions.maxSelectNumber = 1; let uri: string = ''; let documentViewPicker = new picker.DocumentViewPicker(); await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => { uri = documentSelectResult[0]; console.info('documentViewPicker.select to text file succeed and uris are:' + uri); }).catch((err: Error) => { console.error(`Invoke documentViewPicker.select failed, code is ${err}, message is ${err.message}`); }) // 获取到文档文件的URI this.textFileUri = uri; // 获取到文档文件的文件名称 await TextFileManager.readTextFile(this.textFileUri); this.textFileName = TextFileManager.getName(); this.plainText = TextFileManager.getString(); } async selectSignFileAndRead() { let documentSelectOptions = new picker.DocumentSelectOptions(); documentSelectOptions.fileSuffixFilters = ['.txt']; documentSelectOptions.maxSelectNumber = 1; let uri: string = ''; let documentViewPicker = new picker.DocumentViewPicker(); await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => { uri = documentSelectResult[0]; console.info('documentViewPicker.select to text file succeed and uris are:' + uri); }).catch((err: Error) => { console.error(`Invoke documentViewPicker.select failed, code is ${err}, message is ${err.message}`); }) // 获取到文档文件的URI this.signFileUri = uri; // 获取到文档文件的文件名称 await TextFileManager.readTextFile(this.signFileUri); this.signFileName = TextFileManager.getName(); this.signText = TextFileManager.getString(); } async createKeyFileAndWrite() { let documentSaveOptions = new picker.DocumentSaveOptions(); documentSaveOptions.newFileNames = ['rsaKey.txt']; let documentPicker = new picker.DocumentViewPicker(); try { let documentSaveResult = await documentPicker.save(documentSaveOptions); this.createKeyUri = documentSaveResult[0]; await TextFileManager.writeTextFile(this.createKeyUri, this.keyString); } catch (error) { Logger.error(TAG, `save key failed, ${error}`); } } async verifyFunc() { let verifyRes: Boolean = false; if (this.plainText === '' || this.keyFileUri === '' || this.signText === '') { promptAction.showToast({ message: $r('app.string.null_message') }); return; } try { verifyRes = await this.CryptoOperation.rsaConvertAndVerify(this.keyString, this.plainText, this.signText); } catch (error) { Logger.error(TAG, `verify failed, ${error}`); } if (verifyRes != true) { promptAction.showToast({ message: $r('app.string.verify_fail') }); return; } else { promptAction.showToast({ message: $r('app.string.verify_success') }); } }
}
以上就是本篇文章所带来的鸿蒙开发中一小部分技术讲解;想要学习完整的鸿蒙全栈技术。可以在结尾找我可全部拿到!
下面是鸿蒙的完整学习路线 ,展示如下:
除此之外,根据这个学习鸿蒙全栈学习路线,也附带一整套完整的学习【文档+视频】,内容包含如下:
内容包含了:(ArkTS、ArkUI、Stage模型、多端部署、分布式应用开发、音频、视频、WebGL、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、鸿蒙南向开发、鸿蒙项目实战)等技术知识点。帮助大家在学习鸿蒙路上快速成长!
鸿蒙【北向应用开发+南向系统层开发】文档
鸿蒙【基础+实战项目】视频
鸿蒙面经
为了避免大家在学习过程中产生更多的时间成本,对比我把以上内容全部放在了↓↓↓想要的可以自拿喔!谢谢大家观看!