HarmonyOS鸿蒙Next中RSA密钥对生成非字符串
HarmonyOS鸿蒙Next中RSA密钥对生成非字符串 为什么https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/crypto-rsa-asym-encrypt-decrypt-pkcs1-V5这份文档所讲解的rsa的公钥和私钥生产出来是这样,不是字符串的格式呢。
async function genKeyPairByData(pubKeyData: Uint8Array, priKeyData: Uint8Array) {
let pubKeyBlob: cryptoFramework.DataBlob = { data: pubKeyData };
let priKeyBlob: cryptoFramework.DataBlob = { data: priKeyData };
let rsaGenerator = cryptoFramework.createAsyKeyGenerator('RSA1024');
let keyPair = await rsaGenerator.convertKey(pubKeyBlob, priKeyBlob);
console.info('convertKey success');
return keyPair;
}
项目迁移到鸿蒙中之前使用的是JSEncrypt进行加密解密,密钥公钥都是字符串,但是现在使用鸿蒙的无法加密解密,针对我们现在的情况有什么解决的办法吗
更多关于HarmonyOS鸿蒙Next中RSA密钥对生成非字符串的实战教程也可以访问 https://www.itying.com/category-93-b0.html
-
最简单复用之前的js库, 但是没有提示什么的.
-
推荐用鸿蒙提供的原生密码框架.
转换一下数据类型. 将字符串的参数转换为 Uint8Array
, 核心代码.
new Uint8Array(buffer.from(message, 'utf-8').buffer)
有个加密的demo 包括了.rsa 的加密. 可以参考: https://gitee.com/harmonyos_samples/crypto-collection
更多关于HarmonyOS鸿蒙Next中RSA密钥对生成非字符串的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
当前给出的api只能接受Uint8Array格式,若入参为字符串,需要使用Base64Helper进行格式转换。 下面是一个实现RSA的公钥PK,加密一段文字的demo,可以参考
密钥规格:
static ASY_KEY_NAME_RSA_3072: string = 'RSA1024';
static ALG_NAME_RSA_3072: string = 'RSA|ECB|PKCS1';
static priKey: Uint8Array = new Uint8Array(); //用于临时保存
static pubKey: Uint8Array = new Uint8Array(); //用于临时保存
// 生成非对称密钥对
public static async generateRsaKeyPair(): Promise<KeyPair> {
let keyPair: KeyPair = new KeyPair();
try {
let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(this.ASY_KEY_NAME_RSA_3072);
const tempKeyPair = await asyKeyGenerator.generateKeyPair();
keyPair = {
publicKey: base.encodeToStringSync(tempKeyPair.pubKey.getEncoded().data),
privateKey: base.encodeToStringSync(tempKeyPair.priKey.getEncoded().data)
}
} catch (err) {
console.error(err)
}
return keyPair;
}
主体方法:
// 加密
public static async add(str: string, publicKey: string): Promise<string> {
let result = '';
try {
let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(this.ASY_KEY_NAME_RSA_3072);
//创建一个 Cipher (解密)对象
let cipher = cryptoFramework.createCipher(this.ALG_NAME_RSA_3072);
//引入外部的公钥加密
const publicKeyDataBlob = { data: base.decodeSync(publicKey) };
let keyGenPromise: cryptoFramework.KeyPair = await asyKeyGenerator.convertKey(publicKeyDataBlob, null);
await cipher.init(cryptoFramework.CryptoMode.ENCRYPT_MODE, keyGenPromise.pubKey, null);
let put: cryptoFramework.DataBlob = { data: stringToUint8Array(str) };
const finalRes = await cipher.doFinal(put)
result = base.encodeToStringSync(finalRes.data);
} catch (err) {
console.log(err.message)
}
return result;
}
// 解密
public static async rsaDecrypt(message: string | Uint8Array, privateKey: string): Promise<string> {
let result = '';
try {
let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator(this.ASY_KEY_NAME_RSA_3072);
const privateKeyDataBlob = { data: base.decodeSync(privateKey) };
const keyPair = await asyKeyGenerator.convertKey(null, privateKeyDataBlob);
let cipher = cryptoFramework.createCipher(this.ALG_NAME_RSA_3072); //创建一个 Cipher (解密)对象
await cipher.init(cryptoFramework.CryptoMode.DECRYPT_MODE, keyPair.priKey, null);
let bytes: Uint8Array = null;
if (typeof message === 'string') {
bytes = base.decodeSync(message);
} else {
bytes = message;
}
const finalRes = await cipher.doFinal({ data: bytes })
result = uint8ArrayToString(finalRes.data);
} catch (err) {
console.error(err.code)
}
return result;
}
公共方法:
const base = new util.Base64Helper();
// 字符串转成字节流
function stringToUint8Array(str: string) {
return new Uint8Array(buffer.from(str,'utf-8').buffer);
}
// 字节流转成可理解的字符串
function uint8ArrayToString(array:Uint8Array) {
// 将UTF-8编码转换成Unicode编码
let out: string = "";
let index: number = 0;
let len: number = array.length;
while (index < len) {
let character = array[index++];
switch(character >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
out += String.fromCharCode(character);
break;
case 12:
case 13:
out += String.fromCharCode(((character & 0x1F) << 6) | (array[index++] & 0x3F));
break;
case 14:
out += String.fromCharCode(((character & 0x0F) << 12) | ((array[index++] & 0x3F) << 6) | ((array[index++] & 0x3F) << 0));
break;
default:
break;
}
}
return out;
}
在HarmonyOS鸿蒙Next中,RSA密钥对的生成可以通过cryptoFramework
模块实现,生成的密钥对以对象形式存在,而非字符串格式。具体步骤如下:
- 创建密钥生成器:使用
cryptoFramework.createAsyKeyGenerator
方法创建RSA密钥生成器。 - 生成密钥对:调用
generateKeyPair
方法生成RSA密钥对,返回的是一个包含公钥和私钥的对象。 - 获取密钥数据:通过
getEncoded
方法获取公钥和私钥的二进制数据,而非字符串。
示例代码如下:
import cryptoFramework from '@ohos.security.cryptoFramework';
let rsaKeyGen = cryptoFramework.createAsyKeyGenerator("RSA1024|PRIMES_2");
rsaKeyGen.generateKeyPair((err, keyPair) => {
if (err) {
console.error("Failed to generate RSA key pair.");
return;
}
let pubKey = keyPair.pubKey;
let priKey = keyPair.priKey;
pubKey.getEncoded((err, data) => {
if (err) {
console.error("Failed to get public key data.");
return;
}
console.info("Public key data: " + data);
});
priKey.getEncoded((err, data) => {
if (err) {
console.error("Failed to get private key data.");
return;
}
console.info("Private key data: " + data);
});
});
该代码片段展示了如何在鸿蒙Next中生成RSA密钥对并获取其二进制数据。
在HarmonyOS鸿蒙Next中,RSA密钥对的生成可以通过Security
模块实现。使用KeyPairGenerator
类可以生成非字符串形式的密钥对。以下是一个示例代码:
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "HarmonyOS");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
生成的KeyPair
对象包含公钥和私钥,分别是PublicKey
和PrivateKey
类型,可以通过getEncoded()
方法获取字节数组形式的密钥数据。