Получить открытый ключ CryptoAPI через PKCS # 11

В моей программе на C ++ я создал пару открытый / закрытый ключ, используя CryptoAPI.

CryptGenKey(eTokenProv,ENCRYPT_ALGORITHM,CRYPT_EXPORTABLE,&k1)

Ключи хранятся в eToken.
Можно ли получить открытый ключ, используя PKCS # 11? Ранее созданный закрытый ключ находится после поиска по следующему шаблону поиска:

    CK_ATTRIBUTE private_search[] = {
{CKA_PRIVATE, CK_TRUE, sizeof(CK_BBOOL)}
};

Если я установлю CKA_PRIVATE в CK_FALSE, я не могу получить открытый ключ. Я также пробовал с другими атрибутами.
Есть ли способ сделать это?

РЕДАКТИРОВАТЬ

Как owlstead предполагает, что я попытался создать открытый ключ, начиная с модуля и экспоненты открытого ключа, созданного в предыдущем сеансе (в CAPI или, только для этого теста, в PKCS11). Я получил модуль и открытый показатель из закрытого ключа в этих буферах:

CK_BYTE  modulus[128]; //if 1024bit
CK_BYTE  publicExponent[4]; //4 Byte, according to public key blob

Но когда я пытаюсь создать новый публичный ключ с помощью следующих инструкций:

CK_ATTRIBUTE publicKeyTemplate[] = {
{CKA_TOKEN, &yes, sizeof(true)},
{CKA_WRAP, &yes, sizeof(true)},
{CKA_ENCRYPT, &yes, sizeof(true)},
{CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
{CKA_MODULUS, &modulus, sizeof(modulus)},
{CKA_PUBLIC_EXPONENT, &publicExponent, sizeof(publicExponent)}

CK_MECHANISM mechanism = {CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };
rv = (*functions->C_GenerateKeyPair) (session, &mechanism, publicKeyTemplate, 6, privateKeyTemplate, 6, &hPublicKey, &hPrivateKey);

Я получаю ошибку «Неверный шаблон». Проблема в модуле, потому что без него я могу создать пару ключей. Я использую функцию C_GenerateKeyPair, но меня интересует только открытый ключ. Я опустил закрытый шаблон.
Что здесь не так?

1

Решение

CKA_PRIVATE не указывает закрытый ключ вообще.

Когда атрибут CKA_PRIVATE равен TRUE, пользователь не может получить доступ к объекту, пока пользователь
был аутентифицирован в токене

Вместо этого вы должны искать такой атрибут, как CKA_CLASS со значением CKO_PUBLIC_KEY или же CKO_PRIVATE_KEY, возможно, используя другие атрибуты для дальнейшей фильтрации ваших результатов.

Если вы не можете найти какие-либо CKO_PUBLIC_KEY затем я предполагаю, что он не был сгенерирован в токене (ключ был импортирован, проверьте, CKA_LOCAL установлено). В качестве альтернативы, он может быть создан только как объект сеанса. Наконец это могло быть удалено.

Обратите внимание, что закрытые ключи RSA обычно содержат открытый показатель, поэтому вы все равно можете создать открытый ключ только из объекта закрытого ключа (конечно, используя модуль и открытый показатель).

2

Другие решения

Удалите символ ссылки в CK_ATTRIBUTE при установке указателя на массив CK_BYTE — в вашем случае модуль.

CK_ATTRIBUTE publicKeyTemplate[] = {
{CKA_TOKEN, &yes, sizeof(true)},
{CKA_WRAP, &yes, sizeof(true)},
{CKA_ENCRYPT, &yes, sizeof(true)},
{CKA_MODULUS_BITS, &modulusBits, sizeof(modulusBits)},
{CKA_MODULUS, modulus, sizeof(modulus)},
{CKA_PUBLIC_EXPONENT, &publicExponent, sizeof(publicExponent)}

Я не проверял ваш код, но я могу успешно получить модуль CK_OBJECT_HANDLE (закрытый ключ / открытый ключ), установив следующий шаблон и сделав вызов C_GetAttributeValue:

CK_BYTE         modulus[128];
CK_ATTRIBUTE    Modulus = { CKA_MODULUS, modulus, sizeof(modulus) };

if ((rv = (*p11FunctionList->C_GetAttributeValue)(hSession, hPrivKey /*hPubKey*/, &Modulus, 1)) == CKR_OK)
{
// do something with obtained modulus
}

Сгенерированная пара закрытый-открытый ключ была сгенерирована следующим образом:

CK_OBJECT_HANDLE    hPrivKey, hPubKey;
CK_BBOOL            bTrue   = TRUE;
CK_ULONG            mod_bits = 1024;
CK_MECHANISM        GenMechanism = { CKM_RSA_PKCS_KEY_PAIR_GEN, NULL_PTR, 0 };

CK_ATTRIBUTE        GenPubTemplate[] = {
{ CKA_MODULUS_BITS, &mod_bits, sizeof(CK_ULONG) },
{ CKA_PUBLIC_EXPONENT, "\x01\x00\x01", 3 },
{ CKA_TOKEN, &bTrue, sizeof(CK_BBOOL) },
{ CKA_ID, (CK_CHAR_PTR)szKeyID, strlen(szKeyID) } }; // szKeyID is a const char *

CK_ATTRIBUTE         GenPrivTemplate[] = {
{ CKA_TOKEN, &bTrue, sizeof(CK_BBOOL) },
{ CKA_PRIVATE, &bTrue, sizeof(CK_BBOOL) },
{ CKA_SENSITIVE, &bTrue, sizeof(CK_BBOOL) },
{ CKA_ID, (CK_CHAR_PTR)szKeyID, strlen(szKeyID) } }; // szKeyID is a const char *

// hSession is a CK_SESSION_HANDLE of an opened & logged in session
if ((rv = (*p11FunctionList->C_GenerateKeyPair)(hSession, &GenMechanism, GenPubTemplate, 4, GenPrivTemplate, 4, &hPubKey, &hPrivKey)) == CKR_OK)
{
// Now get the modulus of a the private / public key as described above
}
0

Хотя это уже было дано ответом для тех, кто хочет это сделать, мы создали оболочку на основе PKCS # 11 для CryptoAPI, вы можете найти ее здесь:

https://github.com/PeculiarVentures/pvpkcs11

При этом вы можете получить доступ к ключам, хранящимся в CryptoAPI, а также к сертификатам, используя собственные интерфейсы PKCS # 11.

0
По вопросам рекламы [email protected]