SubmittedCWE-321 — Use of Hard-coded Cryptographic Key
HUKS 设备认证签名路径硬编码 RSA-2048 私钥
View Upstream Issuegitcode.com/openharmony/security_huks/issues/1529CWE:CWE-321 — Use of Hard-coded Cryptographic Key
Repository:security_huks
Date:2026-04-29
Reporter:Zirui
漏洞编号:
CWE-321 (Use of Hard-coded Cryptographic Key)
漏洞归属组件
漏洞归属版本
CVSS V3.0分值
漏洞简述
涉及文件:
services/huks_standard/huks_engine/main/device_cert_manager/include/dcm_certs_and_key.h(密钥定义)services/huks_standard/huks_engine/main/device_cert_manager/src/dcm_attest.c(签名路径)services/huks_standard/huks_engine/main/core/src/hks_core_service_key_attest.c(公共入口)
完整调用链
Step 1 — 公共入口:HksCoreAttestKey
// hks_core_service_key_attest.c:73 — 公共 API 入口
int32_t HksCoreAttestKey(const struct HksBlob *key, const struct HksParamSet *paramSet, ...) {
// line 102: 读取 HKS_TAG_ATTESTATION_MODE 参数
// line 110: 若为 ANONYMOUS → CreateAttestCertChain(true, ...)
// line 112: 否则 → CreateAttestCertChain(false, ...) ← 默认路径,使用 RSA 密钥
}
默认路径(非匿名认证)传入 isAnonAttest = false。
Step 2 — 构建认证规范,加载硬编码密钥
// dcm_attest.c:1419-1437 — GetCertAndKey()
static int32_t GetCertAndKey(struct HksAttestSpec *attestSpec) {
int32_t ret;
if (!attestSpec->isAnonAttest) {
ret = GetCertOrKey(HKS_DEVICE_CERT, &attestSpec->devCert); // line 1423: 加载设备证书
HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get devCert fail")
ret = GetCertOrKey(HKS_DEVICE_KEY, &attestSpec->devKey); // line 1426: 加载硬编码 RSA 私钥
HKS_IF_NOT_SUCC_LOGE_RETURN(ret, ret, "get devKey fail")
}
// ...
}
Step 3 — 从静态数组直接复制(无任何运行时覆盖机制)
// dcm_attest.c:1396-1400 — GetCertOrKey()
static int32_t GetCertOrKey(enum HksCertType type, struct HksBlob *out) {
switch (type) {
case HKS_DEVICE_KEY:
return ReadCertOrKey(g_deviceKey, sizeof(g_deviceKey), out); // line 1400: 直接从硬编码数组读取
// ...
}
}
// dcm_attest.c:1381-1394 — ReadCertOrKey()
static int32_t ReadCertOrKey(const uint8_t *inData, uint32_t size, struct HksBlob *out) {
uint8_t *data = HksMalloc(size);
if (memcpy_s(data, size, inData, size) != EOK) { // line 1386: 纯 memcpy,无文件读取、无配置检查
// ...
}
out->size = size;
out->data = data;
return HKS_SUCCESS;
}
Step 4 — 使用硬编码私钥签名认证证书
// dcm_attest.c:1020-1022 — CreateAttestCert() 中
struct HksBlob signature = { sizeof(sigBuf), sigBuf };
ret = SignTbs(&signature, &tbs, &attestSpec->devKey, signAlg); // line 1022: 用 devKey 签名
// → HksCryptoHalSign(&priKey, &usageSpec, &message, sig); // line 1003: 底层签名调用
硬编码密钥内容
// dcm_certs_and_key.h:190-254 — 1190 字节 DER 编码 RSA-2048 PKCS#1 私钥
static const uint8_t g_deviceKey[] = {
0x30, 0x82, 0x04, 0xA4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xBC, 0x1C, 0x78, 0x55,
// ... 共 1190 字节,含完整 RSA CRT 参数 (n, e, d, p, q, dp, dq, qInv)
};
// 对应证书 dcm_certs_and_key.h:154-167
// CN = "helloworld111", O = "helloworld" — 明确为测试占位身份
static const uint8_t g_deviceCert[] = { /* ... DER 编码 X.509 证书 ... */ };
为什么无法被覆盖
- 无文件回退:
ReadCertOrKey()仅执行malloc + memcpy_s,无任何文件 I/O - 无编译开关:唯一编译守卫
#ifdef HKS_SUPPORT_API_ATTEST_KEY在hks_config.h:28和hks_config_base.h:172中无条件定义 - 无头文件覆盖机制:
#ifndef HKS_CERTS_AND_KEY不提供外部替换途径 - 从未被修补:该文件仅 2 次 commit —— 初始创建和 2025-01 添加匿名认证密钥。硬编码 RSA 密钥自创建以来从未轮换
触发条件
- 任何调用
huks接口进行设备认证的流程(非匿名模式,即默认路径) GetCertAndKey()被无条件调用,g_deviceKey直接复制到attestSpec->devKey- 该密钥用于签名 TBS 证书,生成设备认证签名
影响性分析说明
影响
- 认证签名可伪造:私钥公开于 Apache 2.0 开源代码中,任何人可提取并伪造设备认证签名
- 影响范围广:所有使用此代码且未做设备级密钥置备(provisioning)的设备均受影响
- 信任链失效:依赖设备认证的远程验证方(如企业 MDM、支付系统)将接受伪造签名
原理分析
受影响版本
规避方案或消减措施
建议修复
- 移除源码中的硬编码私钥
g_deviceKey - 在
GetCertAndKey()中添加运行时检查:若无可用的置备密钥,拒绝认证而非回退到硬编码密钥 - 在设备制造阶段实现设备特定密钥置备机制
- 轮换已被公开的密钥对