Certificate HSM生成自签名证书报告“;包装键句柄无效“;错误

Certificate HSM生成自签名证书报告“;包装键句柄无效“;错误,certificate,pkcs#11,Certificate,Pkcs#11,使用HSM(带有PKCS11标准API)生成自签名证书报告“包装密钥句柄无效”错误(错误代码113,CKR\u包装密钥句柄无效)。当使用GUIctbrowser工具生成或使用与演示类似的代码时,都会发生这种情况 下面是一个代码示例来重现这个问题,它生成一个RSA密钥对,然后尝试使用它们生成一个自签名证书 int main() { int rv; CK_CHAR pwd[] = "password"; static char pubkeyLabel[256]="demoPu

使用HSM(带有PKCS11标准API)生成自签名证书报告“包装密钥句柄无效”错误(错误代码
113
CKR\u包装密钥句柄无效
)。当使用GUI
ctbrowser
工具生成或使用与演示类似的代码时,都会发生这种情况

下面是一个代码示例来重现这个问题,它生成一个RSA密钥对,然后尝试使用它们生成一个自签名证书

int main()
{
    int rv;
    CK_CHAR pwd[] = "password";
    static char pubkeyLabel[256]="demoPub";
    static char prvkeyLabel[256]="demoPrv";
    static CK_BYTE id[256];
    static CK_BBOOL isTok = TRUE;
    static CK_BBOOL True = TRUE;
    static CK_BBOOL False = FALSE;

    CK_SESSION_HANDLE hSession;
    CK_OBJECT_HANDLE hPubKey;
    CK_OBJECT_HANDLE_PTR phPubKey = &hPubKey;
    CK_OBJECT_HANDLE hSignerKey;
    CK_OBJECT_HANDLE_PTR phSignerKey = &hSignerKey;
    CK_OBJECT_HANDLE hCert;
    CK_OBJECT_HANDLE_PTR phCert = &hCert;
    CK_MECHANISM mechanism = { 0, NULL, 0 };
    static CK_SIZE mBits=2048;

    static char edate[] = {'2','0','2','0','1','2','3','1'};
    static char certLabel[128]="demo_cert";
    static char subject[256]="C=XX,ST=XX,L=XX,O=MEOW,OU=HSM,CN=TESTCERT";

    CK_ATTRIBUTE publicKeyTemplate[] = {
      {CKA_TOKEN, &isTok, 1},
      {CKA_PRIVATE, &False, 1},
      {CKA_LABEL, pubkeyLabel, sizeof(pubkeyLabel)},
      {CKA_SUBJECT_STR, subject, sizeof(subject)},
      {CKA_MODULUS_BITS, &mBits, sizeof(mBits)},
      {CKA_ENCRYPT, &False, 1},
      {CKA_VERIFY, &True, 1},
      {CKA_WRAP, &False, 1},
      {CKA_DERIVE, &True, 1},
      {CKA_EXTRACTABLE, &True, 1},
      {CKA_EXPORTABLE, &True, 1}
    };
    CK_ATTRIBUTE privateKeyTemplate[] = {
      {CKA_TOKEN, &isTok, 1},
      {CKA_LABEL, prvkeyLabel, sizeof(prvkeyLabel)},
      {CKA_PRIVATE, &True, 1},
      {CKA_SUBJECT_STR, subject, sizeof(subject)},
      {CKA_ID, id, sizeof(id)},
      {CKA_SENSITIVE, &True, 1},
      {CKA_DECRYPT, &False, 1},
      {CKA_SIGN, &True, 1},
      {CKA_UNWRAP, &True, 1},
      {CKA_WRAP, &False, 1},
      {CKA_EXTRACTABLE, &False, 1},
      {CKA_EXPORTABLE, &False, 1}
    };

    CK_ATTRIBUTE certTemplate[] = {
      {CKA_TOKEN, &True, 1},
      {CKA_PRIVATE, &False, 1},
      {CKA_LABEL, certLabel, sizeof(certLabel)},
      {CKA_SUBJECT_STR, subject, sizeof(subject)},
      {CKA_ISSUER_STR, subject, sizeof(subject)},
      {CKA_END_DATE, edate, sizeof(edate)},
      {CKA_EXTRACTABLE, &True, 1},
      {CKA_EXPORTABLE, &True, 1}
    };

    printf("Generate cert %s from %s, signed by %s.\n", certLabel, pubkeyLabel, prvkeyLabel);
    rv = C_Initialize(NULL_PTR);
    if ( rv ) return rv;

    rv = C_OpenSession(0, CKF_RW_SESSION|CKF_SERIAL_SESSION, NULL, NULL, &hSession);

    rv = C_Login(hSession, CKU_USER, pwd, 8);

    publicKeyTemplate[2].valueLen = (CK_SIZE)strlen((char*)pubkeyLabel);
    publicKeyTemplate[3].valueLen = (CK_SIZE)strlen((char*)subject)+1;
    privateKeyTemplate[1].valueLen = (CK_SIZE)strlen((char*)prvkeyLabel);
    privateKeyTemplate[3].valueLen = (CK_SIZE)strlen((char*)subject)+1;
    mechanism.mechanism = CKM_RSA_PKCS_KEY_PAIR_GEN;
    rv = C_GenerateKeyPair(hSession, &mechanism,
                           publicKeyTemplate, NUMITEMS(publicKeyTemplate),
                           privateKeyTemplate, NUMITEMS(privateKeyTemplate),
                           phPubKey, phSignerKey);
    printf("Keypair generated with rv=%x\n", rv);

    mechanism.mechanism = CKM_SHA256_RSA_PKCS;
    rv = C_SignInit(hSession, &mechanism, hSignerKey);
    printf("cert signer initiated with rv=%x\n", rv);
    mechanism.mechanism = CKM_ENCODE_X_509;
    certTemplate[2].valueLen = (CK_SIZE)strlen((char*)certLabel);
    certTemplate[3].valueLen = (CK_SIZE)strlen((char*)subject)+1;
    certTemplate[4].valueLen = (CK_SIZE)strlen((char*)subject)+1;
    rv = C_DeriveKey(hSession, &mechanism,
                     hPubKey,
                     certTemplate, NUMITEMS(certTemplate),
                     phCert);
    printf("cert generation finished with rv=%x\n", rv);

    return 0;
}

