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

4 回复
  1. 最简单复用之前的js库, 但是没有提示什么的.

  2. 推荐用鸿蒙提供的原生密码框架.

转换一下数据类型. 将字符串的参数转换为 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模块实现,生成的密钥对以对象形式存在,而非字符串格式。具体步骤如下:

  1. 创建密钥生成器:使用cryptoFramework.createAsyKeyGenerator方法创建RSA密钥生成器。
  2. 生成密钥对:调用generateKeyPair方法生成RSA密钥对,返回的是一个包含公钥和私钥的对象。
  3. 获取密钥数据:通过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对象包含公钥和私钥,分别是PublicKeyPrivateKey类型,可以通过getEncoded()方法获取字节数组形式的密钥数据。

回到顶部