HSM技术精讲(3.8):证书对象——数字世界的“身份证明“

3.8 证书对象:数字世界的"身份证明"

📚 本文内容摘自本人的开源书《HSM技术书 - 从思想实验到安全基石》

🔗 在线阅读/下载:hsm-book

bash 复制代码
git clone https://github.com/Lularible/hsm-book.git

⭐ 如果对您有帮助,欢迎 Star 支持,也欢迎通过 GitHub Issues 交流讨论。

证书对象概述

PKCS#11规范第4.6节定义了证书对象(CKO_CERTIFICATE),用于存储公钥证书和属性证书。

复制代码
证书对象分类:

CKO_CERTIFICATE(证书对象类)
├── CKC_X_509          X.509公钥证书(最常用)
├── CKC_WTLS           WTLS公钥证书(移动设备)
└── CKC_X_509_ATTR_CERT  X.509属性证书

Cryptoki的态度:规范明确指出------"Cryptoki不赋予证书任何特殊意义"。证书对象只是一个存储容器,PKCS#11不负责验证证书有效性、不检查证书链、不解析证书内容。这些工作由应用程序完成。

这体现了PKCS#11"只提供机制,不提供策略"的设计哲学。


证书对象的通用属性

所有证书对象共享以下属性:

属性 数据类型 含义
CKA_CERTIFICATE_TYPE CK_CERTIFICATE_TYPE 证书类型(CKC_X_509等)
CKA_TRUSTED CK_BBOOL 证书是否可信(仅SO可设置)
CKA_CERTIFICATE_CATEGORY CK_CERTIFICATE_CATEGORY 证书类别(用户证书/CA证书/其他)
CKA_CHECK_VALUE Byte array 校验值(SHA-1的前3字节)
CKA_START_DATE CK_DATE 证书起始日期(仅参考)
CKA_END_DATE CK_DATE 证书终止日期(仅参考)
CKA_PUBLIC_KEY_INFO Byte array SubjectPublicKeyInfo的DER编码

关键约束

  1. CKA_CERTIFICATE_TYPE创建后不可修改
  2. CKA_TRUSTED只能由SO或Token初始化程序设置为CK_TRUE,可信证书不可修改
  3. CKA_CERTIFICATE_CATEGORY创建后不可修改
  4. CKA_CHECK_VALUE = SHA-1(CKA_VALUE)的前3字节

CKA_CERTIFICATE_CATEGORY:证书的三种角色

这个属性标识证书的"身份角色":

复制代码
证书类别:

CK_CERTIFICATE_CATEGORY_UNSPECIFIED  未指定(默认)
CK_CERTIFICATE_CATEGORY_TOKEN_USER   用户证书(对应私钥在Token上)
CK_CERTIFICATE_CATEGORY_AUTHORITY     CA证书(签发者证书)
CK_CERTIFICATE_CATEGORY_OTHER_ENTITY  其他实体证书

用途:帮助应用程序区分证书用途。

  • "Token User"表示该证书对应的私钥存在于此Token(可用于签名/解密)
  • "Authority"表示这是一个CA证书(可用于验证其他证书)
  • "Other Entity"表示第三方证书(没有对应私钥)

X.509公钥证书对象

最常用的证书类型(CKC_X_509),存储标准的X.509公钥证书。

专属属性

属性 数据类型 含义
CKA_SUBJECT Byte array 证书主体的DER编码(必须)
CKA_ID Byte array 密钥标识符(关联公私钥)
CKA_ISSUER Byte array 签发者的DER编码
CKA_SERIAL_NUMBER Byte array 序列号
CKA_VALUE Byte array 证书BER编码(必须)
CKA_URL RFC2279 string 证书URL(VALUE为空时使用)
CKA_HASH_OF_SUBJECT_PUBLIC_KEY Byte array 主体公钥的哈希
CKA_HASH_OF_ISSUER_PUBLIC_KEY Byte array 签发者公钥的哈希

创建示例

c 复制代码
CK_OBJECT_CLASS class = CKO_CERTIFICATE;
CK_CERTIFICATE_TYPE certType = CKC_X_509;
CK_UTF8CHAR label[] = "Server Certificate";
CK_BYTE subject[] = {...};  // DER编码的主体名
CK_BYTE id[] = {0x01};      // 与公钥/私钥共享的ID
CK_BYTE certificate[] = {...};  // BER编码的完整证书
CK_BBOOL true = CK_TRUE;

