如何通过模板获取PKCS11 PublicKey

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过模板获取PKCS11 PublicKey相关的知识,希望对你有一定的参考价值。

我有一个GO应用程序,它通过opencryptoki(pkcs11)以软件语言将它的证书存储到HSM。但这不是一个问题,我认为这是一个普遍的问题。

我设置我的证书和私钥这样:

    certTemplate := []*pkcs11.Attribute{
        pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE),
        pkcs11.NewAttribute(pkcs11.CKA_CERTIFICATE_TYPE, pkcs11.CKC_X_509),
        pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
        pkcs11.NewAttribute(pkcs11.CKA_VALUE, certBytes),
        pkcs11.NewAttribute(pkcs11.CKA_SUBJECT, template.SubjectKeyId),
        pkcs11.NewAttribute(pkcs11.CKA_ID, pkcs11KeyID),
    }

    privateKeyTemplate := []*pkcs11.Attribute{
        pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PRIVATE_KEY),
        pkcs11.NewAttribute(pkcs11.CKA_KEY_TYPE, pkcs11.CKK_ECDSA),
        pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true), 
        pkcs11.NewAttribute(pkcs11.CKA_ID, pkcs11KeyID),
        pkcs11.NewAttribute(pkcs11.CKA_EC_PARAMS, []byte{0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07}),
        pkcs11.NewAttribute(pkcs11.CKA_VALUE, ecdsaPrivKeyD),
    }

ctx.CreateObject(session, certTemplate)
ctx.CreateObject(session, privateKeyTemplate)

这非常有效。我也可以通过证书获得证书

findTemplate := []*pkcs11.Attribute{
    pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
    pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_CERTIFICATE),
    pkcs11.NewAttribute(pkcs11.CKA_CERTIFICATE_TYPE, pkcs11.CKC_X_509),
}

ctx.FindObjectsInit(session, findTemplate); 
objs, b, err := ctx.FindObjects(session, numSlots)

但正如我所料,我无法得到我的公钥

findTemplate := []*pkcs11.Attribute{
        pkcs11.NewAttribute(pkcs11.CKA_TOKEN, true),
        pkcs11.NewAttribute(pkcs11.CKA_ID, pkcs11KeyID),
        pkcs11.NewAttribute(pkcs11.CKA_CLASS, pkcs11.CKO_PUBLIC_KEY),
    }
ctx.FindObjectsInit(session, findTemplate); 
obj, _, err := ctx.FindObjects(session, 1)

没有错误,只是hsm商店中没有密钥。

答案

虽然公钥是证书的一部分,但CKO_PUBLIC_KEY对象可能无法单独使用,并且证书也没有CKA_PUBLIC属性。

要获取公钥,您必须检索证书的CKA_VALUE并使用您最喜欢的X.509v3证书解析器进行解析。毫无疑问,结果将返回编码的公钥值或公钥作为您喜欢的运行时中的结构。

另一答案

正如您在问题中所写的那样,您只创建/导入了两个持久性令牌对象 - 证书对象(CKA_CLASS = CKO_CERTIFICATE)和私钥对象(CKA_CLASS = CKO_PRIVATE_KEY) - 所以很自然地,您只需调用FindObjectsInitFindObjects就可以找到这两个对象。

如果您还要查找公钥对象(CKA_CLASS = CKO_PUBLIC_KEY),则需要先创建/导入它。

以上是关于如何通过模板获取PKCS11 PublicKey的主要内容,如果未能解决你的问题,请参考以下文章

在 Java Card 上编码 publicKey

CAC卡/读卡器的PKCS11驱动

如何通过提供 PrivateKey 来获得 RSA PublicKey?

是否可以通过 PKCS#11 开发 baseCSP 卡微型驱动程序?

X.509证书及CeritificationPath及PKCS

如何将公共RSA密钥上传到HSM(使用PKCS#11库)?