密码学系列 - 密钥派生

发布于:2025-07-27 ⋅ 阅读:(21) ⋅ 点赞:(0)

介绍

密钥派生是从一个或多个源密钥(通常是长随机数字或密码短语)派生出一个或多个目标密钥的过程。密钥派生通常是从高熵(高度随机)的源中生成用于特定目的的密钥,例如加密、数字签名、身份验证等。

以下是SSH派生的一般步骤和常见方法:

  1. 源基础设施选择
    • 密钥派生的第一步是选择一个合适的源密钥。源密钥通常是一个高熵的随机数,或者是用户提供的密码短语短。高熵的随机数可以通过安全的随机数生成器生成,而密码键盘用户选择一个相对的字符串。
  2. 派生函数选择
    • 钥匙派生过程中使用的派生函数决定了派生钥匙的生成方式。常见的钥匙派生函数包括:
      • 哈希函数:将源密钥作为输入,使用哈希函数(如SHA-256)生成固定长度的输出,作为目标密钥。
      • 随机α函数(PRF):PRF是一种特殊的哈希函数,用于生成α随机数序列。PRF通常将源密钥和一些附加信息作为输入,生成可用于密钥派生的α随机数序列。
      • PBKDF(Password-Based Key Derivation Function):PBKDF是一类专门用于从密码学主板派生密钥的函数,如PBKDF2、bcrypt、scrypt等。它们通常包含密码学上安全的迭代、盐和密钥拉伸(Key Stretching)等机制,以增强密码学的安全性。
  3. 生成
    • 一旦选择了派生函数,就可以使用该函数将源密钥派生出目标密钥。根据派生函数的设计,可能需要提供一些额外的参数,如盐值、迭代次数等。生成的目标密钥通常用于加密、数字签名或其他安全目的。

密钥派生是加密体系中的重要阶段,用于从高熵的源中生成安全且适合特定用途的密钥。密钥派生函数的选择和参数用于设置生成安全密钥关键,应根据具体的安全需求和最佳实践来进行选择和配置。


用一个邮箱地址派生出固定的密钥

通过邮箱地址来派生一个固定的密钥,核心思想就是利用 密钥派生函数 (KDF, Key Derivation Function),以邮箱作为输入,结合一些安全参数(比如盐、迭代次数等),然后生成一个稳定、可重复的密钥。

不过这里需要注意的是,邮箱地址本身的熵不高(因为邮箱可能是公开信息),所以在实际应用中,最好还结合用户的密码或者其他秘密信息来增强安全性。如果只是为了生成一个“固定但非高安全性”的密钥,比如身份标识类的场景,可以不用太复杂。

下面我给你梳理下思路,然后给个代码例子。


基本步骤

  1. 输入值
    你打算用邮箱地址做输入(比如 user@example.com)。
  2. 选择派生函数
    常用的 KDF:
    • PBKDF2(广泛使用,支持自定义迭代次数和盐值)
    • HKDF(基于 HMAC 的扩展算法)
    • bcrypt / scrypt(密码学安全性更强,但计算更慢)
  3. 盐值(Salt)
    • 可选项。
    • 如果你要保证相同邮箱永远派生同一个密钥,可以选择不加盐(不推荐用于高安全性应用)。
    • 如果用盐,可以固定一个全局盐,或者邮箱自己派生出盐。
  4. 输出密钥长度
    • 通常是 128-bit(16 字节)、256-bit(32 字节)等,具体看用途。

Python 代码示例(用 PBKDF2 + 邮箱派生)

import hashlib
import binascii

def derive_key_from_email(email: str, salt: bytes = b'', iterations: int = 100000, key_len: int = 32):
    """
    用邮箱地址派生一个固定长度的密钥
    - email: 邮箱地址
    - salt: 盐值,固定的话就可以确保相同邮箱返回相同密钥
    - iterations: 迭代次数,越高越安全(但耗时)
    - key_len: 返回的密钥长度(字节)
    """
    email_bytes = email.encode('utf-8')
    
    # 派生密钥
    key = hashlib.pbkdf2_hmac(
        'sha256',        # 哈希算法
        email_bytes,     # 密码 or 主密钥,这里用邮箱地址
        salt,            # 盐值(salt)
        iterations,      # 迭代次数
        dklen=key_len    # 输出长度
    )
    
    # 输出十六进制格式
    return binascii.hexlify(key).decode()

# 测试
email = "user@example.com"
salt = b"your-fixed-salt"  # 可以固定盐值,也可以不传
derived_key = derive_key_from_email(email, salt)

print(f"邮箱 {email} 派生出的密钥: {derived_key}")

注意事项

  1. 安全性
    如果只是邮箱 + 固定盐,密钥是确定性的,暴露邮箱可能会让人推导密钥。
    如果用于身份标识,问题不大。如果用于加密数据,最好引入用户密码或者私钥。
  2. 盐值选择
    • 不加盐或者用固定盐,确保同一个邮箱始终派生出同一个密钥。
    • 每个用户一个不同盐值 + 邮箱 + 密码的组合才真正安全。

延伸

如果是想做账户生成、公钥系统,可以结合 Ed25519ECDSA 密钥生成流程:

  • 邮箱派生种子(比如 PBKDF2 得到 32 字节种子)
  • 再生成椭圆曲线私钥、公钥
  • 用于数字签名、加密等

往期精彩回顾:
区块链知识系列
密码学系列
零知识证明系列
共识系列
公链调研系列
BTC系列
以太坊系列
EOS系列
Filecoin系列
联盟链系列
Fabric系列
智能合约系列
Token系列

网站公告

今日签到

点亮在社区的每一天
去签到