CK_ATTRIBUTE template[] = {
    {CKA_CLASS, &class, sizeof(class)},
    {CKA_CERTIFICATE_TYPE, &certType, sizeof(certType)},
    {CKA_TOKEN, &true, sizeof(true)},
    {CKA_LABEL, label, sizeof(label)-1},
    {CKA_SUBJECT, subject, sizeof(subject)},
    {CKA_ID, id, sizeof(id)},
    {CKA_VALUE, certificate, sizeof(certificate)}
};

CK_OBJECT_HANDLE hCert;
rv = C_CreateObject(hSession, template, 7, &hCert);

CKA_ID:密钥与证书的"纽带"

CKA_ID是连接公钥、私钥、证书三者的关键属性。

复制代码
理想关联关系:

┌───────────────────┐
│  X.509证书对象     │  CKA_ID = 0x01
│  CKA_SUBJECT      │
│  CKA_VALUE        │
└───────────────────┘
         │
         │ CKA_ID相同
         ▼
┌───────────────────┐
│  公钥对象          │  CKA_ID = 0x01
│  CKA_CLASS =       │
│  CKO_PUBLIC_KEY    │
└───────────────────┘
         │
         │ CKA_ID相同
         ▼
┌───────────────────┐
│  私钥对象          │  CKA_ID = 0x01
│  CKA_CLASS =       │
│  CKO_PRIVATE_KEY   │
│  CKA_SENSITIVE=TRUE│
└───────────────────┘

规范建议:同一主体的公钥、私钥、证书应该使用相同的CKA_ID值,方便应用程序查找关联对象。

实际约束:Cryptoki不强制这种关联,也不强制CKA_ID的唯一性。应用程序需要自行维护这种关联关系。


CKA_URL:移动设备的轻量存储

当证书较大时,可以选择存储URL而非证书本身:

c 复制代码
CK_ATTRIBUTE template[] = {
    {CKA_CLASS, &class, sizeof(class)},
    {CKA_CERTIFICATE_TYPE, &certType, sizeof(certType)},
    {CKA_SUBJECT, subject, sizeof(subject)},
    {CKA_URL, "https://ca.example.com/certs/server.der", 36},
    {CKA_HASH_OF_SUBJECT_PUBLIC_KEY, hash, sizeof(hash)}
};

适用场景

  • 移动设备存储空间有限
  • 证书需要动态更新
  • 证书存储在外部服务器

约束:CKA_VALUE和CKA_URL不能同时为空,至少要有一个。


X.509属性证书对象

属性证书(CKC_X_509_ATTR_CERT)不是公钥证书,而是绑定属性到主体的证书。

复制代码
公钥证书 vs 属性证书:

X.509公钥证书(CKC_X_509)
├── 主体:Subject DN
├── 公钥:RSA/ECDSA等
├── 签发者:Issuer DN
└── 用途:证明"我是谁"(身份认证)

X.509属性证书(CKC_X_509_ATTR_CERT)
├── 主体:Owner(不同于Subject)
├── 属性:角色、权限、组等
├── 签发者:AC Issuer
└── 用途:证明"我能做什么"(授权)

专属属性

属性 数据类型 含义
CKA_OWNER Byte array 属性证书主体的DER编码(必须)
CKA_AC_ISSUER Byte array 属性签发者的DER编码
CKA_SERIAL_NUMBER Byte array 序列号
CKA_ATTR_TYPES Byte array 属性类型OID序列
CKA_VALUE Byte array 属性证书BER编码(必须)

注意:CKA_OWNER与CKA_SUBJECT使用不同的ASN.1语法,这是规范明确区分的。


WTLS证书对象

WTLS证书(CKC_WTLS)来自无线传输层安全协议,用于移动设备环境。

复制代码
WTLS vs X.509:

WTLS证书特点:
- 编码格式更紧凑(适合移动设备)
- Subject/Issuer使用WTLS特有的Identifier编码
- 与X.509证书的ASN.1语法不同

适用场景:
- WAP移动设备
- 资源受限环境

CKA_TRUSTED:信任锚点

CKA_TRUSTED = CK_TRUE表示此证书被信任为根证书(Trust Anchor)。

安全约束

  • 应用程序不能将CKA_TRUSTED设置为CK_TRUE
  • 只有SO(Security Officer)或Token初始化程序可以设置
  • 可信证书不可被修改
c 复制代码
/* 应用程序尝试设置CKA_TRUSTED会失败 */

