密钥派生算法KDF

NOTE

     密钥派生算法的关键点如下

  1. 伪随机函数
  2. 迭代次数
  3. 初始密钥材料,如密码、盐等
  4. 块关系,类似对称加密模式的ECB或者CBC等

定义

        密钥派生算法是从一个密钥产生一个或多个密钥的过程,产生的密钥可用于不同的安全需求,比如加解密、身份验证和完整性保护等。派生过程涉及迭代、散列或者加密等操作,以确保生成的密钥具有高度的随机性和不可预测性。

应用场景

  1. 加解密(一次一密):在数据存储时,需要保护数据的机密性,密钥派生算法可生成数据加解密使用的密钥,同时可以确保密钥的安全性和可靠性
  2. 身份校验:密钥派生算法可以生成用户密码派生密钥,派生密钥可验证用户身份或进行其他安全操作
  3. 通信协议:在安全通信协议中经常需要多个不同密钥来实现不同的安全功能,通过密钥派生算法可以从一个主密钥中派生出多个子密钥,并分别用于加密、解密、签名、验签等功能

算法详情

        存在多个密钥派生算法,可根据实际应用场景进行选择。经常用到的有PBKDF2(Password-Based Key Derivation Function),国密SM2算法中派生算法,NIST SP 800-108定义的三种算法(基于计数器/基于反馈/基于双线叠加),HKDF等。本文实战选择HKDF

        HKDF是基于HMAC的密钥派生函数。分为俩部分,第一部分是从初始密钥材料中提取出固定长度的伪随机密钥key;第二部分扩展key到我们指定长度

提取过程:

        HKDF-Extract(salt, IKM) -> PRK

        Hash:Hash函数,HashLen表示hash函数输出的字节数

        salt:非秘密随机值,不提供时使用HashLen个0

        IKM:输入的密钥材料

        PRK:输出HashLen字节长的伪随机化密钥

        PRK = HMAC-Hash(salt, IKM)

        本质上就是把初始密钥材料加盐做一次 Hmac-Hash

扩展过程:

        HKDF-Expand(PRK, info, L) -> OKM

        PRK:提取阶段的输出

        info:可选值

        L:期望输出的密钥长度

        OKM:派生的密钥

OKM计算过程:

        N = ceil(L/HashLen)        // 至少迭代N次才能够派生密钥L长度的切割

        T = T(1) | T(2) | T(3) | ... | T(N)

        OKM = first L octets of T        // 拼接迭代结果,从起始地址开始截取所需长度作为派生密

        T(N)计算过程

                T(0) = empty string (zero length)

                T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)

                T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)

                T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)

代码:

int T(const char *hashAlg, int n, char *prk, int prkLen, char *info, int infoLen, char *tPre, char *t) {
  char *mac = NULL;
  char *m = NULL;
  int mLen = 0;
  int ret = 0;
  int hashLen = 0; // 根据所选hash算法设置

  m = Malloc(hashLen + infoLen + 1);

  if (nullptr == tPre) {
    memcpy(m, info, infoLen);
    memcpy(m+ infoLen, (char *)&n, 1);
    mLen = infoLen + 1;
  } else {
    memcpy(m, tPre, hashLen);
    memcpy(m+ hashLen, info, infoLen);
    memcpy(m+ hashLen + infoLen, (char *)&n, 1);
    mLen = hashLen + infoLen + 1;
  }

  ret = HMAC(hashAlg, prk, prkLen, message, messageLen, &mac);
  if (ret > 0) {
    memcpy(t, mac, hashLen);
  }
  Free(mac);
  Free(m);

  return ret;
}

int HKDF_Expand(const char *hashAlg, char *prk, int prkLen, char *info, int infoLen, char *okm, int okmLen) {
  int ret = 0;
  int N = 0;
  int i = 0;
  char *t[255] = {0};
  int hashLen = 0; // 根据选择的hash算法设置

  N = okmLen / hashLen;
  if (okmLen % hashLen != 0) {
    N++;
  }
  if (N > 255) {
    return -1;
  }

  t[0] = NULL;
  for (i = 1; i <= N; i++) {
    t[i] = Malloc(hashLen);
    ret = T(hashAlg, i, prk, prkLen, info, infoLen, t[i - 1], t[i]);
    if (ret < 0) {
      goto FREE;
    }
  }

  for (i = 1; i <= N; i++) {
    if (i == N && okmLen % hashLen) {
      memcpy(okm + hashLen * (i - 1), t[i], okmLen % hashLen);
    } else {
      memcpy(okm + hashLen * (i - 1), t[i], hashLen);
    }
  }

  ret = okmLen;
  i--;

FREE:
  for (; i > 0; i--) {
    Free(t[i]);
  }

  return ret;
}

int HKDF_Extract(const char *hashAlg, char *salt, int saltLen, char *ikm, int ikmLen, char *prk, int prkLen) {
  char *mac = NULL;
  int ret = 0;
  int hashLen = 0; // 根据选择的hash算法设置为hash结果的长度
  char saltInit[hashLen] = {0};

  if (NULL == salt) {
    ret = HMAC(hashAlg, saltInit, hashLen, ikm, ikmLen, &mac);
  } else {
    ret = HMAC(hashAlg, salt, saltLen, ikm, ikmLen, &mac);
  }
  if (ret > 0) {
    if (ret > prkLen) {
      return -1;
    }
    memcpy(prk, mac, ret);
    Free(mac);
  }

  return ret;
}

int HKDF(const char *hashAlg, char *salt, int saltLen, char *ikm, int ikmLen, char *info, int infoLen, char *okm, int okmLen) {
  char prk[64] = {0};
  int prkLen = 64;
  int ret = 0;

  ret = HKDF_Extract(hashAlg, salt, saltLen, ikm, ikmLen, prk, prkLen);
  if (ret < 0) {
    return ret;
  }
  prkLen = ret;

  return HKDF_Expand(hashAlg, prk, prkLen, info, infoLen, okm, okmLen);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值