代码仓
中
更新时间: 2026/10/31
在AtomGit上查看源码

key_mgmt ​

版本信息 ​

项目内容
组件版本1.140.1
首发版本openUBMC 26.12
文档作者openUBMC 社区
最后更新2026-10-31

1. 组件概述 ​

1.1 组件简介 ​

key_mgmt 为 Master 角色,负责所有域 MK(Master Key)的注册、生成、状态修改、删除等,即生成、更新 KSF 文件。其他使用 KMC 服务的 APP 为 Agent 角色,只对 KSF 文件做读操作,获取 DomainId 和 KeyId 用于加解密。

1.2 解决什么问题 ​

  • 为不同业务组件提供密钥域隔离机制,确保个别密钥泄密不会影响全部业务数据安全
  • 支持 Master-Agent 架构,实现主从部署场景下的密钥统一管理和安全分发
  • 提供 KSF 文件生命周期管理,支持密钥自动更新和密文重加密

1.3 核心功能 ​

  • 密钥域管理:为不同组件分配独立的密钥域(Domain),实现密钥集合隔离
  • 主密钥生命周期管理:支持 Master Key 的注册、生成、状态修改、删除和自动更新
  • KSF 文件管理:管理 KSF(Key Storage File)文件生成、备份和恢复
  • 密钥角色管理:区分 Master 和 Agent 角色,Master 拥有全部管理权限,Agent 仅拥有本地域读权限

1.3.1 密钥分层架构 ​

KMC 组件支持多层次密钥架构,上层密钥只用来保护下层密钥,最下层密钥(WK: Work Key)用来保护业务模块应用的机密数据:

  • RK(Root Key):根密钥,纯软件环境下由硬编码和文件两部分存储,基于硬件保护根密钥时根密钥直接存储于硬件中
  • RMK(Root Master Key):纯软件方式保护根密钥时,由 RK 派生得到,用于加密 Master Key,RK/RMK 封装在根密钥管理模块内部,永不出现在模块之外
  • MK(Master Key):主密钥

Master Key按来源分为自动生成和外部导入(注册)两大类: 1)系统随机生成:这类Master Key由KMC内部随机生成,其所属域对应于内部生成域,原则上被封装在Master Key管理模块内部,按需提供密钥访问接口; 2)由业务模块导入:本CBB支持对业务模块导入的Master Key进行管理,其所属域为外部注册域,由业务模块导入的Master Key可以被业务模块直接访问。通常情况下不建议直接访问Master Key,系统可以计算并返回派生密钥(WorkKey),业务模块可输入盐值、迭代次数作为密钥派生运算的参数;

Master Key按使用范围分为本地和共享两大类: 1)本地MK:此类Master Key只能在Master或Agent自身使用,其所属域为本地域,此类主密钥不可以在主从间共享,KMC 3.0起支持本地域 2)共享MK:此类Master Key可以在Master和Agent间共享,其所属域为共享域,KMC 3.0之前版本仅支持共享域(注:KMC V1不支持主从部署,不涉及共享MK,因此无所谓共享或本地划分)

1.3.2 角色权限 ​

组件分 Master 和 Agent 两个角色:

  • Master:Master 自身 RootKey 的生成/修改,所有域 MK 的注册/生成/状态修改/删除,Master 自身 KSF 完整性检查和修复
  • Agent:Agent 自身 RootKey 的生成/修改,本地域 MK 的注册/生成/状态修改/删除,Agent 自身 KSF 完整性检查和修复

1.3.3 实现流程 ​

1.4 关键术语表 ​

术语解释
KSFKey Storage File,密钥存储文件,用于持久化保存密钥信息
Domain密钥作用域,Domain 隔离,为不同 App 分配不同的 Domain,可在 App 间有效隔离密钥集合
KeyId密钥 ID,在同一 Domain 内唯一,与 DomainId 共同构成 MK 的唯一身份标识
RKRoot Key,根密钥,纯软件环境下由硬编码和文件两部分存储,基于硬件保护时直接存储于硬件中
RMKRoot Master Key,由 RK 派生得到,用于加密 Master Key
MKMaster Key,主密钥,按来源分为自动生成和外部导入(注册)两大类
WKWork Key,工作密钥,由 MK 派生而来,用于保护业务模块应用的机密数据
KMCKey Management Center,密钥管理中心,提供密钥加解密和派生运算能力

1.5 外部交互边界图 ​

text
业务组件(Agent)
         |
         | key_client_lib.lua
         v
key_mgmt 服务
         |
         v
key_mgmt_app.lua
         |
         +-------------------------+
         |                         |
         v                         v
