在cryptoki库中提取或设置私钥参数

时间:2015-05-15 10:41:23

标签: c cryptography nss

我遇到了一些使用cryptoki库编写小型测试程序的问题。我希望(有)获取RSA私钥(所有参数)。我想过要么生成密钥然后提取参数,要么使用已经生成的参数来手动设置密钥。到目前为止,我没有得到任何这方面的工作。代码在帖子的末尾。

提取

我知道有 C_GetAttributeValue(),我可以使用它来提取公共指数或模数等属性。这适用于公钥和私钥对象,但是当我尝试从私钥对象中提取私有参数时,我得到 CKR_ATTRIBUTE_SENSITIVE 错误。有没有办法提取这些属性?登录会话或初始化期间是否可以设置某些参数?

手动设置密钥

我的第二种方法是从文件中读取密钥材料(使用OPENSSL生成),并使用它来生成具有 C_CreateObject()的密钥对象。该文件包含所有RSA参数(n,e,d,p,q,dmp1,dmq1,iqmp)。阅读后,我将它们从ASCII转换为十六进制表示,并将它们存储在 CK_BYTE [] 中。到现在为止还挺好。现在,当我将所有这些传递给 C_CreateObject()以创建私钥时,我收到 CKR_ATTRIBUTE_VALUE_INVALID 错误消息。使用公共参数以相同的方式创建公钥对象。我验证了在创建的公钥对象上使用 C_GetAttributeValue()。 如果这样甚至可能产生私钥对象,我错过了什么? 我认为 C_GenerateKeyPair()总是生成新密钥,无论是否提供密钥材料,对吧?

C代码

这是我尝试使用以下方法创建私钥对象的方法:

CK_OBJECT_HANDLE hPrivateKeys[NUMKEYS];
CK_KEY_TYPE kType= CKK_RSA;
CK_OBJECT_CLASS kClass = CKO_PRIVATE_KEY;
CK_BYTE id[] = {123};
CK_UTF8CHAR label[] = "An RSA private key object";

// sn,sd,se, etc contain the length of the respective parameter
CK_ATTRIBUTE privateKeyTemplate[] = {
            {CKA_CLASS, &kClass, sizeof(kClass)},
            {CKA_KEY_TYPE, &kType, sizeof(kType)},
            {CKA_TOKEN, &false, sizeof(false)},
            {CKA_PRIVATE, &false, sizeof(false)},
            {CKA_SENSITIVE, &false, sizeof(false)},
            {CKA_EXTRACTABLE, &true, sizeof(true)},
            {CKA_ID, id, sizeof(id)},
            {CKA_SUBJECT, NULL_PTR, 0},
            {CKA_DECRYPT, &true, sizeof(true)},
            {CKA_SIGN, &true, sizeof(true)},
            {CKA_LABEL, label, sizeof(label)-1},
            {CKA_ID, id, sizeof(id)},
            {CKA_MODULUS, modulus, sn},
            {CKA_PUBLIC_EXPONENT, publicExponent, se},
            {CKA_PRIVATE_EXPONENT, privateExponent, sd},
            {CKA_PRIME_1, prime1, sp},
            {CKA_PRIME_2, prime2, sq},
            {CKA_EXPONENT_1, exponent1, sdmp1},
            {CKA_EXPONENT_2, exponent2, sdmq1},
            {CKA_COEFFICIENT, coefficient, siqmp}
    };

    CK_ATTRIBUTE publicKeyTemplate[] = {
            {CKA_ENCRYPT, &true, sizeof(true)},
            {CKA_VERIFY, &true, sizeof(true)},
            {CKA_WRAP, &true, sizeof(true)},
            {CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
            {CKA_PUBLIC_EXPONENT, publicExponent, se},
            {CKA_MODULUS, modulus, sn}
    };

rv = pFunctionList->C_CreateObject(hSession, privateKeyTemplate, NUM_ELEM(privateKeyTemplate), &hPrivateKeys[j]);

1 个答案:

答案 0 :(得分:0)

您生成密钥对然后将其读出的想法很好,但您应该在私钥模板中将属性CKA_SENSITIVE设置为false。请注意,如果支持此类功能,它始终取决于令牌本身。

通常当从令牌中提取私钥信息时,您希望对其进行加密。密钥加密称为包装,敏感信息的可能提取由CKA_EXTRACTABLE属性管理。

  

阅读后,我将它们从ASCII转换为十六进制表示,并将它们存储在CK_BYTE []中。

PKCS#11令牌接口精确指定如何编码/解码属性。只是偶然地尝试格式不会产生任何结果。