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 { LocalMockServer } from '../server/LocalMockServer'; 17import { aesGcmDecrypt, aesGcmEncrypt, generateAesKey } from '../utils/AesUtils'; 18import { rsaEncryption, verify } from '../utils/RsaUtils'; 19import { MessagePosition, sendProcessMessage } from '../utils/Utils'; 20 21const TAG: string = 'LocalClient'; 22 23class SignedData { 24 encryptedMessage: string = ""; 25 signedMessage: string = ""; 26} 27 28/** 29 * 本地客户端进行加密、验签 30 */ 31export class LocalClient { 32 private server: LocalMockServer = new LocalMockServer(); 33 private publicKey: string = ""; 34 private aesKey: string = ""; 35 36 // 客户端下载公钥 37 async downloadPublicKey() { 38 let publicKeyResult: SignedData = JSON.parse(await this.server.downloadPublicKey()); 39 // 验证公钥签名 40 if (await verify(publicKeyResult.encryptedMessage, publicKeyResult.signedMessage, 41 publicKeyResult.encryptedMessage)) { 42 this.publicKey = publicKeyResult.encryptedMessage; 43 } 44 if (this.publicKey === "") { 45 sendProcessMessage("获取公钥失败", MessagePosition.Right); 46 throw new Error('downloadPublicKey failed'); 47 } 48 sendProcessMessage("获取公钥成功", MessagePosition.Right); 49 } 50 51 // 发送数据到服务端 52 async sendMessageToServer(message: string): Promise<void> { 53 sendProcessMessage("开始发送数据到服务端...", MessagePosition.Right); 54 // 消息加密 55 let encryptionMessage: string = await this.encryption(message); 56 sendProcessMessage("发送加密数据到服务端...", MessagePosition.Right); 57 // 发送服务端 58 await this.server.receiveMessageFromClient(encryptionMessage); 59 } 60 61 // 从服务端接收数据 62 async receiveMessageFromServer(): Promise<string> { 63 sendProcessMessage("开始接收服务端数据...", MessagePosition.Right); 64 let signMessage: string = await this.server.sendMessageToClient(); 65 // 验证签名 66 let signData: SignedData = JSON.parse(signMessage); 67 sendProcessMessage("开始验证签名...", MessagePosition.Right); 68 let isVerified: boolean = await verify(signData.encryptedMessage, signData.signedMessage, this.publicKey); 69 if (isVerified) { 70 sendProcessMessage("签名验证成功,开始解密...", MessagePosition.Right); 71 let decryptedMessage = await aesGcmDecrypt(signData.encryptedMessage, this.aesKey); 72 sendProcessMessage("解密成功,解密结果:" + decryptedMessage, MessagePosition.Right); 73 return decryptedMessage; 74 } 75 sendProcessMessage("签名验证失败", MessagePosition.Right); 76 return "签名验证失败"; 77 } 78 79 // 加密 80 async encryption(message: string): Promise<string> { 81 if (!this.publicKey) { 82 sendProcessMessage("本地未找到公钥,开始下载...", MessagePosition.Right); 83 // 获取公钥 84 await this.downloadPublicKey(); 85 sendProcessMessage("公钥下载成功", MessagePosition.Right); 86 } 87 if (this.aesKey === "") { 88 sendProcessMessage("本地未找到AES密钥,开始生成...", MessagePosition.Right); 89 // 生成AES密钥 90 this.aesKey = await generateAesKey(); 91 sendProcessMessage(`AES密钥生成成功,密钥:${this.aesKey},开始发送到服务端...`, MessagePosition.Right); 92 // 将AES密钥发送到服务端 93 await this.sendAesKeyToServer(); 94 } 95 sendProcessMessage(`客户端开始加密数据...`, MessagePosition.Right); 96 let encryptionResult: string = await aesGcmEncrypt(message, this.aesKey); 97 sendProcessMessage(`客户端加密成功,加密结果:${encryptionResult}`, MessagePosition.Right); 98 // 使用AES加密数据 99 return encryptionResult; 100 } 101 102 // 发送AES密钥到服务端 103 async sendAesKeyToServer() { 104 sendProcessMessage(`AES密钥进行加密...`, MessagePosition.Right); 105 // 对AES密钥使用公钥进行加密 106 let encryptedAesKey: string = await rsaEncryption(this.aesKey, this.publicKey); 107 sendProcessMessage(`加密成功,加密结果:${encryptedAesKey},开始发送到服务端...`, MessagePosition.Right); 108 // 将加密后的AES密钥发送到服务端 109 await this.server.receiveKeyFromClient(encryptedAesKey); 110 } 111}