CK_BBOOL trusted = CK_TRUE;
CK_ATTRIBUTE template[] = {
    {CKA_TRUSTED, &trusted, sizeof(trusted)}
};
rv = C_CreateObject(hSession, template, 1, &hCert);
// 返回CKR_ATTRIBUTE_READ_ONLY或CKR_USER_NOT_LOGGED_IN

设计意图:防止恶意应用程序植入"假信任锚点"。只有Token管理员才能决定哪些证书是可信的。


证书对象在车载HSM中的应用

车载HSM常见的证书对象配置:

复制代码
车载证书存储方案:

┌─────────────────────────────────────┐
│ Token(HSM安全存储区)               │
│                                     │
│  ┌───────────────┐                 │
│  │ CA根证书       │ CKA_TRUSTED=TRUE│
│  │ CKA_CATEGORY  │ = AUTHORITY     │
│  │ CKA_ID = 0xFF │ (不可修改)      │
│  └───────────────┘                 │
│                                     │
│  ┌───────────────┐                 │
│  │ 设备证书       │ CKA_TRUSTED=FALSE│
│  │ CKA_CATEGORY  │ = TOKEN_USER    │
│  │ CKA_ID = 0x01 │ (关联私钥)      │
│  └───────────────┘                 │
│         │                           │
│         │ CKA_ID关联                │
│         ▼                           │
│  ┌───────────────┐                 │
│  │ 设备私钥       │ CKA_ID = 0x01  │
│  │ CKA_SENSITIVE │ = TRUE          │
│  │ CKA_SIGN      │ = TRUE          │
│  └───────────────┘                 │
└─────────────────────────────────────┘

典型应用场景

  1. 安全启动:Boot ROM验证固件签名证书链
  2. 车载通信:V2X通信使用设备证书签名消息
  3. 诊断认证:UDS 27服务验证诊断仪证书

小结:证书对象的设计智慧

证书对象的设计体现了PKCS#11的核心哲学:

复制代码
设计要点回顾:

1. "只存储,不验证"
   - Cryptoki不验证证书有效性
   - 不检查证书链
   - 不解析证书内容
   - 应用程序负责这些工作

2. "信任锚点需要管理员授权"
   - CKA_TRUSTED只能由SO设置
   - 防止应用程序植入假信任锚
   - 体现硬件安全模块的"信任根"定位

3. "灵活的存储方式"
   - 可以存储完整证书(CKA_VALUE)
   - 可以只存储URL(CKA_URL)
   - 适应不同设备的存储约束

4. "清晰的关联机制"
   - CKA_ID连接公钥、私钥、证书
   - 不强制,但建议应用程序维护关联

证书对象为PKCS#11提供了"身份证明"的存储能力,而真正使用证书进行安全操作(签名、验证),则需要对应的密钥对象。

下一节,我们将了解硬件特性对象------看时钟、计数器等特殊对象。

【下集预告】

HSM有哪些特殊对象?

时钟对象有什么用?单调计数器是什么?

用户界面对象怎么工作?

下一节,硬件特征对象。

相关推荐
FreakStudio2 小时前
WIZnet 开源方案分享:W55MH32 开发板 + 小智 AI实现以太网版本的小智机器人
python·单片机·嵌入式·大学生·面向对象·并行计算·电子diy·电子计算机
德迅--文琪2 小时前
筑牢主机安全最后一公里,德迅卫士构建全维度智能防护屏障
安全
+wacyltd大模型备案算法备案2 小时前
大模型评估测试题库怎么建?风险分类、测试样本的完整方法
人工智能·算法·安全·分类·大模型·大模型备案·大模型上线登记
金色的暴发户4 小时前
一劳永逸解决Codex手机验证
前端·人工智能·开源
dddwjzx4 小时前
嵌入式Linux C应用编程入门——进程 ( 二 )
linux·嵌入式
kuankeTech4 小时前
数据驱动替代经验经营,AI外贸ERP从记录工具升级为经营决策助手
大数据·人工智能·开源·软件开发·erp
志栋智能5 小时前
超自动化安全如何优化安全运营成本?
人工智能·安全·自动化
jieyucx6 小时前
【系统安全铁律】解密 Linux 权限三色数字密码:chmod 最小化赋权与生产环境避坑指南
linux·安全·系统安全·权限·chmod·777
葫三生6 小时前
《论三生原理》与模糊数学的关联、异同、互补关系?
人工智能·科技·算法·机器学习·开源