Skip to content

doc-war/ckd-rust

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CKD — Channel Key Derivation (Rust)

轻量级、无状态、可逆的资源标识派生协议 。

概述

CKD(Channel Key Derivation)是一种轻量级、无状态、可逆的资源标识派生协议。

它允许从一个内部资源标识派生出多个不同用途的外部标识,并支持在不依赖映射表的情况下恢复原始资源标识。

目标

CKD 的核心目标:

  • 一个内部资源 ID
  • 派生多个用途隔离的外部 Key
  • 无数据库映射
  • 可逆恢复
  • 不同用途之间不可互相推导

在数学上的具体表现为:

  • C → A
  • C → B
  • A → C
  • B → C
  • A 无法推导 B
  • B 无法推导 A
  • 不需要存储 A→C 映射
  • 不需要存储 B→C 映射
  • 仅依赖平台密钥即可完成派生和反向解析
  • 且无法使用已知的AB来反向破解密钥

价值

采用CKD的O(1)复杂度,相比库索引,在数值上的影响是直观的:

指标 查库 CKD
单次路由延迟 1~10ms 0.01~0.1ms
单机QPS 1万~5万 10万~50万
横向扩容 受DB限制 近线性
Redis依赖 需要 不需要
MySQL依赖 需要 不需要

对于极纯粹的高并发技术设施,将系统从“状态驱动路由”变成“计算驱动路由”,减少两次查库,并发能力提升通常不是 2 倍、3 倍,而是一个数量级(10x)起步。

安装

Cargo.toml 中添加:

[dependencies]
ckd = { git = "https://github.com/doc-war/ckd-rust" }

快速开始

use ckd::{self, Ckd};

fn main() -> Result<(), ckd::Error> {
    // 主密钥:32 字节高熵随机字节串(CSPRNG 生成)
    let secret: Vec<u8> = (0..32).collect();

    let ckd = ckd::new(ckd::Config {
        current_version: 1,
        secrets_by_version: [(1, secret)].into(),
    })?;

    // 派生:内部 ID → 外部 Key
    let channel_id = b"channel_12345";
    let webhook_key = ckd.derive(channel_id, "webhook")?;
    let sse_key = ckd.derive(channel_id, "sse")?;

    println!("webhook: {}", webhook_key);

    // 恢复:外部 Key → 内部 ID
    let recovered = ckd.parse(&webhook_key, "webhook")?;
    assert_eq!(&recovered, channel_id);

    Ok(())
}

核心概念

概念 说明
资源 ID (C) 内部资源标识,如 channel_id, user_id
用途 (P) 用途标识,如 webhook, sse, api,仅允许 [a-z0-9_-],长度 1~64
派生密钥 (K) 外部标识,base64url 编码,含版本号和认证标签
主密钥 (S) 平台主密钥,推荐 256-bit CSPRNG 字节串

API 参考

Config

pub struct Config {
    pub current_version: u8,              // [1, 15]
    pub secrets_by_version: HashMap<u8, Vec<u8>>,
}

Ckd trait

pub trait Ckd {
    fn derive(&self, resource_id: &[u8], purpose: &str) -> Result<String, Error>;
    fn parse(&self, derived_key: &str, purpose: &str) -> Result<Vec<u8>, Error>;
}

Error 类型

pub enum Error {
    InvalidPurpose,     // 用途标识格式不合法
    InvalidDerivedKey,  // 派生密钥解析失败
}

parse 对认证失败、格式错误、版本不存在等情况返回统一的 InvalidDerivedKey

密钥轮换

let ckd = ckd::new(ckd::Config {
    current_version: 2,
    secrets_by_version: [
        (1, old_secret),  // 旧密钥,用于解析旧 Key
        (2, new_secret),  // 新密钥,用于新派生
    ].into(),
})?;

// 新派生使用 v2
let new_key = ckd.derive(channel_id, "webhook")?;

// 旧 Key 仍可被解析(v1 密钥保留在表中)
let old_id = ckd.parse(&old_key, "webhook")?;

用途隔离

不同 purpose 派生出的 Key 不可互相推导。

算法

组件 算法 标准
密钥派生 HKDF (SHA-256) RFC 5869
确定性 AEAD AES-256-SIV RFC 5297
编码 base64url (无 padding) RFC 4648 §5

跨语言测试向量

3 组固定向量在 src/internal/core.rs test_known_vectors 中验证跨语言一致性(Go / Rust)。

# Secret Purpose Ver ResourceID K
1 0001...1e1f (32B) webhook 1 channel_12345 AXnjdNQal5XDP66STw0pQbOzRi3AdGmiX1Xi5ZxO
2 0001...1e1f (32B) sse 1 user_67890 Aez5p0zdhSjxmsgy92MfMhiMlhAbRxlldWcl
3 ffee...1100 (32B) api_token 2 channel_12345 ApUFLCCTYol1B57b459DrXW8SiQaJLaJRUx246YY

测试

cargo test

许可

MIT

About

CKD(Channel Key Derivation)是一种轻量级、无状态、可逆的资源标识派生协议。 它允许从一个内部资源标识派生出多个不同用途的外部标识,并支持在不依赖映射表的情况下恢复原始资源标识。

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages