专注于分布式系统架构AI辅助开发工具(Claude
Code中文周刊)

密钥体系与加密通信 - 第2章:多租户密钥体系设计

智谱 GLM,支持多语言、多任务推理。从写作到代码生成,从搜索到知识问答,AI 生产力的中国解法。

第2章:多租户密钥体系设计

🎯 本章目标

学完这一章,你将理解:
– 每个客户是否需要独立的公私钥对
– 三种密钥体系方案的设计
– 如何根据业务场景选择方案

预计学习时间: 40分钟


2.1 业务场景分析

你的业务场景

你是平台方(SaaS提供商)
├── 客户A(某医院)
│   ├── 北京数据中心
│   ├── 上海数据中心
│   └── 100台设备
│
├── 客户B(某工厂)
│   ├── 深圳工厂
│   └── 50台设备
│
└── 客户C(某学校)
    ├── 主校区
    ├── 分校区
    └── 30台设备

核心问题

问题1:每个客户是否需要独立的公私钥对?
– 如果是,如何管理这么多密钥?
– 如果不是,如何区分不同客户?

问题2:统一安装包如何处理密钥?
– 安装包内置什么密钥?
– 客户特定密钥如何注入?

问题3:客户导入设备时如何验证?
– 设备如何证明自己属于这个客户?
– 平台如何验证设备的合法性?


2.2 方案1:每客户一对密钥(简单方案)

设计思路

核心原则: 每个客户有独立的公私钥对

平台(你)
├── 平台根密钥对(Platform Root Key)
│   ├── 平台根公钥(公开)
│   └── 平台根私钥(绝对保密)
│
├── 客户A密钥对
│   ├── 客户A公钥
│   └── 客户A私钥
│
├── 客户B密钥对
│   ├── 客户B公钥
│   └── 客户B私钥
│
└── 客户C密钥对
    ├── 客户C公钥
    └── 客户C私钥

密钥生成流程

class SimpleKeySystem:
    """
    方案1:每客户一对密钥
    """

    def __init__(self):
        # 平台根密钥对(只生成一次)
        self.platform_root_key = RSA.generate(4096)
        self.platform_root_public = self.platform_root_key.publickey()

    def create_customer(self, customer_id, customer_name):
        """
        为新客户生成密钥对
        """
        # 1. 生成客户专属密钥对
        customer_key = RSA.generate(2048)
        customer_public = customer_key.publickey()

        # 2. 创建客户证书(用平台根私钥签名)
        customer_cert = {
            "customer_id": customer_id,
            "customer_name": customer_name,
            "public_key": customer_public.export_key().decode(),
            "issued_at": datetime.now().isoformat(),
            "valid_until": (datetime.now() + timedelta(days=365)).isoformat()
        }

        # 3. 用平台根私钥签名证书
        cert_data = json.dumps(customer_cert, sort_keys=True)
        hash_obj = SHA256.new(cert_data.encode())
        signature = pkcs1_15.new(self.platform_root_key).sign(hash_obj)

        customer_cert["signature"] = base64.b64encode(signature).decode()

        # 4. 返回客户密钥包
        return {
            "customer_id": customer_id,
            "private_key": customer_key.export_key().decode(),
            "public_key": customer_public.export_key().decode(),
            "certificate": customer_cert
        }

信任链

[平台根证书](自签名)
      ↓ 签发
[客户A证书](包含客户A公钥)
      ↓ 签发
[设备1证书](包含设备1公钥)

验证流程:
1. 验证设备1证书 → 用客户A公钥验证
2. 验证客户A证书 → 用平台根公钥验证
3. 验证平台根证书 → 自签名(信任锚点)

设备导入流程

def import_device(self, customer_id, device_info):
    """
    客户导入新设备
    """
    # 1. 验证客户身份
    customer = self.get_customer(customer_id)
    if not customer:
        raise Exception("客户不存在")

    # 2. 为设备生成密钥对
    device_key = RSA.generate(2048)
    device_public = device_key.publickey()

    # 3. 创建设备证书(用客户私钥签名)
    device_cert = {
        "device_id": device_info["id"],
        "customer_id": customer_id,
        "serial_number": device_info["serial"],
        "public_key": device_public.export_key().decode(),
        "issued_at": datetime.now().isoformat()
    }

    # 4. 用客户私钥签名
    cert_data = json.dumps(device_cert, sort_keys=True)
    hash_obj = SHA256.new(cert_data.encode())
    customer_private_key = RSA.import_key(customer["private_key"])
    signature = pkcs1_15.new(customer_private_key).sign(hash_obj)

    device_cert["signature"] = base64.b64encode(signature).decode()

    return {
        "device_id": device_info["id"],
        "private_key": device_key.export_key().decode(),
        "certificate": device_cert
    }