key_service.lua             master_key.lua
         |                         |
         +------------+------------+
                      |
                      v
               KMC 与持久化组件

2. API 使用说明与示例 ​

对外发布的 API 为资源协作接口,服务名 bmc.kepler.key_mgmt

2.1 RegisterKey ​

功能说明 ​

注册新的密钥域,Agent 组件通过此方法向 key_mgmt 注册,获得唯一的 DomainId。

属性内容
接口名bmc.kepler.KeyService.Keys
废弃状态正常可用

参数说明 ​

参数名方向类型描述取值范围
AppName输入String组件名称非空字符串
KsfName输入String主 KSF 文件名非空字符串
KsfBakName输入String备份 KSF 文件名非空字符串
KsfPath输入String主 KSF 存储路径合法目录路径
KsfBakPath输入String备份 KSF 存储路径合法目录路径
OwnerId输入U32文件所有者 ID有效 UID
GroupId输入U32文件所属组 ID有效 GID

返回值与异常 ​

返回值含义触发条件处理建议
DomainId (>0)成功正常执行完成无
0失败参数非法或内部错误检查输入参数是否合法

应用场景 ​

业务组件(Agent)在初始化时调用此接口注册密钥域,获取 DomainId 并加载 KSF 文件。

限制条件 ​

此方法仅在 Agent 角色下调用。

2.2 UpdateKey ​

功能说明 ​

触发所有域的主密钥更新,以异步任务方式执行。

属性内容
接口名bmc.kepler.KeyService
废弃状态正常可用

参数说明 ​

无参数。

返回值与异常 ​

返回值含义触发条件处理建议
TaskId (>0)成功正常执行完成使用 TaskId 查询进度
0失败服务未就绪检查 key_mgmt 服务状态

应用场景 ​

管理员触发密钥更新时调用此方法,系统会逐域更新 MK 并通知各 Agent 组件重新加载 KSF。

限制条件 ​

需要 SecurityMgmt 权限。

2.3 CiphertextUpdated ​

功能说明 ​

通知密钥管理服务组件已完成密文更新。

属性内容
接口名bmc.kepler.KeyService
废弃状态正常可用

参数说明 ​

参数名方向类型描述取值范围
DomainId输入U32密钥域 ID已注册的 DomainId
KeyId输入U32密钥 ID已存在的 KeyId

返回值与异常 ​

无返回值。

应用场景 ​

Agent 组件完成密文重加密后调用此方法通知 key_mgmt 更新 CiphertextKeyId。

2.4 GetUpdateState ​

功能说明 ​

查询密钥更新状态。

属性内容
接口名bmc.kepler.KeyService
废弃状态正常可用

参数说明 ​

无参数。

返回值与异常 ​

返回值含义触发条件
0就绪密钥更新已完成
1更新中密钥更新正在进行
2已更新所有域密钥已更新,等待 Agent 确认
3失败密钥更新失败

应用场景 ​

Agent 组件查询当前密钥更新状态,判断是否需要重新加载 KSF。

3. 组件扩展案例 ​

3.1 扩展能力概述 ​

key_mgmt 提供客户端库接入机制,支持业务组件(Agent)以插件方式接入密钥管理服务。

3.2 扩展点说明 ​

  • 密钥注册扩展:业务组件通过 key_client_lib.lua 注册密钥域,可自定义 KSF 文件路径和权限

3.3 二次开发指导 ​

步骤一:引入客户端库 ​

lua
local KeyClient = require("key_mgmt.key_client_lib")

步骤二:构造客户端实例 ​

lua
local key_client = KeyClient.new(
    bus,
    "SUBJECT_NAME",
    function(domain_id, key_id)
        print(string.format("密钥已更新: DomainId=%d, KeyId=%d", domain_id, key_id))
    end,
    "KSF_NAME",
    "KSF_BACK_NAME",
    {}
)

验证方法 ​

  1. 检查 key_mgmt 服务是否正常运行:busctl --user tree bmc.kepler.key_mgmt
  2. 调用 RegisterKey 检查返回值是否为有效 DomainId
  3. 触发 UpdateKey 检查回调是否被正确触发

4. 日志说明 ​

4.1 一键日志收集 ​

文件路径内容说明
/var/log/framework.logkey_mgmt 组件日志记录在框架日志中

4.2 关键日志信息 ​

