PKCS11,对象 PIN
PKCS11, OBJECT PIN
我正在为网络应用制作 pkcs11 模块。它是证书的远程存储,它提供 API 用于签名数据。 API 签名看起来像这样:
sign(int CertificateId, char* Password, void* data, int lenght)
在 pkcs11 模块中,整个存储由一个令牌表示。在 C_Initialize 部分,我向服务器进行身份验证。我找到了另一个 API 调用的对象,一切都很好。问题是,当我调用 C_SignInit 或 C_Sign 函数时,我不知道如何为我的对象获取辅助密码。
谁能帮帮我?
在 PKCS#11 中,所有对象都使用用户 PIN 进行保护。他们没有自己的 PIN。因此,没有标准方法可以为特定对象请求不同的 PIN。
如果您将保护 .pfx 或 .pvk 文件中的私钥的密码称为 "secondary password",那您就错了。这些密码用于保护那些文件(.pfx 或 .pvk)中的私钥,而不是 HSM 文件中的私钥。 HSM 中没有其他密码来保护密钥。如果您想调用 api 功能,您必须使用用户或管理员 PIN 登录。
正如 Eugene Mayevski 在 PKCS#11 中没有 "object PIN" 这样的概念。
您可以实施以下架构的某些变体以获得类似的访问控制模型:
正在注册密钥对:
通过 C_GenerateKeyPair
生成密钥对并确保私钥生成为仅会话对象(即使用 CKA_TOKEN==FALSE
)。另一种方法是以某种方式导入密钥对(这里不讨论)。
生成一个强密码(或使用用户提供的密码)并运行通过一些KDF得到"unlocking key"。将此 "unlocking key" 保存在您的应用程序内存中。
生成一个新的持久对称"derivation key",它只允许密钥派生(即CKA_TOKEN==TRUE
和CKA_DERIVE==TRUE
)使用例如CKM_AES_KEY_GEN
.
派生一个新的 "wrap key" 仅限会话的密钥对象,例如使用CKM_AES_CBC_ENCRYPT_DATA
以 "unblocking key" 字节作为输入多样化数据并使用 "derivation key" 作为主密钥。新密钥应该是一个仅限会话的对象,并且应该只允许密钥包装(即 CKA_TOKEN==FALSE
和 CKA_WRAP==TRUE
)。
使用"wrap key"将步骤1中的私钥对象包装成"key blob"。
存储 "key blob"(令牌内部或外部)。
删除步骤 1 中的私钥和 "wrap key"。 Nuke 密码和 "unlocking key"。 (即使前面的一些步骤失败了也要做这一步)
在不知道密码的情况下应该无法访问私钥。
使用密钥对:
运行通过同样的KDF输入密码得到"unlocking key".
以与密钥注册期间相同的方式导出 "wrap key",但这次仅用于解包(即 CKA_TOKEN==FALSE
和 CKA_UNWRAP==TRUE
)。
将 "key blob" 解包到新的仅限会话的私钥对象中。
删除"wrap key"。 Nuke 密码和 "unlocking key"。 (即使前面的一些步骤失败了也要做这一步)
随意使用密钥对。
删除私钥。 (即使前面的一些步骤失败了也要做这一步)
擦除密钥对:
- 删除关联的"derivation key"和"key blob"。
一些额外的(随机)注释:
所使用的 AES 机制只是示例。如果使用 CKM_AES_CBC_ENCRYPT_DATA
.
,则必须将使用过的 IV 与 "key blob" 一起存储
非常注意所有对象属性值(即拒绝所有不需要的东西)。如果您的设备支持某些供应商定义的扩展来控制对象的使用,那么请务必使用它们(例如强制执行 wrap/unwrap/derive 允许的机制)。
记住 wipe/delete 来自 memory/session 的密码和临时密钥。
使用供应商特定的包装机制,因为它们可能提供更好的保护(如果可能)。
删除会话对象的一种简便方法是关闭会话。
如果包装机制未提供,您可能希望保护 "key blob" 的完整性。
祝你好运!
免责声明:我不是加密专家,所以请验证我的想法。
PKCS#11 的想法是使用 1 个密码 (PIN) 来保护整个令牌。位于同一令牌上的密钥的二次身份验证已完全排除在协议之外。如 2.01 规范中所述:
Using a private key protected by secondary authentication uses the same process, and call sequence, as using a private key that is only protected by the login PIN. In fact, applications written for Cryptoki Version 2.01 will use secondary authentication without modification.
转换为:"secondary authentication is not our problem. Such mechanisms must be implemented OUTSIDE of our protocol"。
但是,他们描述了一种技巧,可以在密钥实际位于同一令牌上时公开多个 PIN here
Link 到 2.11 规范:here
我正在为网络应用制作 pkcs11 模块。它是证书的远程存储,它提供 API 用于签名数据。 API 签名看起来像这样: sign(int CertificateId, char* Password, void* data, int lenght)
在 pkcs11 模块中,整个存储由一个令牌表示。在 C_Initialize 部分,我向服务器进行身份验证。我找到了另一个 API 调用的对象,一切都很好。问题是,当我调用 C_SignInit 或 C_Sign 函数时,我不知道如何为我的对象获取辅助密码。 谁能帮帮我?
在 PKCS#11 中,所有对象都使用用户 PIN 进行保护。他们没有自己的 PIN。因此,没有标准方法可以为特定对象请求不同的 PIN。
如果您将保护 .pfx 或 .pvk 文件中的私钥的密码称为 "secondary password",那您就错了。这些密码用于保护那些文件(.pfx 或 .pvk)中的私钥,而不是 HSM 文件中的私钥。 HSM 中没有其他密码来保护密钥。如果您想调用 api 功能,您必须使用用户或管理员 PIN 登录。
正如 Eugene Mayevski
您可以实施以下架构的某些变体以获得类似的访问控制模型:
正在注册密钥对:
通过
C_GenerateKeyPair
生成密钥对并确保私钥生成为仅会话对象(即使用CKA_TOKEN==FALSE
)。另一种方法是以某种方式导入密钥对(这里不讨论)。生成一个强密码(或使用用户提供的密码)并运行通过一些KDF得到"unlocking key"。将此 "unlocking key" 保存在您的应用程序内存中。
生成一个新的持久对称"derivation key",它只允许密钥派生(即
CKA_TOKEN==TRUE
和CKA_DERIVE==TRUE
)使用例如CKM_AES_KEY_GEN
.派生一个新的 "wrap key" 仅限会话的密钥对象,例如使用
CKM_AES_CBC_ENCRYPT_DATA
以 "unblocking key" 字节作为输入多样化数据并使用 "derivation key" 作为主密钥。新密钥应该是一个仅限会话的对象,并且应该只允许密钥包装(即CKA_TOKEN==FALSE
和CKA_WRAP==TRUE
)。使用"wrap key"将步骤1中的私钥对象包装成"key blob"。
存储 "key blob"(令牌内部或外部)。
删除步骤 1 中的私钥和 "wrap key"。 Nuke 密码和 "unlocking key"。 (即使前面的一些步骤失败了也要做这一步)
在不知道密码的情况下应该无法访问私钥。
使用密钥对:
运行通过同样的KDF输入密码得到"unlocking key".
以与密钥注册期间相同的方式导出 "wrap key",但这次仅用于解包(即
CKA_TOKEN==FALSE
和CKA_UNWRAP==TRUE
)。将 "key blob" 解包到新的仅限会话的私钥对象中。
删除"wrap key"。 Nuke 密码和 "unlocking key"。 (即使前面的一些步骤失败了也要做这一步)
随意使用密钥对。
删除私钥。 (即使前面的一些步骤失败了也要做这一步)
擦除密钥对:
- 删除关联的"derivation key"和"key blob"。
一些额外的(随机)注释:
所使用的 AES 机制只是示例。如果使用
CKM_AES_CBC_ENCRYPT_DATA
. ,则必须将使用过的 IV 与 "key blob" 一起存储
非常注意所有对象属性值(即拒绝所有不需要的东西)。如果您的设备支持某些供应商定义的扩展来控制对象的使用,那么请务必使用它们(例如强制执行 wrap/unwrap/derive 允许的机制)。
记住 wipe/delete 来自 memory/session 的密码和临时密钥。
使用供应商特定的包装机制,因为它们可能提供更好的保护(如果可能)。
删除会话对象的一种简便方法是关闭会话。
如果包装机制未提供,您可能希望保护 "key blob" 的完整性。
祝你好运!
免责声明:我不是加密专家,所以请验证我的想法。
PKCS#11 的想法是使用 1 个密码 (PIN) 来保护整个令牌。位于同一令牌上的密钥的二次身份验证已完全排除在协议之外。如 2.01 规范中所述:
Using a private key protected by secondary authentication uses the same process, and call sequence, as using a private key that is only protected by the login PIN. In fact, applications written for Cryptoki Version 2.01 will use secondary authentication without modification.
转换为:"secondary authentication is not our problem. Such mechanisms must be implemented OUTSIDE of our protocol"。
但是,他们描述了一种技巧,可以在密钥实际位于同一令牌上时公开多个 PIN here
Link 到 2.11 规范:here