智能客服
你问我答,随时在线为你解决问题
如何实现文件下载后加密存储到公共目录,使之无法打开查看,需要再次读取公共目录保存的加密文件进行解密后再次保存,方可正常查看?
由问题可知实现此功能重点是如下两步:
示例代码如下(代码中使用AES对称密钥(ECB模式)加解密,亦可选择其他加解密算法;前置步骤需要配置网络权限已省略,请参考配置网络权限):
- import { BusinessError, request } from '@kit.BasicServicesKit';
- import picker from '@ohos.file.picker';
- import fs from '@ohos.file.fs';
- import { cryptoFramework } from '@kit.CryptoArchitectureKit';
-
- let keyData = new Uint8Array([83, 217, 231, 76, 28, 113, 23, 219, 250, 71, 209, 210, 205, 97, 32, 159]);
- let symKey = genSymKeyByData(keyData);
-
- function genSymKeyByData(symKeyData: Uint8Array) {
- let symKeyBlob: cryptoFramework.DataBlob = { data: symKeyData };
- let aesGenerator = cryptoFramework.createSymKeyGenerator('AES128');
- let symKey = aesGenerator.convertKeySync(symKeyBlob);
- return symKey;
- }
-
- // 加密消息
- function encryptMessage(symKey: cryptoFramework.SymKey, plainText: cryptoFramework.DataBlob) {
- let cipher = cryptoFramework.createCipher('AES128|ECB|PKCS7');
- cipher.initSync(cryptoFramework.CryptoMode.ENCRYPT_MODE, symKey, null); // ECB模式params为null。
- let cipherData = cipher.doFinalSync(plainText);
- return cipherData;
- }
-
- // 解密消息
- function decryptMessage(symKey: cryptoFramework.SymKey, cipherText: cryptoFramework.DataBlob) {
- let decoder = cryptoFramework.createCipher('AES128|ECB|PKCS7');
- decoder.initSync(cryptoFramework.CryptoMode.DECRYPT_MODE, symKey, null); // ECB模式params为null。
- let decryptData = decoder.doFinalSync(cipherText);
- return decryptData;
- }
-
- function getPlainText(file: fs.File) {
- let stat = fs.statSync(file.path); // 获取文件状态
- let buf = new ArrayBuffer(stat.size); // 创建一个ArrayBuffer对象
- let num = fs.readSync(file.fd, buf); // 读取文件
- let plainText: cryptoFramework.DataBlob = { data: new Uint8Array(buf.slice(0, num)) };
- return plainText;
- }
-
- @Entry
- @Component
- export struct DocumentSave {
- context = this.getUIContext().getHostContext() as Context;
- // downloadUrl替换为实际文件下载链接
- downloadUrl: string = 'https://xxx/xxx/xx.docx';
-
- // 下载文件并加密内容
- downloadFileAndEncrypt() {
- // 自定义文件名以及文件格式
- const fileName = `test${Date.now()}.docx`;
- request.downloadFile(this.context, {
- enableMetered: true,
- url: this.downloadUrl,
- filePath: `${this.context.filesDir}/${fileName}`, // 沙箱路径
- }).then((downloadTask: request.DownloadTask) => {
- downloadTask.on('complete', () => {
- const documentSaveOptions = new picker.DocumentSaveOptions(); // 创建文件管理器保存选项实例
- documentSaveOptions.newFileNames = [fileName]; // 保存文件名
- const documentViewPicker = new picker.DocumentViewPicker;
- documentViewPicker.save(documentSaveOptions)
- .then(async (documentSaveResult) => {
- // 获取到图片或者视频文件的URI后进行文件读取等操作
- let uri = documentSaveResult[0];
- if (uri) {
- // 沙箱路径文件
- let sanFile =
- fs.openSync(`${this.context.filesDir}/${fileName}`, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
- let pubFile = fs.openSync(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
- const plainText = getPlainText(sanFile);
- // 加密
- let encryptText = encryptMessage(symKey, plainText);
- fs.writeSync(pubFile.fd, encryptText.data.buffer);
- fs.unlink(sanFile.path);
- } else {
- // 取消保存到用户目录之后,删除沙箱目录下保存的文件
- fs.rmdirSync(`${this.context.filesDir}/${fileName}`);
- }
- }
- );
- });
- }
- ).catch((err: BusinessError) => {
- console.error(`Invoke downloadTask failed, code is ${err.code}, message is ${err.message}`);
- });
- }
-
- // 文件解密
- async decryptFile() {
- let uri: string = '';
- // 自定义文件名以及文件格式
- const fileName = `test${Date.now()}.docx`;
- let documentSelectOptions = new picker.DocumentSelectOptions();
- documentSelectOptions.fileSuffixFilters = [];
- documentSelectOptions.maxSelectNumber = 1;
- let documentViewPicker = new picker.DocumentViewPicker();
- await documentViewPicker.select(documentSelectOptions).then((documentSelectResult: Array<string>) => {
- uri = decodeURIComponent(documentSelectResult[0]);
- let pubFile = fs.openSync(uri, fs.OpenMode.READ_ONLY);
- let file =
- fs.openSync(`${this.context.filesDir}/${fileName}`, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); // 打开文件
-
- const plainText = getPlainText(pubFile);
- let decryptText = decryptMessage(symKey, plainText);
- fs.writeSync(file.fd, decryptText.data.buffer);
- const documentSaveOptions = new picker.DocumentSaveOptions(); // 创建文件管理器保存选项实例
- documentSaveOptions.newFileNames = [fileName];
- documentViewPicker.save(documentSaveOptions).then(async (documentSaveResult) => {
- let uri = documentSaveResult[0];
- if (uri) {
- let pubFile = fs.openSync(uri, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
- fs.copyFileSync(file.fd, pubFile.fd);
- fs.unlink(file.path);
- } else {
- fs.rmdirSync(`${this.context.filesDir}/${fileName}`);
- }
- });
- }).catch((err: Error) => {
- console.error(`Invoke documentViewPicker.select failed, code is ${err}, message is ${err.message}`);
- });
- }
-
- build() {
- RelativeContainer() {
- Row() {
- Button('下载加密保存')
- .fontSize(20)
- .fontWeight(FontWeight.Bold)
- .onClick(() => {
- this.downloadFileAndEncrypt();
- });
- Button('解密后保存')
- .fontSize(20)
- .fontWeight(FontWeight.Bold)
- .onClick(() => {
- this.decryptFile();
- });
- };
- }
- .height('100%')
- .width('100%');
- }
- }
智能客服
你问我答,随时在线为你解决问题
合作咨询
我们的专家服务团队将竭诚为您提供专业的合作咨询服务
解决方案
精准高效的一站式服务支持,助力开发者商业成功