日志片段日志级别含义解读建议处理动作
init domain %s master key failed during Key Service initializationERROR服务初始化时域 MK 初始化失败检查该域的 KSF 文件路径配置和磁盘空间
kmc initialization failed during Key Service initialization, WsecInitialize failedERRORKMC 核心库初始化失败检查 mc.kmc 库文件是否完整、硬件根密钥是否可用
init kmc master failed during Key Service initializationERRORKMC Master 模式初始化失败检查 KSF 文件权限和路径配置
init kmc domain failed during Key Service initializationERRORKMC 域初始化失败检查数据库中域数据是否完整
init_domain failed for domain_id=%d, err=%sERROR域初始化失败检查 KSF 文件是否存在及文件锁是否被占用
Key Service update domain %d master key failed, err=%sERROR密钥更新时域 MK 更新失败检查对应域的 KSF 写入权限和磁盘空间
Key Service failed to notify master key updateERROR密钥更新后通知 Agent 失败检查 Agent 是否在线,D-Bus 连接是否正常
copy datatocheck_bak failed during master key updateERROR密钥更新时备份 datatocheck 失败检查 /data/backup/ksf/ 目录权限和磁盘空间
Key Service update the domain %s master key failed, domain id not foundERROR密钥更新失败,域 ID 不存在检查该域是否已注册
Key Service import data failed, data is invalidERROR数据导入失败,数据无效检查 KSF 文件格式是否正确
domain %s missing KsfPath...will be removedWARN服务启动时发现域缺少 KSF 路径配置,将被清理如需保留该域,检查数据库中该域的 KSF 路径配置
open flock_file failed during master key export ksfWARN导出 KSF 时文件锁打开失败检查 /data/trust/ksf/ 目录权限和锁文件状态
backup failed, failed to backup %s to destination pathERROR备份 KSF 文件失败检查 /data/backup/ksf/ 目录权限和磁盘空间
recover failed, get preserve config failedERROR恢复时获取保留配置失败检查数据库连接和配置数据
recover failed, domain id is an empty listERROR恢复时域 ID 列表为空检查备份数据完整性

4.3 调试方法 ​

bash
# 开启 key_mgmt 详细日志
busctl --user call bmc.kepler.key_mgmt \
/bmc/kepler/key_mgmt/MicroComponent \
bmc.kepler.MicroComponent.Debug SetDlogLevel a{ss}sy 0 debug 1

# 查看实时日志
tail -f /var/log/framework.log | grep key_mgmt

5. 问题定界指南 ​

5.1 典型问题定界 ​

现象描述是否为本组件问题判断依据关键证据收集方法
Agent 无法注册密钥域是检查 RegisterKey 返回值和日志查看框架日志中 RegisterKey 相关日志
密钥更新失败是检查 UpdateKey 返回的 TaskId 和状态查看框架日志中 UpdateKey 相关日志
KSF 文件读取失败是检查文件权限和路径执行 ls -la /data/trust/ksf/ 检查文件存在性和权限
Agent 未收到密钥更新通知否检查 Agent 是否正确监听属性变更信号检查 Agent 端日志和 key_client_lib 初始化日志
硬件根密钥不可用否检查 HARDWARE_ROOTKEY_ENABLE 配置确认硬件支持并正确配置

5.2 错误码速查表 ​

组件无显式数字错误码

6. 常见问题解答 ​

Q1:kmc解密接口报268错误怎么办? ​

  • 问题描述:查看日志发现kmc解密接口报268错误
  • 一句话答案:268错误码代表MK不存在,即该进程中不存在该domainId
  • 根因说明:domainId和ksf文件不匹配导致,可能是运行过程中,数据库被破坏,导致domainId被key_mgmt重新匹配;或者由于业务场景没有考虑充分,导致旧密钥被误删,从而加解密失败
  • 解决方案:如果是ipmi命令报错,重新设置密码即可;如果是web打不开,日志刷证书解密失败,则重新导入证书;涉及kmc的组件都存在这种情况,可以根据对应业务场景删除相应数据即可,并重新触发加密,即可正常使用;所有涉及kmc的组件都存在这种情况,可以直接彻底地重置kmc数据,删除数据库domainId分配信息,重启key_mgmt,重新导入证书,设置密码等,但是kmc业务面涉及较广,比较难将数据清除干净,不建议使用;多个组件依赖同一个密钥的场景,需要考虑将domain进行拆分,并且兼容降级场景,此时则需要先更新密钥的组件不删除旧domainId
  • 适用版本:所有版本

Q2:定位问题时需要持续更新主密钥,如何绕过密钥更新周期检查? ​

  • 问题描述:定位问题时需要绕过密钥更新周期检查
  • 一句话答案:使用mdbctl setprop set KeyService_0 bmc.kepler.KeyService LastUpdateTime 1684327765 命令设置密钥更新时间早于当前时间,便可通过更新周期检查
  • 适用版本:所有版本

更多常见问题可查看社区文档《key_mgmt密钥管理组件FAQ》