通用密钥管理
介绍
本示例介绍了如何使用AES和RSA进行数据加解密,并模拟了服务端和客户端的加解密通信流程。
效果图预览

使用说明:
- 点击输入框,输入任何内容,点击“发送”按钮,页面将会展示客户端和服务端的加解密通信过程。
- 客户端会在2s后调用模拟服务端的方法,页面将会展示签名验证数据的过程。
实现思路
-
创建页面,添加List用于显示加解密流程信息,添加TextInput用于输入数据。详细代码可参考Index.ets。
@Entry @Component struct KeyManager { ... build() { RelativeContainer() { Row() { TextInput({ text: this.message, placeholder: '请输入内容' }) .id('input') .onChange((value: string) => { this.message = value; }) .layoutWeight(4) ... } ... List() { ForEach(this.messageArray, (message: Message) => { ListItem() { Row() { Text(message.message) .padding(10) .fontColor(message.position === MessagePosition.Left ? Color.Blue : Color.Black) .constraintSize({ maxWidth: '80%' }) .borderRadius(10) .backgroundColor("#F1F1F1") .margin({ left: message.position === MessagePosition.Left ? 10 : 0, right: message.position === MessagePosition.Right ? 10 : 0 }) } ... } }) } ... } } -
分别实现AES密钥生成方法和加解密方法。详细代码可参考AesUtils.ets。
/** * 生成AES密钥 * @returns AES密钥的16进制字符串 */ export async function generateAesKey(): Promise<string> { ... } /** * AES解密 * @param encryptedMessage 已经加密的数据 * @param aesKey AES密钥 * @returns 解密后的数据 */ export async function aesGcmDecrypt(encryptedMessage: string, aesKey: string): Promise<string> { ... } /** * AES加密 * @param textString 需要加密的数据 * @param aesKey AES密钥 * @returns */ export async function aesGcmEncrypt(textString: string, aesKey: string): Promise<string> { ... } -
分别实现RSA密钥生成方法、加解密方法、签名验证方法。详细代码可参考RsaUtils.ets。
/** * 生成RSA密钥对 * @returns RSA密钥对 */ export async function generateRsaKey(): Promise<RsaKey | undefined> { ... } /** * RSA加密 * @param data 需要加密的数据 * @param publicKey 公钥 * @returns 完成加密的数据 */ export async function rsaEncryption(data: string, publicKey: string): Promise<string> { ... } /** * RSA解密 * @param encryptedData 经过加密的数据 * @param privateKey 私钥 * @returns 解密后的数据 */ export async function rsaDecryption(encryptedData: string, privateKey: string): Promise<string> { ... return ""; } /** * 验证签名 * @param encryptedData 待验证的数据 * @param singedData 签名信息 * @param publicKey 公钥 * @returns 签名验证是否通过 */ export async function verify(encryptedData: string, singedData: string, publicKey: string): Promise<boolean> { ... } /** * 签名 * @param data 需要签名的数据 * @param privateKey 私钥 * @returns 签名信息 */ export async function sign(data: string, privateKey: string): Promise<string> { ... } -
在客户端中进行AES密钥生成、加解密以及RSA加密。详细代码可参考LocalClient.ets。
// 客户端下载公钥 async downloadPublicKey() { let publicKeyResult: SignedData = JSON.parse(await this.server.downloadPublicKey()); // 验证公钥签名 if (await verify(publicKeyResult.encryptedMessage, publicKeyResult.signedMessage, publicKeyResult.encryptedMessage)) { this.publicKey = publicKeyResult.encryptedMessage; } if (this.publicKey === "") { sendProcessMessage("获取公钥失败", MessagePosition.Right); throw new Error('downloadPublicKey failed'); } sendProcessMessage("获取公钥成功", MessagePosition.Right); } // 发送数据到服务端 async sendMessageToServer(message: string): Promise<void> { sendProcessMessage("开始发送数据到服务端...", MessagePosition.Right); // 消息加密 let encryptionMessage: string = await this.encryption(message); sendProcessMessage("发送加密数据到服务端...", MessagePosition.Right); // 发送服务端 await this.server.receiveMessageFromClient(encryptionMessage); } // 从服务端接收数据 async receiveMessageFromServer(): Promise<string> { sendProcessMessage("开始接收服务端数据...", MessagePosition.Right); let signMessage: string = await this.server.sendMessageToClient(); // 验证签名 let signData: SignedData = JSON.parse(signMessage); sendProcessMessage("开始验证签名...", MessagePosition.Right); let isVerified: boolean = await verify(signData.encryptedMessage, signData.signedMessage, this.publicKey); if (isVerified) { sendProcessMessage("签名验证成功,开始解密...", MessagePosition.Right); let decryptedMessage = await aesGcmDecrypt(signData.encryptedMessage, this.aesKey); sendProcessMessage("解密成功,解密结果:" + decryptedMessage, MessagePosition.Right); return decryptedMessage; } sendProcessMessage("签名验证失败", MessagePosition.Right); return "签名验证失败"; } // 加密 async encryption(message: string): Promise<string> { if (!this.publicKey) { sendProcessMessage("本地未找到公钥,开始下载...", MessagePosition.Right); // 获取公钥 await this.downloadPublicKey(); sendProcessMessage("公钥下载成功", MessagePosition.Right); } if (this.aesKey === "") { sendProcessMessage("本地未找到AES密钥,开始生成...", MessagePosition.Right); // 生成AES密钥 this.aesKey = await generateAesKey(); sendProcessMessage(`AES密钥生成成功,密钥:${this.aesKey},开始发送到服务端...`, MessagePosition.Right); // 将AES密钥发送到服务端 await this.sendAesKeyToServer(); } sendProcessMessage(`客户端开始加密数据...`, MessagePosition.Right); let encryptionResult: string = await aesGcmEncrypt(message, this.aesKey); sendProcessMessage(`客户端加密成功,加密结果:${encryptionResult}`, MessagePosition.Right); // 使用AES加密数据 return encryptionResult; } // 发送AES密钥到服务端 async sendAesKeyToServer() { sendProcessMessage(`AES密钥进行加密...`, MessagePosition.Right); // 对AES密钥使用公钥进行加密 let encryptedAesKey: string = await rsaEncryption(this.aesKey, this.publicKey); sendProcessMessage(`加密成功,加密结果:${encryptedAesKey},开始发送到服务端...`, MessagePosition.Right); // 将加密后的AES密钥发送到服务端 await this.server.receiveKeyFromClient(encryptedAesKey); } -
在客户端中进行AES密钥生成、加解密以及RSA加密。详细代码可参考LocalClient.ets。
//生成证书 async createKey() { sendProcessMessage("模拟服务端开始生成证书", MessagePosition.Left); let rsaKey: RsaKey | undefined = await generateRsaKey() if (rsaKey) { this.publicKey = rsaKey.publicKey; this.privateKey = rsaKey.privateKey; sendProcessMessage("模拟服务端生成证书成功,公钥:" + this.publicKey, MessagePosition.Left); } } // 模拟公钥下载 async downloadPublicKey(): Promise<string> { if (this.publicKey === "") { // 创建密钥 await this.createKey(); } // 对公钥进行签名 let signResult: string = await sign(this.publicKey, this.privateKey); let publicKeyResult: SignedData = { encryptedMessage: this.publicKey, signedMessage: signResult }; return JSON.stringify(publicKeyResult); } async receiveKeyFromClient(encryptedAesKey: string) { sendProcessMessage(`模拟服务端接收到AES密钥:${encryptedAesKey}`, MessagePosition.Left); this.aesKey = await rsaDecryption(encryptedAesKey, this.privateKey); sendProcessMessage(`模拟服务端AES密钥解密成功,AES密钥为:${this.aesKey}`, MessagePosition.Left); Logger.info(TAG, 'receive key from client success, server aesKey:' + this.aesKey); } // 获取客户端消息 async receiveMessageFromClient(message: string): Promise<void> { sendProcessMessage("模拟服务端接收到数据,开始解密...", MessagePosition.Left); // 解密 let decryptedMessage = await aesGcmDecrypt(message, this.aesKey); sendProcessMessage(`模拟服务端解密成功,解密结果:${decryptedMessage}`, MessagePosition.Left); // 存储 this.messageStorage.push(decryptedMessage); } async sendMessageToClient(): Promise<string> { let needSendMessage: string = "这是模拟服务端返回的测试数据," + this.messageStorage[this.messageStorage.length-1]; sendProcessMessage(`模拟服务端开始发送数据,将要发送的数据是:${needSendMessage}`, MessagePosition.Left); sendProcessMessage(`模拟服务端开始加密数据:${needSendMessage}`, MessagePosition.Left); let encryptedMessage: string = await aesGcmEncrypt(needSendMessage, this.aesKey); sendProcessMessage(`模拟服务端加密成功,加密结果:${encryptedMessage}`, MessagePosition.Left); // 签名 sendProcessMessage(`模拟服务端开始签名数据...`, MessagePosition.Left); let signedMessage: string = await sign(encryptedMessage, this.privateKey); sendProcessMessage(`模拟服务端签名成功,签名结果:${signedMessage}`, MessagePosition.Left); let signData: SignedData = { encryptedMessage: encryptedMessage, signedMessage: signedMessage }; // 发送消息 return JSON.stringify(signData); }
工程结构&模块类型
KeyManger // har类型
|---client
| |---LocalClient.ets // 模拟客户端
|---pages
| |---KeyManager.ets // 应用页面
|---server
| |---LocalMockServer.ets // 模拟服务端
|---utils
| |---AesUtils.ets // AES加密工具类
| |---Logger.ets // 日志打印类
| |---RsaUtils.ets // RSA加密工具类
| |---Utils.ets // 其他公用方法
模块依赖
无
相关权限
无
约束与限制
-
本示例仅支持标准系统上运行。
-
本示例为Stage模型,从API version 12开始支持。SDK版本号:5.0.0.71 Release,镜像版本号:OpenHarmony 5.0.1.107。
-
本示例需要使用DevEco Studio 5.0.4 Release (Build Version: 5.0.11.100, built on March 28, 2025)编译运行。
下载
如需单独下载本工程,执行如下命令:
git init
git config core.sparsecheckout true
echo code/BasicFeature/Security/KeyManager/ > .git/info/sparse-checkout
git remote add origin https://gitee.com/openharmony/applications_app_samples.git
git pull origin master