优缺点分析

优点:
– ✅ 简单直观,容易理解
– ✅ 客户隔离性好(每个客户独立密钥)
– ✅ 客户可以自己管理设备密钥

缺点:
– ❌ 密钥管理复杂(100个客户 = 100对密钥)
– ❌ 客户私钥需要安全分发(如何给客户?)
– ❌ 客户私钥泄露风险高(客户可能保管不善)
– ❌ 不支持多地域(一个客户只有一对密钥)

适用场景

✅ 适合:
- 客户数量少(<50个)
- 客户有专业IT团队
- 客户需要完全自主控制

❌ 不适合:
- 客户数量多(>100个)
- 客户IT能力弱
- 需要多地域部署

2.3 方案2:分层密钥体系(推荐方案)

设计思路

核心原则: 密钥分层管理,客户不持有私钥

平台密钥层级:
┌─────────────────────────────────┐
│   平台根密钥(Platform Root)    │
│   - 最高权限                     │
│   - 离线保存在HSM               │
└─────────────────────────────────┘
              ↓ 签发
┌─────────────────────────────────┐
│   客户主密钥(Customer Master)  │
│   - 每个客户一个                 │
│   - 平台保管,客户不持有         │
└─────────────────────────────────┘
              ↓ 派生
┌─────────────────────────────────┐
│   地域密钥(Region Key)         │
│   - 每个数据中心一个             │
│   - 用于签发设备证书             │
└─────────────────────────────────┘
              ↓ 签发
┌─────────────────────────────────┐
│   设备密钥(Device Key)         │
│   - 每个设备一个                 │
│   - 设备持有私钥                 │
└─────────────────────────────────┘

完整代码实现

class HierarchicalKeySystem:
    """
    方案2:分层密钥体系
    """

    def __init__(self):
        # 平台根密钥(4096位,最高安全级别)
        self.platform_root_key = RSA.generate(4096)
        self.platform_root_public = self.platform_root_key.publickey()

        # 客户主密钥存储
        self.customer_master_keys = {}

        # 地域密钥存储
        self.region_keys = {}

    def create_customer(self, customer_id, customer_name):
        """
        为客户创建主密钥
        """
        # 1. 生成客户主密钥(平台保管)
        customer_master_key = RSA.generate(2048)

        # 2. 创建客户证书
        customer_cert = {
            "customer_id": customer_id,
            "customer_name": customer_name,
            "public_key": customer_master_key.publickey().export_key().decode(),
            "issued_at": datetime.now().isoformat(),
            "valid_until": (datetime.now() + timedelta(days=365)).isoformat(),
            "key_usage": ["sign_device_cert", "derive_region_key"]
        }

        # 3. 用平台根私钥签名
        cert_data = json.dumps(customer_cert, sort_keys=True)
        hash_obj = SHA256.new(cert_data.encode())
        signature = pkcs1_15.new(self.platform_root_key).sign(hash_obj)
        customer_cert["signature"] = base64.b64encode(signature).decode()

        # 4. 保存客户主密钥(平台保管,客户不持有)
        self.customer_master_keys[customer_id] = {
            "private_key": customer_master_key,
            "public_key": customer_master_key.publickey(),
            "certificate": customer_cert
        }

        return customer_cert

    def create_region_key(self, customer_id, region_name):
        """
        为客户的某个地域创建密钥
        """
        # 1. 获取客户主密钥
        customer_master = self.customer_master_keys.get(customer_id)
        if not customer_master:
            raise Exception("客户不存在")

        # 2. 派生地域密钥(从客户主密钥派生)
        region_key = RSA.generate(2048)

        # 3. 创建地域证书
        region_cert = {
            "customer_id": customer_id,
            "region_name": region_name,
            "public_key": region_key.publickey().export_key().decode(),
            "issued_at": datetime.now().isoformat(),
            "valid_until": (datetime.now() + timedelta(days=365)).isoformat(),
            "key_usage": ["sign_device_cert"]
        }

        # 4. 用客户主私钥签名
        cert_data = json.dumps(region_cert, sort_keys=True)
        hash_obj = SHA256.new(cert_data.encode())
        signature = pkcs1_15.new(customer_master["private_key"]).sign(hash_obj)
        region_cert["signature"] = base64.b64encode(signature).decode()

        # 5. 保存地域密钥
        region_id = f"{customer_id}:{region_name}"
        self.region_keys[region_id] = {
            "private_key": region_key,
            "public_key": region_key.publickey(),
            "certificate": region_cert
        }

        return region_cert

    def import_device(self, customer_id, region_name, device_info):
        """
        客户导入设备(在指定地域)
        """
        # 1. 获取地域密钥
        region_id = f"{customer_id}:{region_name}"
        region_key = self.region_keys.get(region_id)

        if not region_key:
            raise Exception("地域不存在,请先创建地域密钥")

        # 2. 为设备生成密钥对
        device_key = RSA.generate(2048)
        device_public = device_key.publickey()

        # 3. 创建设备证书
        device_cert = {
            "device_id": device_info["id"],
            "customer_id": customer_id,
            "region_name": region_name,
            "serial_number": device_info["serial"],
            "public_key": device_public.export_key().decode(),
            "issued_at": datetime.now().isoformat()
        }

        # 4. 用地域私钥签名
        cert_data = json.dumps(device_cert, sort_keys=True)
        hash_obj = SHA256.new(cert_data.encode())
        signature = pkcs1_15.new(region_key["private_key"]).sign(hash_obj)
        device_cert["signature"] = base64.b64encode(signature).decode()

        return {
            "device_id": device_info["id"],
            "private_key": device_key.export_key().decode(),
            "certificate": device_cert,
            "certificate_chain": [
                device_cert,
                region_key["certificate"],
                self.customer_master_keys[customer_id]["certificate"]
            ]
        }

    def verify_device(self, device_cert, cert_chain):
        """
        验证设备证书链
        """
        # 1. 验证设备证书(用地域公钥)
        region_cert = cert_chain[1]
        region_public_key = RSA.import_key(region_cert["public_key"])

        cert_data = json.dumps({k: v for k, v in device_cert.items() if k != "signature"}, sort_keys=True)
        hash_obj = SHA256.new(cert_data.encode())
        signature = base64.b64decode(device_cert["signature"])

        try:
            pkcs1_15.new(region_public_key).verify(hash_obj, signature)
            print("✅ 设备证书验证成功")
        except:
            print("❌ 设备证书验证失败")
            return False

        # 2. 验证地域证书(用客户主公钥)
        customer_cert = cert_chain[2]
        customer_public_key = RSA.import_key(customer_cert["public_key"])

        cert_data = json.dumps({k: v for k, v in region_cert.items() if k != "signature"}, sort_keys=True)
        hash_obj = SHA256.new(cert_data.encode())
        signature = base64.b64decode(region_cert["signature"])

        try:
            pkcs1_15.new(customer_public_key).verify(hash_obj, signature)
            print("✅ 地域证书验证成功")
        except:
            print("❌ 地域证书验证失败")
            return False

        # 3. 验证客户证书(用平台根公钥)
        cert_data = json.dumps({k: v for k, v in customer_cert.items() if k != "signature"}, sort_keys=True)
        hash_obj = SHA256.new(cert_data.encode())
        signature = base64.b64decode(customer_cert["signature"])

        try:
            pkcs1_15.new(self.platform_root_public).verify(hash_obj, signature)
            print("✅ 客户证书验证成功")
        except:
            print("❌ 客户证书验证失败")
            return False

        print("✅ 完整证书链验证成功")
        return True