因为整个过程不涉及任何包装,所以我不知道如何调试它。有人知道它怎么了吗?(注意:插槽是预先存在并已初始化的。)

根据受版权保护的PKCS11 API指南(ProtectToolkit C Programmers Manual,版权所有©Eracom Technologies),该问题是由于缺少
CKA_序列号造成的,当未提供序列号时,将返回错误
CKR_WRAPPING_KEY_HANDLE_INVALID


因此,在签名密钥中添加
CKA\u USAGE\u COUNT
,或者通过在cert模板中指示
CKA\u serial\u number
/
CKA\u serial\u number\u INT
来指示证书的序列号可以解决此问题。

我建议您联系HSM的制造商并请求支持。您正在明确设置许多属性,包括
CKA_WRAP
CKA_UNWRAP
以及可提取和可导出的标志(可能需要包装键)。也许你应该删除这些属性,然后再试一次。如果这样做有效,你可以再次设置它们,看看是哪一个导致了错误failure@MaartenBodewes
CKA_WRAP
CKA_UNWRAP
是属性,禁用它们表示它们不会用作导出其他键的包装键EXTRACTABLE
,否则无法访问该值,更不用说将(
EXPORTABLE
标志)导出到cert中了。我尝试了各种较少的属性,但都不起作用。嘿,很高兴你解决了这个问题,感谢你向网站报告。对不起,如果我的建议不起作用;这似乎是有可能出错的事情。我不记得在HSM上看到过这个错误;奇怪,但信息很好。过了一会儿,你可以接受你自己的答案(当然我也投了赞成票)。