HSM技术精讲(3.6):通用属性详解——所有Object共享的“基因“
3.6 通用属性详解所有Object共享的基因本文内容摘自本人的开源书《HSM技术书 - 从思想实验到安全基石》 在线阅读/下载hsm-bookgitclone https://github.com/Lularible/hsm-book.git⭐ 如果对您有帮助欢迎 Star 支持也欢迎通过 GitHub Issues 交流讨论。什么是通用属性PKCS#11规范第4.2节定义了一组通用属性——所有Object都必须或可能拥有的属性。这些属性就像Object的基因决定了Object的基本行为。必需属性与可选属性必需属性RequiredObject必须拥有这些属性否则创建失败。可选属性OptionalObject可以拥有这些属性也可以不拥有。通用属性分类 必需属性创建时必须提供 ├── CKA_CLASS Object类型必须 └── 其他取决于Object类型 可选属性可以提供也可以不提供 ├── CKA_TOKEN 是否存储在Token中 ├── CKA_PRIVATE 是否私有 ├── CKA_MODIFIABLE 是否可修改属性 ├── CKA_DESTROYABLE 是否可销毁 ├── CKA_LABEL 用户标签 ├── CKA_ID 用户ID ├── CKA_UNIQUE_ID Token内的唯一ID由Token生成 └── CKA_COPYABLE 是否可复制CKA_CLASSObject的类型标识定义Object的类型。取值CK_OBJECT_CLASS常量CKO_PUBLIC_KEY、CKO_PRIVATE_KEY等必需性所有Object都必须拥有。CK_OBJECT_CLASS objClassCKO_PUBLIC_KEY;CK_ATTRIBUTE classAttr{CKA_CLASS,objClass,sizeof(objClass)};意义CKA_CLASS决定了Object是什么CKO_PUBLIC_KEY → 公钥对象CKO_PRIVATE_KEY → 私钥对象CKO_SECRET_KEY → 对称密钥对象CKO_CERTIFICATE → 证书对象CKO_DATA → 数据对象Token根据CKA_CLASS来决定Object需要哪些其他属性。CKA_TOKEN持久性的开关定义Object是否存储在Token中持久化。取值CK_BBOOLTRUE或FALSE默认值FALSE意义CKA_TOKENObject类型生命周期存储位置FALSESession ObjectSession关闭后消失Session内存TRUEToken Object永久存储Token存储/* 创建Session Object临时 */CK_BBOOL bTokenFALSE;CK_ATTRIBUTE tokenAttr{CKA_TOKEN,bToken,sizeof(bToken)};// Session关闭后Object消失/* 创建Token Object持久 */CK_BBOOL bTokenTRUE;CK_ATTRIBUTE tokenAttr{CKA_TOKEN,bToken,sizeof(bToken)};// Session关闭后Object仍然存在// 下次打开SessionObject仍然可用使用场景Session Object临时密钥如协商出的会话密钥、一次性数据Token Object长期密钥如CA私钥、证书、配置数据CKA_PRIVATE访问控制的闸门定义Object是否私有需要登录才能访问。取值CK_BBOOLTRUE或FALSE默认值依赖Token默认行为通常是TRUE意义CKA_PRIVATE未登录Session已登录SessionFALSE可访问可访问TRUE不可访问可访问/* 创建公开对象 */CK_BBOOL bPrivateFALSE;CK_ATTRIBUTE privateAttr{CKA_PRIVATE,bPrivate,sizeof(bPrivate)};// 不需要C_Login可以直接访问/* 创建私有对象 */CK_BBOOL bPrivateTRUE;CK_ATTRIBUTE privateAttr{CKA_PRIVATE,bPrivate,sizeof(bPrivate)};// 必须C_Login后才能访问安全意义公开对象公钥、证书本意就是要公开私有对象私钥、敏感数据需要保护CKA_MODIFIABLE属性的锁定义Object的属性是否可以修改。取值CK_BBOOLTRUE或FALSE默认值TRUE意义CKA_MODIFIABLEC_SetAttributeValue备注TRUE可以修改属性可以更新标签等FALSE不能修改属性属性锁死/* 可修改属性的对象 */CK_BBOOL bModifiableTRUE;CK_ATTRIBUTE modAttr{CKA_MODIFIABLE,bModifiable,sizeof(bModifiable)};// 之后可以修改标签等属性rvC_SetAttributeValue(hSession,hObject,setTemplate,1);/* 不可修改属性的对象 */CK_BBOOL bModifiableFALSE;CK_ATTRIBUTE modAttr{CKA_MODIFIABLE,bModifiable,sizeof(bModifiable)};// 之后不能修改任何属性除了特殊属性安全意义设置CKA_MODIFIABLE FALSE可以防止属性被篡改增强安全性。CKA_DESTROYABLE销毁的开关定义Object是否可以被销毁C_DestroyObject。取值CK_BBOOLTRUE或FALSE默认值TRUE意义CKA_DESTROYABLEC_DestroyObject备注TRUE可以销毁可以删除密钥FALSE不能销毁密钥永存/* 可销毁的对象 */CK_BBOOL bDestroyableTRUE;CK_ATTRIBUTE destroyAttr{CKA_DESTROYABLE,bDestroyable,sizeof(bDestroyable)};// 之后可以销毁rvC_DestroyObject(hSession,hObject);/* 不可销毁的对象 */CK_BBOOL bDestroyableFALSE;CK_ATTRIBUTE destroyAttr{CKA_DESTROYABLE,bDestroyable,sizeof(bDestroyable)};// 之后不能销毁rvC_DestroyObject(hSession,hObject);// 返回CKR_ACTION_PROHIBITED安全意义设置CKA_DESTROYABLE FALSE可以防止密钥被意外或恶意删除。CKA_LABEL与CKA_ID用户的标记CKA_LABEL用户定义的标签字符串。CKA_ID用户定义的ID字节数组。这两个属性都是可选的用于方便用户识别Object。/* 设置标签和ID */CK_CHAR label[]MySigningKey;CK_BYTE id[]{0x01,0x02,0x03};CK_ATTRIBUTE labelAttr{CKA_LABEL,label,sizeof(label)};CK_ATTRIBUTE idAttr{CKA_ID,id,sizeof(id)};使用场景/* 通过标签查找密钥 */CK_CHAR label[]MySigningKey;CK_ATTRIBUTE findTemplate[]{{CKA_LABEL,label,sizeof(label)},};rvC_FindObjectsInit(hSession,findTemplate,1);rvC_FindObjects(hSession,hKey,1,ulCount);rvC_FindObjectsFinal(hSession);Label与ID的区别属性类型用途CKA_LABEL字符串人可读的描述CKA_ID字节数组程序可用的标识通常公钥和私钥使用相同的CKA_ID便于关联密钥对。CKA_COPYABLE复制的开关定义Object是否可以被复制C_CopyObject。取值CK_BBOOLTRUE或FALSE默认值TRUE/* 可复制的对象 */CK_BBOOL bCopyableTRUE;CK_ATTRIBUTE copyAttr{CKA_COPYABLE,bCopyable,sizeof(bCopyable)};// 之后可以复制CK_OBJECT_HANDLE hNewObject;rvC_CopyObject(hSession,hObject,newTemplate,1,hNewObject);/* 不可复制的对象 */CK_BBOOL bCopyableFALSE;CK_ATTRIBUTE copyAttr{CKA_COPYABLE,bCopyable,sizeof(bCopyable)};// 之后不能复制CKA_UNIQUE_IDToken生成的唯一标识符定义PKCS#11 v3.1标准通用属性0x0000010B由Token为每个Object自动生成的唯一标识符。特点由Token自动生成不能手动设置保证Token内唯一用于内部管理/* 读取UNIQUE_ID */CK_ATTRIBUTE uniqueIdAttr{CKA_UNIQUE_ID,NULL_PTR,0};// 先获取长度rvC_GetAttributeValue(hSession,hObject,uniqueIdAttr,1);// 分配内存读取值CK_BYTE uniqueId[uniqueIdAttr.ulValueLen];uniqueIdAttr.pValueuniqueId;rvC_GetAttributeValue(hSession,hObject,uniqueIdAttr,1);通用属性的完整列表根据PKCS#11 v3.1规范第4.2节属性类型必需性默认值描述CKA_CLASSCK_OBJECT_CLASS必需-Object类型CKA_TOKENCK_BBOOL可选FALSE是否存储在Token中CKA_PRIVATECK_BBOOL可选Token默认是否私有CKA_MODIFIABLECK_BBOOL可选TRUE是否可修改属性CKA_DESTROYABLECK_BBOOL可选TRUE是否可销毁CKA_LABELCK_UTF8CHAR[]可选空用户标签CKA_IDCK_BYTE[]可选空用户IDCKA_UNIQUE_IDCK_BYTE[]Token生成-唯一标识CKA_COPYABLECK_BBOOL可选TRUE是否可复制属性的组合效应这些通用属性可以组合产生不同的效果组合一最高安全密钥最高安全密钥属性组合 CKA_CLASS CKO_PRIVATE_KEY 私钥对象 CKA_TOKEN TRUE 持久存储 CKA_PRIVATE TRUE 需要登录 CKA_MODIFIABLE FALSE 属性不可修改 CKA_DESTROYABLE FALSE 不可销毁 CKA_COPYABLE FALSE 不可复制 CKA_SENSITIVE TRUE 密钥值不可读取密钥对象属性 CKA_EXTRACTABLE FALSE 密钥不可导出密钥对象属性 效果 - 密钥永久存在 - 需要登录才能使用 - 属性不可修改 - 密钥不可销毁 - 密钥不可复制 - 密钥值不可读取 - 密钥不可导出 密钥锁死在Token中组合二临时会话密钥临时会话密钥属性组合 CKA_CLASS CKO_SECRET_KEY 对称密钥对象 CKA_TOKEN FALSE 不持久Session Object CKA_PRIVATE TRUE 需要登录 CKA_MODIFIABLE TRUE 可修改 CKA_DESTROYABLE TRUE 可销毁 CKA_COPYABLE TRUE 可复制 效果 - Session关闭后密钥消失 - 需要登录才能使用 - 可以修改标签等 - 可以销毁 - 可以复制 临时密钥灵活使用组合三公开证书公开证书属性组合 CKA_CLASS CKO_CERTIFICATE 证书对象 CKA_TOKEN TRUE 持久存储 CKA_PRIVATE FALSE 公开不需要登录 CKA_MODIFIABLE FALSE 属性不可修改 CKA_DESTROYABLE TRUE 可销毁 效果 - 证书永久存储 - 不需要登录就能查看 - 属性不可修改防止篡改 - 可以销毁可以删除证书 公开但防篡改的证书本篇小结通用属性是所有Object共享的基因定义了Object的基本行为。必需属性CKA_CLASSObject类型所有Object必须有可选属性控制生命周期、访问、操作CKA_TOKEN持久性开关FALSE临时TRUE永久CKA_PRIVATE访问闸门FALSE公开TRUE私有CKA_MODIFIABLE属性锁FALSE不可修改CKA_DESTROYABLE销毁开关FALSE不可销毁CKA_COPYABLE复制开关FALSE不可复制用户标记属性CKA_LABEL人可读标签CKA_ID程序可用IDToken生成属性CKA_UNIQUE_IDToken内的唯一标识下一节我们将深入密钥对象的专属属性——CKA_SENSITIVE、CKA_EXTRACTABLE、CKA_ALWAYS_SENSITIVE、CKA_NEVER_EXTRACTABLE等安全属性。【下集预告】密钥对象有专属的安全属性。CKA_SENSITIVE密钥值是否可读取CKA_EXTRACTABLE密钥是否可导出CKA_ALWAYS_SENSITIVE创建时就敏感永远不能改CKA_NEVER_EXTRACTABLE创建时就不能导出永远不能改这些属性如何锁定密钥的安全边界下一节密钥对象与安全属性。