信任链示例

场景:客户A在北京数据中心导入设备001

证书链:
[平台根证书]
  ↓ 签发
[客户A主证书]
  ↓ 签发
[北京地域证书]
  ↓ 签发
[设备001证书]

验证流程:
1. 设备001连接平台
2. 设备001提供:设备证书 + 完整证书链
3. 平台验证:
   - 设备证书 ← 用北京地域公钥验证
   - 北京地域证书 ← 用客户A主公钥验证
   - 客户A主证书 ← 用平台根公钥验证
4. 全部通过 → 设备合法 ✅

优缺点分析

优点:
– ✅ 支持多地域(每个地域独立密钥)
– ✅ 客户不持有私钥(降低泄露风险)
– ✅ 密钥管理集中(平台统一管理)
– ✅ 灵活性高(可以按地域撤销)
– ✅ 扩展性好(轻松支持新地域)

缺点:
– ❌ 实现复杂(需要管理多层密钥)
– ❌ 平台责任重(所有密钥都在平台)
– ❌ 需要HSM(硬件安全模块保护根密钥)

适用场景

✅ 适合:
- 客户数量多(>100个)
- 需要多地域部署
- 客户IT能力弱
- 需要集中管理

✅ 推荐场景:
- SaaS平台
- 多租户系统
- 跨国部署

2.4 方案3:混合密钥体系(最灵活)

设计思路

核心原则: 结合方案1和方案2的优点

平台层:
├── 平台根密钥(Platform Root)
│
客户层(两种模式):
├── 模式A:客户自管密钥(客户持有私钥)
│   └── 适合:大客户、有IT团队
│
└── 模式B:平台托管密钥(平台持有私钥)
    └── 适合:小客户、无IT团队

代码实现

