HarmonyOS 鸿蒙Next huks密钥协商,能协商出128位的密钥吗

发布于 1周前 作者 eggper 来自 鸿蒙OS

HarmonyOS 鸿蒙Next huks密钥协商,能协商出128位的密钥吗

在huks文档中,密钥协商的案例协商出来的密钥都是256位的,只能进行aes256计算,我们想协商出128位的sm4密钥,请问huks是否支持

2 回复

ECDH ECC256算法协商出的共享秘钥长度是一定的为256位。

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/crypto-key-agreement-overview-V13#ecdh

服务端和客户端可以采用相同的PRF算法派生出128位的秘钥作为SM4的秘钥,例如以HMAC函数SHA256算法派生。

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V13/crypto-key-derivation-overview-V13

客户端demo:


import cryptoFramework from "@ohos.security.cryptoFramework";

import { CryptoUtil } from '@yunkss/eftool'

class StringBuilder {
  private value: string[];

  constructor() {

    this.value = [];

  }

  append(str: string | number): StringBuilder {

    this.value.push(String(str));

    return this;

  }

  toString(): string {

    return this.value.join('');

  }
}

@Entry
@Component
struct Index {
  @State message: string = 'Hello World';

  async generateShareKey(pubKey: string | Uint8Array, priKey: string | Uint8Array) {

    //公钥数据

    let pubKeyArray: Uint8Array = new Uint8Array();

    //私钥数据

    let priKeyArray: Uint8Array = new Uint8Array();

    if (typeof pubKey === 'string') {

      let pk = await CryptoUtil.convertPubKeyFromStr(pubKey as string, 'ECC256');

      pubKeyArray = pk.pubKey.getEncoded().data;

    } else {

      pubKeyArray = pubKey as Uint8Array;

    }

    if (typeof priKey === 'string') {

      let pk = await CryptoUtil.convertPriKeyFromStr(priKey as string, 'ECC256');

      priKeyArray = pk.priKey.getEncoded().data;

    } else {

      priKeyArray = priKey as Uint8Array;

    }

    //创建密钥生成器

    let eccGen = cryptoFramework.createAsyKeyGenerator('ECC256');

    let eccKeyAgreement = cryptoFramework.createKeyAgreement('ECC256');

    let keyPair = await eccGen.convertKey({ data: pubKeyArray }, { data: priKeyArray });

    let secret = await eccKeyAgreement.generateSecret(keyPair.priKey, keyPair.pubKey);

    return secret;

  }

  /**

   * 将字节流以16进制字符串输出

   * @param arr Uint8Array数组

   * @returns 字符串

   */
  unitArray2String(arr: Uint8Array): string {

    //转换成可以读懂的字符串

    let sb = new StringBuilder();

    arr.forEach((value) => {

      sb.append(('00' + value.toString(16)).slice(-2));

    });

    return sb.toString();

  }

  async generator() {

    let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator('ECC256');

    // 通过非对称密钥生成器,随机生成非对称密钥

    le

    async
    generator() {

      let asyKeyGenerator = cryptoFramework.createAsyKeyGenerator('ECC256');

      // 通过非对称密钥生成器,随机生成非对称密钥

      let promiseKeyPair = await asyKeyGenerator.generateKeyPair();

      let privateKey = promiseKeyPair.priKey.getEncoded();

      let publicKey = promiseKeyPair.pubKey.getEncoded();

      console.log('====' + this.unitArray2String(privateKey.data));

      console.log('====' + this.unitArray2String(publicKey.data));

    }

    async
    derivedKey() {

      // 客户端私钥

      let priK =
        "30310201010420d8895b35d1398ead5b05f4a414b42a244b004c9b37b35e88ae7c68a7f5b07fe2a00a06082a8648ce3d030107"

      // 服务端公钥

      let pubK =
        "3059301306072a8648ce3d020106082a8648ce3d030107034200044e960bfdca598087f8bf3caa71af5ba92f379e4ec4c12017babbdc0135526d2e6f24c8da9598791f1a5f8862c674781294f9a3a3f80264ccfcc2d48fe1c1df43";

      // 生成共享秘钥

      let shareKey = (await this.generateShareKey(pubK, priK)).data;

      console.log('====' + this.unitArray2String((shareKey)));

      // 派生128位秘钥

      let spec: cryptoFramework.PBKDF2Spec = {

        algName: 'PBKDF2',

        password: shareKey,

        salt: new Uint8Array(8),

        iterations: 1000,

        keySize: 16

      };

      let kdf = cryptoFramework.createKdf('PBKDF2|SHA256');

      let secret = await kdf.generateSecret(spec);

      console.info("=== key derivation output is " + this.unitArray2String(secret.data));

    }

    build() {

      Row() {

        Column() {

          Button(this.message)

            .fontSize(50)

            .fontWeight(FontWeight.Bold)

            .onClick(() => {

              this.derivedKey()

            })

        }

        .width('100%')

      }

      .height('100%')

    }

  }

问题二:

生成秘钥和派生秘钥需要同时设置成HUKS_STORAGE_KEY_EXPORT_ALLOWED。

https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/huks-key-derivation-arkts-V5

秘钥是否一致还可以通过加密相同明文对比密文是否相同。

安卓和鸿蒙在进行派生时,需要设置的属性参数要一致;

鸿蒙操作系统默认的编码字符集是UTF-8,而Java的是UTF-16,建议在进行java的字符串转换时指定参数为UTF-8

HarmonyOS 鸿蒙Next huks密钥协商,能协商出128位的密钥

HarmonyOS 鸿蒙Next系统确实支持密钥协商功能,这是通过其强大的加密框架实现的。关于huks(通用密钥库系统)密钥协商是否能协商出128位的密钥,这主要取决于所使用的密钥协商算法及其配置。

HarmonyOS 鸿蒙Next支持多种密钥协商算法,包括ECDH(基于椭圆曲线的Diffie-Hellman密钥交换)、X25519以及传统的DH算法等。这些算法能够协商出不同长度的密钥,以适应不同应用场景的安全需求。

对于AES等对称加密算法,HarmonyOS 鸿蒙Next确实支持128位密钥的生成和使用。但在密钥协商过程中,最终生成的密钥长度和类型取决于所选算法及其参数配置。

因此,要确定是否能协商出128位的密钥,需要具体查看所使用的密钥协商算法及其配置。如果配置正确且算法支持,那么协商出128位的密钥是完全可能的。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html

回到顶部