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 { LocalClient } from '../client/LocalClient'; 17import { KeyboardAvoidMode } from '@kit.ArkUI'; 18import { emitter } from '@kit.BasicServicesKit'; 19import { Message, messageEvent, MessagePosition, sendProcessMessage } from '../utils/Utils'; 20import { inputMethod } from '@kit.IMEKit'; 21 22/** 23 * 模拟数据加密传输流程 24 * 1. 请求服务端,获取公钥。 25 * 2. 服务端生成RSA密钥,用私钥对公钥签名后返回给客户端。 26 * 3. 客户端验证公钥签名。 27 * 4. 生成AES密钥,通过公钥加密后发送到服务端 28 * 5. 服务端解密并存储AES密钥 29 * 6. 客户端使用AES密钥对数据进行加密,发送给服务端 30 * 7. 服务端使用AES密钥对数据进行解密,存储 31 * 8. 服务端使用AES密钥对数据进行加密 32 * 9. 服务端使用私钥对数据签名,并发送给客户端 33 * 10. 客户端使用公钥对数据验签,判断是否成功 34 * 11. 验签成功后使用AES密钥解密数据 35 */ 36 37@Entry 38@Component 39struct KeyManager { 40 @State message: string = ""; 41 private client: LocalClient = new LocalClient(); 42 @State messageArray: Message[] = []; 43 44 aboutToAppear(): void { 45 this.getUIContext().setKeyboardAvoidMode(KeyboardAvoidMode.RESIZE); 46 47 emitter.on(messageEvent, (data: emitter.EventData) => { 48 let message: Message = new Message(); 49 message.message = data.data?.message; 50 message.position = data.data?.position; 51 this.messageArray.push(message); 52 }); 53 } 54 55 build() { 56 RelativeContainer() { 57 Row() { 58 TextInput({ text: this.message, placeholder: $r('app.string.please_input') }) 59 .id('input') 60 .onChange((value: string) => { 61 this.message = value; 62 }) 63 .layoutWeight(4) 64 Button($r('app.string.send')) 65 .id('button') 66 .onClick(() => { 67 inputMethod.getController().stopInputSession(); 68 this.sendMessage(this.message); 69 this.message = ""; 70 }) 71 .layoutWeight(1) 72 .margin({ 73 left: 10 74 }) 75 } 76 .padding({ 77 left: 10, 78 right: 10 79 }) 80 .alignRules({ 81 bottom: { anchor: '__container__', align: VerticalAlign.Bottom }, 82 left: { anchor: '__container__', align: HorizontalAlign.Start }, 83 right: { anchor: '__container__', align: HorizontalAlign.End } 84 }) 85 .height(60) 86 .alignItems(VerticalAlign.Center) 87 .width('100%') 88 .id("row_input") 89 90 List() { 91 ForEach(this.messageArray, (message: Message) => { 92 ListItem() { 93 Row() { 94 Text(message.message) 95 .padding(10) 96 .fontColor(message.position === MessagePosition.Left ? Color.Blue : Color.Black) 97 .constraintSize({ 98 maxWidth: '80%' 99 }) 100 .borderRadius(10) 101 .backgroundColor("#F1F1F1") 102 .margin({ 103 left: message.position === MessagePosition.Left ? 10 : 0, 104 right: message.position === MessagePosition.Right ? 10 : 0 105 }) 106 } 107 .width('100%') 108 .justifyContent(message.position === MessagePosition.Left ? FlexAlign.Start : FlexAlign.End) 109 .margin({ 110 top: 10 111 }) 112 } 113 }) 114 }.id('list') 115 .scrollBar(BarState.Off) 116 .alignRules({ 117 bottom: { anchor: 'row_input', align: VerticalAlign.Top }, 118 top: { anchor: '__container__', align: VerticalAlign.Top }, 119 left: { anchor: '__container__', align: HorizontalAlign.Start }, 120 right: { anchor: '__container__', align: HorizontalAlign.End } 121 }) 122 .expandSafeArea([SafeAreaType.KEYBOARD]) 123 124 } 125 .height('100%') 126 .width('100%') 127 } 128 129 async sendMessage(message: string) { 130 sendProcessMessage("需要发送给服务端的数据是:" + message, MessagePosition.Right); 131 await this.client.sendMessageToServer(message); 132 133 setTimeout(async () => { 134 await this.client.receiveMessageFromServer(); 135 }, 2000) 136 } 137}