首页 > 编程语言 >密钥派生算法KDF

密钥派生算法KDF

时间:2025-01-23 11:58:17浏览次数:3  
标签:infoLen 派生 int KDF ret char 密钥 hashLen

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(int n, char *prk, int prkLen, char *info, int infoLen, char *tPre, char *t) {
  char *mac = nullptr;
  char *message = nullptr;
  int messageLen = 0;
  int ret = 0;
  int hashLen = 32;

  if ((infoLen > 0 && nullptr == info) || infoLen < 0) {
    infoLen = 0;
  }

  message = Malloc(hashLen + infoLen + 1);

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

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

  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(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) {  // 当指定产生密钥长度不是hashLen的整数倍时,处理最后一块数据
      memcpy(okm + hashLen * (i - 1), t[i], okmLen % hashLen);
    } else {
      memcpy(okm + hashLen * (i - 1), t[i], hashLen);
    }
  }

  ret = okmLen;
  i--;  // 处理for循环成功时,i值比有效下标大1

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

  return ret;
}

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

  if (NULL == salt) {
    ret = HMAC(saltInit, hashLen, key, keyLen, &mac);
  } else {
    ret = HMAC(salt, saltLen, key, keyLen, &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 *key, int keyLen, char *info, int infoLen, char *okm, int okmLen) {
  char prk[64] = {0};
  int prkLen = 64;
  int ret = 0;

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

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

标签:infoLen,派生,int,KDF,ret,char,密钥,hashLen
From: https://blog.csdn.net/summermeet/article/details/145186294

相关文章

  • Java实现DES编码加解密 - 密钥为: Text
    编写工具类publicclassDesPasswordUtil{publicstaticfinalStringWIFI_DES_KEY="TmuhP9PD";/***生成密钥**@return{@linkString}*@throwsException例外*/publicstaticSecretKeySpeccreateKeyFromText(Stri......
  • Java实现DES编码加解密 - 密钥为: Hex
    编写工具类publicclassDesPasswordUtil{publicstaticfinalStringWIFI_DES_KEY="TmuhP9PDtcQ=";/***生成密钥**@return{@linkString}*@throwsException例外*/publicstaticStringgenerateKey()throwsExce......
  • SM9 - 密钥封装机制和公钥加密算法
    符号A,B:使用公钥密码系统的两个用户。\(cf\):椭圆曲线阶相对于\(N\)的余因子。\(cid\):用一个字节表示的曲线的标识符,其中\(\mbox{0x10}\)表示\(F_p\)(素数\(P>2^{191}\))上常曲线(即非超奇异曲线),\(\mbox{0x11}\)表示\(F_p\)表示超奇异曲线,\(\mbox{0x12}\)表示\(F_p\)上常曲线及其扭......
  • JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请
    目录JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)一、什么时候该使用Array.map(),与forEach()的区别是什么?1、什么时候该用Array.map()2、Array.map()与Array.forEach()的......
  • SM9 - 密钥交换协议
    符号A,B:使用公钥密码系统的两个用户。\(cf\):椭圆曲线阶相对于\(N\)的余因子。\(cid\):用一个字节表示的曲线的标识符,其中\(\mbox{0x10}\)表示\(F_p\)(素数\(P>2^{191}\))上常曲线(即非超奇异曲线),\(\mbox{0x11}\)表示\(F_p\)表示超奇异曲线,\(\mbox{0x12}\)表示\(F_p\)上常曲线及其扭......
  • 网站优化排名:解锁搜索引擎流量的密钥
    在数字化时代,网站不仅是企业线上身份的象征,更是连接潜在客户的桥梁。然而,在数以亿计的网站中脱颖而出,让目标受众轻松找到你,并非易事。网站优化排名,即通过一系列策略和技术手段提升网站在搜索引擎结果页面(SERP)上的排名,成为了吸引高质量流量、提升品牌知名度和促进业务增长的关......
  • SpringBoot集成ECDH密钥交换
    简介对称加解密算法都需要一把秘钥,但是很多情况下,互联网环境不适合传输这把对称密码,有密钥泄露的风险,为了解决这个问题ECDH密钥交换应运而生EC:EllipticCurve——椭圆曲线,生成密钥的方法DH:Diffie-HellmanKeyExchange——交换密钥的方法设计数据传输的两方服务端(Server)和客......
  • Zotero翻译服务DeepL(Pro)密钥免费获取
            DeepL以其卓越的翻译质量著称,能够生成非常自然、流畅的译文,几乎可以与人工翻译相媲美。下面介绍如何在zotero中免费使用DeepL(Pro)。点开下面链接邀请码:tsYF-dFFL4邀请链接:https://deepl-pro.com/#/translate?referral_code=tsYF-dFFL4        ......
  • 2025年最新分享Win11专业工作站版永久密钥
    Windows11专业工作站版是Windows11家族中的顶级版本,专为满足需要强大性能和高级功能的高端用户和企业而设计。它在Windows11专业版的基础上进行了增强,提供了更强大的硬件支持、更高的性能和更高级的功能,以应对最苛刻的工作负载。主要特性和优势:更强大的硬件支持:多......
  • 2025最新分享Win11专业版永久密钥
    Windows11专业版是微软面向企业用户和专业人士推出的操作系统,在家庭版的基础上增加了许多高级功能,旨在提升工作效率、增强安全性,并提供更灵活的管理选项。主要特点:强大生产力工具:虚拟桌面、Snap布局、改进的任务栏等功能,帮助用户更高效地管理多个任务和窗口。增强安全性:B......