1/* 2 * Copyright (c) 2023 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 promptAction from '@ohos.promptAction'; 17import Logger from '../util/Logger'; 18import picker from '@ohos.file.picker'; 19import { CryptoOperation } from '../cryptoframework/CryptoOperation'; 20import TextFileManager from '../textfilemanager/TextFileManager'; 21import common from '@ohos.app.ability.common'; 22 23const TAG: string = '[Crypto_Framework]'; 24 25@Component 26export struct Decrypt { 27 @State keyFileName: string = ''; 28 @State keyFileUri: string = ''; 29 @State textFileUri: string = ''; 30 @State textFileName: string = ''; 31 @State keyString: string = ''; 32 @State cipherText: string = ''; 33 @State plainText: string = ''; 34 @State message: string = ''; 35 @State decryptedFileUri: string = ''; 36 private CryptoOperation: CryptoOperation = new CryptoOperation(); 37 38 build() { 39 Stack({ alignContent: Alignment.Center }) { 40 Column() { 41 GridRow() { 42 GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { 43 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 44 List() { 45 ListItem() { 46 Row() { 47 Text($r('app.string.open_file')) 48 .fontSize(16) 49 .textAlign(TextAlign.Start) 50 .lineHeight(22) 51 52 Blank() 53 54 Text(this.textFileName === '' ? $r('app.string.please_choose') : this.textFileName) 55 .fontSize(14) 56 .textAlign(TextAlign.Start) 57 .lineHeight(19) 58 59 Image($r('app.media.right_arrow')) 60 .height('19vp') 61 .width('10vp') 62 .margin({ left: 9, right: 9, top: 6, bottom: 6 }) 63 } 64 .backgroundColor(0xFFFFFF) 65 .width('100%') 66 .height('52vp') 67 .padding({ top: 4, left: 12, right: 12 }) 68 }.onClick(() => { 69 this.selectTextFileAndRead(); 70 }) 71 72 ListItem() { 73 Row() { 74 Text($r('app.string.select_key_file')) 75 .fontSize(16) 76 .textAlign(TextAlign.Start) 77 .lineHeight(22) 78 79 Blank() 80 81 Text(this.keyFileName === '' ? $r('app.string.please_choose') : this.keyFileName) 82 .fontSize(14) 83 .textAlign(TextAlign.Start) 84 .lineHeight(19) 85 86 Image($r('app.media.right_arrow')) 87 .height('19vp') 88 .width('10vp') 89 .margin({ left: 9, right: 9, top: 6, bottom: 6 }) 90 } 91 .backgroundColor(0xFFFFFF) 92 .width('100%') 93 .height('48vp') 94 .padding({ left: 12, right: 12 }) 95 }.onClick(() => { 96 this.selectAesKeyFileAndRead(); 97 }) 98 } 99 .width('100%') 100 .height('100%') 101 .borderRadius(16) 102 } 103 } 104 } 105 .height('100vp') 106 .margin({ left: 12, right: 12, bottom: 12 }) 107 108 GridRow() { 109 GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { 110 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 111 Column() { 112 Row() { 113 Text($r('app.string.text_context')) 114 .fontSize(16) 115 .textAlign(TextAlign.Start) 116 .fontWeight(500) 117 .lineHeight(22) 118 } 119 .padding({ left: 12, right: 12 }) 120 .width('100%') 121 .height('48vp') 122 123 Row() { 124 Text() { 125 Span(this.cipherText) 126 .fontSize(16) 127 .fontWeight(400) 128 .fontColor('#182431') 129 }.textAlign(TextAlign.Start) 130 } 131 .padding({ left: 12, right: 12, bottom: 4 }) 132 .width('100%') 133 .height('52vp') 134 } 135 .borderRadius(16) 136 .width('100%') 137 .height('100') 138 .backgroundColor(0xFFFFFF) 139 } 140 } 141 } 142 .height('100vp') 143 .margin({ left: 12, right: 12, bottom: 12 }) 144 145 GridRow() { 146 GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { 147 Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { 148 Column() { 149 Row() { 150 Text($r('app.string.decrypted_context')) 151 .fontSize(16) 152 .textAlign(TextAlign.Start) 153 .fontWeight(500) 154 .lineHeight(22) 155 } 156 .padding({ left: 12, right: 12 }) 157 .width('100%') 158 .height('48vp') 159 160 Row() { 161 Text() { 162 Span(this.plainText) 163 .fontSize(16) 164 .fontWeight(400) 165 .fontColor('#182431') 166 }.textAlign(TextAlign.Start) 167 } 168 .padding({ left: 12, right: 12, bottom: 4 }) 169 .width('100%') 170 .height('52vp') 171 } 172 .borderRadius(16) 173 .width('100%') 174 .height('100') 175 .backgroundColor(0xFFFFFF) 176 } 177 } 178 } 179 .height('100vp') 180 .margin({ left: 12, right: 12, bottom: 12 }) 181 182 Column() { 183 GridRow() { 184 GridCol({ span: { xs: 12, sm: 12, md: 12, lg: 12 } }) { 185 Column() { 186 Button() { 187 Text($r('app.string.decrypt')).fontSize(16).fontWeight(500) 188 .lineHeight(22) 189 .fontColor('#FFFFFF') 190 } 191 .borderRadius(20) 192 .id('decryptionBtn') 193 .type(ButtonType.Capsule) 194 .margin({ left: 24, right: 24 }) 195 .width('100%') 196 .height('40vp') 197 .backgroundColor('#007DFF') 198 .onClick(() => { 199 if (this.textFileUri === '' || this.keyFileUri === '') { 200 promptAction.showToast({ 201 message: $r('app.string.null_message') 202 }); 203 } else { 204 this.decryptFunc(); 205 } 206 }); 207 } 208 } 209 }.margin({ left: 24, right: 24 }) 210 }.width('100%').height('296vp').justifyContent(FlexAlign.End) 211 } 212 .width('100%') 213 .height('100%') 214 } 215 } 216 217 async selectAesKeyFileAndRead() { 218 let config = { 219 action: 'ohos.want.action.OPEN_FILE', 220 parameters: { 221 startMode: 'choose', 222 } 223 } 224 let context = getContext(this) as common.UIAbilityContext; 225 let result = await context.startAbilityForResult(config); 226 if (result === null || result === undefined) { 227 Logger.error(TAG, `result is null or undefined!`); 228 return; 229 } 230 if (result.resultCode !== 0) { 231 Logger.error(TAG, `DocumentPicker.select failed, code is ${result.resultCode}, message is ${result.want.parameters.message}`); 232 return; 233 } 234 if (result.want.parameters.select_item_list === null || result.want.parameters.select_item_list === undefined) { 235 Logger.error(TAG, `result uri is null or undefined!`); 236 return; 237 } 238 if (result.want.parameters.file_name_list === null || result.want.parameters.file_name_list === undefined) { 239 Logger.error(TAG, `result file name is null or undefined!`); 240 return; 241 } 242 // 获取到密钥文档文件的URI 243 this.keyFileUri = result.want.parameters.select_item_list.toString(); 244 // 获取到密钥文档文件的文件名称 245 this.keyFileName = result.want.parameters.file_name_list.toString(); 246 await TextFileManager.readTextFile(this.keyFileUri); 247 this.keyString = TextFileManager.getString(); 248 } 249 250 async selectTextFileAndRead() { 251 let config = { 252 action: 'ohos.want.action.OPEN_FILE', 253 parameters: { 254 startMode: 'choose', 255 } 256 } 257 let context = getContext(this) as common.UIAbilityContext; 258 let result = await context.startAbilityForResult(config); 259 if (result === null || result === undefined) { 260 Logger.error(TAG, `result is null or undefined!`); 261 return; 262 } 263 if (result.resultCode !== 0) { 264 Logger.error(TAG, `DocumentPicker.select failed, code is ${result.resultCode}, message is ${result.want.parameters.message}`); 265 return; 266 } 267 if (result.want.parameters.select_item_list === null || result.want.parameters.select_item_list === undefined) { 268 Logger.error(TAG, `result uri is null or undefined!`); 269 return; 270 } 271 if (result.want.parameters.file_name_list === null || result.want.parameters.file_name_list === undefined) { 272 Logger.error(TAG, `result file name is null or undefined!`); 273 return; 274 } 275 // 获取到文档文件的URI 276 this.textFileUri = result.want.parameters.select_item_list.toString(); 277 // 获取到文档文件的文件名称 278 this.textFileName = result.want.parameters.file_name_list.toString(); 279 await TextFileManager.readTextFile(this.textFileUri); 280 this.cipherText = TextFileManager.getString(); 281 } 282 283 async createTextFileAndWrite() { 284 let documentSaveOptions = new picker.DocumentSaveOptions(); 285 documentSaveOptions.newFileNames = ['plainText.txt']; 286 let documentPicker = new picker.DocumentViewPicker(); 287 let documentSaveResult = await documentPicker.save(documentSaveOptions); 288 this.decryptedFileUri = documentSaveResult[0]; 289 await TextFileManager.writeTextFile(this.decryptedFileUri, this.plainText); 290 } 291 292 async decryptFunc() { 293 if (this.cipherText === '' || this.keyFileUri === '') { 294 promptAction.showToast({ 295 message: $r('app.string.null_message') 296 }); 297 return; 298 } 299 try { 300 this.plainText = await this.CryptoOperation.aesConvertAndDecrypt(this.keyString, this.cipherText); 301 } catch (error) { 302 Logger.error(TAG, `decrypt failed, ${error.code}, ${error.message}`); 303 promptAction.showToast({ 304 message: $r('app.string.decrypt_fail') 305 }); 306 return; 307 } 308 if (this.plainText === '' || this.plainText === null || this.plainText === undefined) { 309 promptAction.showToast({ 310 message: $r('app.string.decrypt_fail') 311 }); 312 return; 313 } else { 314 try { 315 await this.createTextFileAndWrite(); 316 } catch (error) { 317 Logger.error(TAG, `decrypt failed, ${error.code}, ${error.message}`); 318 } 319 } 320 if (this.decryptedFileUri === '' || typeof (this.decryptedFileUri) == 'undefined') { 321 promptAction.showToast({ 322 message: $r('app.string.decrypt_fail') 323 }); 324 } else { 325 promptAction.showToast({ 326 message: $r('app.string.decrypt_success') 327 }); 328 } 329 } 330} 331