Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将C_签名调用与C_生成分开_C_Cryptography_Pkcs#11 - Fatal编程技术网

将C_签名调用与C_生成分开

将C_签名调用与C_生成分开,c,cryptography,pkcs#11,C,Cryptography,Pkcs#11,我正在用C代码实现pkcs11,并尝试实现一个简单的生成、签名、验证工作流。当我对我的pkcs11驱动程序进行一次简单的调用时,这个流程就开始工作了。但是,我正在尝试解耦这些调用,以便能够生成一个密钥,在稍后的阶段将其用于单独的c_签名或c_验证调用 我的主要问题是c_sign调用需要一个CK_OBJECT_HANDLE参数作为私钥句柄,但我不知道如何在以后的阶段检索这个参数。它在单个“generate->sign->verify”流上工作的原因是句柄仍然在generate调用的内存中,使得它在

我正在用C代码实现pkcs11,并尝试实现一个简单的生成、签名、验证工作流。当我对我的pkcs11驱动程序进行一次简单的调用时,这个流程就开始工作了。但是,我正在尝试解耦这些调用,以便能够生成一个密钥,在稍后的阶段将其用于单独的c_签名或c_验证调用

我的主要问题是c_sign调用需要一个CK_OBJECT_HANDLE参数作为私钥句柄,但我不知道如何在以后的阶段检索这个参数。它在单个“generate->sign->verify”流上工作的原因是句柄仍然在generate调用的内存中,使得它在后续调用中很容易访问

我的生成呼叫如下所示:

C_GenerateKeyPair(hSession, &mechanism, 
                  publicKeyTemplate, 
                  sizeof(publicKeyTemplate)/sizeof(CK_ATTRIBUTE), 
                  privateKeyTemplate, 
                  sizeof(privateKeyTemplate)/sizeof(CK_ATTRIBUTE), 
                  phPublicKey, phPrivateKey);
其中
phPublicKey
phPrivateKey
是句柄的存储位置


后续的sign函数需要一个
hPrivateKey
参数,用于我要签名的privKey。

句柄绑定到会话。在新会话中,句柄不再有效。要维护对密钥的引用,需要为其指定一些唯一的名称。有两种方法可以做到这一点:

  • 任何属性都可以有一个
    CKA\u LABEL
    属性,其值为可打印字符串
  • 任何属性都可以具有值为字节数组的
    CKA\u ID
    属性
为密钥提供唯一的id或标签。要稍后打开它,您需要搜索它。这是唯一的方法:PKCS#11没有直接按名称打开密钥的方法!您需要搜索具有正确id/标签的对象,如果该属性是唯一的,则您知道您找到的第一个是正确的。将匹配密钥对中的公钥和私钥赋予相同的id/标签是可以的(而且更方便);在搜索时,通过class属性指定所需的类别

创建:

CK_BYTE id[] = {0x01, 0x02, 0x03, 0x04};
int generate_key(CK_SESSION_HANDLE hSession, …)
{
    CK_BBOOL ck_true = CK_TRUE;
    CK_ATTRIBUTE publicKeyTemplate[] = {
        {CKA_TOKEN, &ck_true, sizeof(ck_true)},
        {CKA_ID, id, sizeof(id)},
        …
    };
    CK_ATTRIBUTE privateKeyTemplate[] = {
        {CKA_TOKEN, &ck_true, sizeof(ck_true)},
        {CKA_ID, id, sizeof(id)},
        …
    };
    CK_MECHANISM mechanism = …;
    CK_OBJECT_HANDLE hPublicKey = CK_INVALID_HANDLE;
    CK_OBJECT_HANDLE hPrivateKey = CK_INVALID_HANDLE;
    C_GenerateKeyPair(hSession, &mechanism, 
                      publicKeyTemplate, 
                      sizeof(publicKeyTemplate)/sizeof(CK_ATTRIBUTE), 
                      privateKeyTemplate, 
                      sizeof(privateKeyTemplate)/sizeof(CK_ATTRIBUTE), 
                      &hPublicKey, &hPrivateKey);
}
使用(省略大多数错误检查):


参数不是存储在
phPrivateKey
指向的任何对象中吗?是什么阻止您在需要时将其保留在内存中?在以后的阶段,您可能需要通过
C_FindObjectsInit
-
C_FindObjects
-
C_FindObjectsFinal
函数检索对象句柄……记住为生成的对象使用合理(且唯一)的标签……祝您的项目好运!我建议你分享更多的代码,这样人们就能理解你的意思。谢谢,这就是我想要的。你也谈到了我接下来要问的问题。因为当我尝试C_FindObjects时,我得到了不止一个密钥,这是有道理的,因为它是一对密钥。。因此,我在尝试使用公钥签名时遇到了一个
无效密钥类型
错误,因为我无法从它返回的数组中知道要使用哪一个:)因此
CK\u OBJECT\u类
帮助了我!
CK_BYTE id[] = {0x01, 0x02, 0x03, 0x04}; // same as when creating the key
int sign_stuff(CK_SESSION_HANDLE hSession, ) {
    CK_OBJECT_CLASS cko_private_key = CKO_PRIVATE_KEY;
    CK_ATTRIBUTE privateKeyTemplate[] = {
        {CKA_ID, id, sizeof(id)},
        {CKA_CLASS, cko_private_key, sizeof(cko_private_key)},
    };
    C_FindObjectsInit(hSession,
                      privateKeyTemplate, sizeof(privateKeyTemplate)/sizeof(*privateKeyTemplate));
    CK_OBJECT_HANDLE hPrivateKey = CK_INVALID_HANDLE;
    CK_ULONG count = 0;
    C_FindObjects(hSession, &hPrivateKey, 1, &count);
    C_FindObjectsFinal(hSession);
    if (count == 0)
        return ERROR_KEY_NOT_FOUND;
    CK_MECHANISM mechanism = …;
    C_SignInit(hSession, &mechanism, hPrivateKey);
    …
}