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 { cryptoFramework } from "@kit.CryptoArchitectureKit"; 17import Logger from "./Logger"; 18import { fromHexString, stringToUint8Array, TAG, uint8ArrayToShowStr } from "./Utils"; 19 20// RSA密钥对 21export interface RsaKey { 22 publicKey: string; 23 privateKey: string; 24} 25 26/** 27 * 生成RSA密钥对 28 * @returns RSA密钥对 29 */ 30export async function generateRsaKey(): Promise<RsaKey | undefined> { 31 try { 32 // 创建非对称密钥生成器 33 let rsaKeyGenerator: cryptoFramework.AsyKeyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024'); 34 // 通过密钥生成器随机生成非对称密钥 35 let keyPair: cryptoFramework.KeyPair = await rsaKeyGenerator.generateKeyPair(); 36 // 获取非对称密钥的二进制数据 37 let encodedPriKey: cryptoFramework.DataBlob = keyPair.priKey.getEncoded(); 38 // 私钥 39 let priKeyData: Uint8Array = encodedPriKey.data; 40 let encodedPubKey: cryptoFramework.DataBlob = keyPair.pubKey.getEncoded(); 41 // 公钥 42 let pubKeyData: Uint8Array = encodedPubKey.data; 43 let rsaKey: RsaKey = { 44 privateKey: uint8ArrayToShowStr(priKeyData), 45 publicKey: uint8ArrayToShowStr(pubKeyData) 46 }; 47 return rsaKey; 48 } catch (error) { 49 Logger.error(TAG, 'RSA create failed'); 50 return undefined; 51 } 52} 53 54/** 55 * RSA加密 56 * @param data 需要加密的数据 57 * @param publicKey 公钥 58 * @returns 完成加密的数据 59 */ 60export async function rsaEncryption(data: string, publicKey: string): Promise<string> { 61 try { 62 // 创建非对称密钥生成器实例 63 let rsaKeyGenerator: cryptoFramework.AsyKeyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024'); 64 // 将RSA密钥字符串转换为密钥类型 65 let pubKeyBlob: cryptoFramework.DataBlob = { data: fromHexString(publicKey) }; 66 let key: cryptoFramework.PubKey = (await rsaKeyGenerator.convertKey(pubKeyBlob, null)).pubKey; 67 // 指定算法名称(含密钥长度)、加密模式以及填充方法的组合 68 let cipherAlgName: string = 'RSA1024|PKCS1'; 69 let cipher: cryptoFramework.Cipher = cryptoFramework.createCipher(cipherAlgName); 70 // 表示进行加密操作 71 let mode: cryptoFramework.CryptoMode = cryptoFramework.CryptoMode.ENCRYPT_MODE; 72 // Cipher中init、update、doFinal为三段式接口,需要成组使用。其中init和doFinal必选,update可选。 73 // 初始化加解密的cipher对象 74 await cipher.init(mode, key, null); 75 // 将明文转换为Uint8Array,用于后续加密操作 76 let plainText: cryptoFramework.DataBlob = { data: fromHexString(data) }; 77 // 用于处理剩余数据和本次传入的数据,并最终结束加密或解密操作。 78 // 在RSA非对称加解密中,doFinal加解密本次传入的数据,通过注册回调函数获取加密或者解密数据。如果数据量较大,可以多次调用doFinal,拼接结果得到完整的明文/密文。 79 let encryptBlob: cryptoFramework.DataBlob = await cipher.doFinal(plainText); 80 return uint8ArrayToShowStr(encryptBlob.data); 81 } catch (err) { 82 Logger.error(TAG, `RSA encryption failed, ${err.code}, ${err.message}`); 83 } 84 return ""; 85} 86 87 88/** 89 * RSA解密 90 * @param encryptedData 经过加密的数据 91 * @param privateKey 私钥 92 * @returns 解密后的数据 93 */ 94export async function rsaDecryption(encryptedData: string, privateKey: string): Promise<string> { 95 try { 96 // 创建非对称密钥生成器实例 97 let rsaKeyGenerator: cryptoFramework.AsyKeyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024'); 98 // 将RSA密钥字符串转换为密钥类型 99 let priKeyBlob: cryptoFramework.DataBlob = { data: fromHexString(privateKey) }; 100 let key: cryptoFramework.PriKey = (await rsaKeyGenerator.convertKey(null, priKeyBlob)).priKey; 101 let cipherAlgName: string = 'RSA1024|PKCS1'; 102 let cipher: cryptoFramework.Cipher = cryptoFramework.createCipher(cipherAlgName); 103 // 表示进行解密操作 104 let mode: cryptoFramework.CryptoMode = cryptoFramework.CryptoMode.DECRYPT_MODE; 105 // Cipher中init、update、doFinal为三段式接口,需要成组使用。其中init和doFinal必选,update可选。 106 // 初始化加解密的cipher对象 107 await cipher.init(mode, key, null); 108 // 将秘文转换为Uint8Array,用于后续解密操作 109 let plainText: cryptoFramework.DataBlob = { data: fromHexString(encryptedData) }; 110 let decryptBlob: cryptoFramework.DataBlob = await cipher.doFinal(plainText); 111 return uint8ArrayToShowStr(decryptBlob.data); 112 } catch (err) { 113 Logger.error(TAG, `RSA decryption failed, ${err.code}, ${err.message}`); 114 } 115 return ""; 116} 117 118/** 119 * 验证签名 120 * @param encryptedData 待验证的数据 121 * @param singedData 签名信息 122 * @param publicKey 公钥 123 * @returns 签名验证是否通过 124 */ 125export async function verify(encryptedData: string, singedData: string, publicKey: string): Promise<boolean> { 126 try { 127 let verifyer = cryptoFramework.createVerify('RSA1024|PKCS1|SHA256'); 128 // 创建非对称密钥生成器实例 129 let rsaKeyGenerator: cryptoFramework.AsyKeyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024'); 130 // 将RSA密钥字符串转换为密钥类型 131 let pubKeyBlob: cryptoFramework.DataBlob = { data: fromHexString(publicKey) }; 132 let key: cryptoFramework.PubKey = (await rsaKeyGenerator.convertKey(pubKeyBlob, null)).pubKey; 133 let encryptedBlob: Uint8Array = stringToUint8Array(encryptedData); 134 let signedBlob: Uint8Array = fromHexString(singedData); 135 await verifyer.init(key); 136 let result: boolean = await verifyer.verify({ data: encryptedBlob }, { data: signedBlob }); 137 return result; 138 } catch (err) { 139 Logger.error(TAG, `RSA verify failed, ${err.code}, ${err.message}`); 140 } 141 return false; 142} 143 144/** 145 * 签名 146 * @param data 需要签名的数据 147 * @param privateKey 私钥 148 * @returns 签名信息 149 */ 150export async function sign(data: string, privateKey: string): Promise<string> { 151 try { 152 let signer = cryptoFramework.createSign('RSA1024|PKCS1|SHA256'); 153 // 创建非对称密钥生成器实例 154 let rsaKeyGenerator: cryptoFramework.AsyKeyGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024'); 155 // 将RSA密钥字符串转换为密钥类型 156 let priKeyBlob: cryptoFramework.DataBlob = { data: fromHexString(privateKey) }; 157 let key: cryptoFramework.PriKey = (await rsaKeyGenerator.convertKey(null, priKeyBlob)).priKey; 158 await signer.init(key); 159 let signBlob = stringToUint8Array(data); 160 let signedBlob = await signer.sign({ data: signBlob }); 161 let tmpArr: Uint8Array = signedBlob.data; 162 let rsaSignedBlobString = uint8ArrayToShowStr(tmpArr); 163 return rsaSignedBlobString; 164 } catch (error) { 165 Logger.error(TAG, `RSA sign failed, ${error.code}, ${error.message}`); 166 return ""; 167 } 168} 169