class HybridKeySystem:
    """
    方案3:混合密钥体系
    """

    def __init__(self):
        self.platform_root_key = RSA.generate(4096)
        self.customers = {}

    def create_customer(self, customer_id, customer_name, key_mode="托管"):
        """
        创建客户(支持两种模式)

        key_mode: "自管" 或 "托管"
        """
        customer_key = RSA.generate(2048)

        customer_cert = {
            "customer_id": customer_id,
            "customer_name": customer_name,
            "key_mode": key_mode,
            "public_key": customer_key.publickey().export_key().decode(),
            "issued_at": datetime.now().isoformat()
        }

        # 签名证书
        cert_data = json.dumps(customer_cert, sort_keys=True)
        hash_obj = SHA256.new(cert_data.encode())
        signature = pkcs1_15.new(self.platform_root_key).sign(hash_obj)
        customer_cert["signature"] = base64.b64encode(signature).decode()

        if key_mode == "托管":
            # 平台托管模式:平台保存私钥
            self.customers[customer_id] = {
                "mode": "托管",
                "private_key": customer_key,
                "public_key": customer_key.publickey(),
                "certificate": customer_cert
            }

            return {
                "customer_id": customer_id,
                "mode": "托管",
                "certificate": customer_cert,
                "message": "密钥由平台托管,客户无需管理私钥"
            }
        else:
            # 客户自管模式:客户保存私钥
            self.customers[customer_id] = {
                "mode": "自管",
                "public_key": customer_key.publickey(),
                "certificate": customer_cert
            }

            return {
                "customer_id": customer_id,
                "mode": "自管",
                "private_key": customer_key.export_key().decode(),
                "certificate": customer_cert,
                "message": "请妥善保管私钥,平台不保存"
            }

优缺点分析

优点:
– ✅ 最灵活(支持两种模式)
– ✅ 满足不同客户需求
– ✅ 可以平滑迁移(从托管到自管)

缺点:
– ❌ 最复杂(需要维护两套逻辑)
– ❌ 测试成本高
– ❌ 文档复杂

适用场景

✅ 适合:
- 客户类型多样(大客户+小客户)
- 需要灵活性
- 有足够的开发资源

2.5 三种方案对比

对比表

维度 方案1:每客户一对密钥 方案2:分层密钥体系 方案3:混合体系
复杂度 ⭐ 简单 ⭐⭐⭐ 复杂 ⭐⭐⭐⭐ 很复杂
多地域支持 ❌ 不支持 ✅ 完美支持 ✅ 支持
客户隔离 ✅ 很好 ✅ 很好 ✅ 很好
密钥管理 客户自管 平台托管 两种模式
安全风险 客户私钥泄露 平台责任重 混合风险
扩展性 ⭐⭐ 一般 ⭐⭐⭐⭐⭐ 很好 ⭐⭐⭐⭐ 好
适合客户数 <50 >100 任意
开发成本
维护成本

推荐选择

如果你的业务是:
├── 客户少(<50)且都有IT团队 → 方案1
├── 客户多(>100)或需要多地域 → 方案2 ⭐推荐
└── 客户类型多样,需要灵活性 → 方案3

2.6 本章小结

核心要点

  1. 方案1:每客户一对密钥,简单但不灵活
  2. 方案2:分层密钥体系,推荐用于多租户SaaS
  3. 方案3:混合体系,最灵活但最复杂

关键决策

每个客户是否需要独立密钥?
– ✅ 是的,每个客户都需要独立密钥
– 但密钥可以由平台托管(方案2)或客户自管(方案1)

推荐方案:方案2(分层密钥体系)
– 支持多地域
– 平台集中管理
– 客户无需管理私钥
– 扩展性好


🤔 思考题

  1. 场景题:如果客户A有3个数据中心(北京、上海、广州),使用方案2,需要生成几个密钥对?

  2. 安全题:方案1中,如果客户的私钥泄露了,会影响其他客户吗?

  3. 设计题:如果要支持客户从”平台托管”模式切换到”客户自管”模式,应该如何设计?


📚 下一章预告

第3章我们将学习多地域证书管理
– 一个客户多个证书的详细设计
– 证书的层级关系
– 跨地域信任链的建立

继续加油!


本章关键词
– 多租户
– 密钥体系
– 分层密钥
– 证书链
– 信任链
– 客户隔离
– 地域密钥

赞(0)
未经允许不得转载:Toy Tech Blog » 密钥体系与加密通信 - 第2章:多租户密钥体系设计
免费、开放、可编程的智能路由方案,让你的服务随时随地在线。

评论 抢沙发

十年稳如初 — LocVPS,用时间证明实力

10+ 年老牌云主机服务商,全球机房覆盖,性能稳定、价格厚道。

老品牌,更懂稳定的价值你的第一台云服务器,从 LocVPS 开始