Извлечение или установка параметров закрытого ключа в библиотеке криптоки

Я столкнулся с некоторыми проблемами при написании небольшой тестовой программы с использованием библиотеки 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 ответ

Ваша идея сгенерировать пару ключей, а затем прочитать их, в порядке, однако вы должны установить атрибут CKA_SENSITIVE false в шаблоне закрытого ключа. Обратите внимание, что всегда зависит от самого токена, если такая функциональность поддерживается.

Обычно при извлечении информации личного ключа из токена вы хотите, чтобы он был зашифрован. Шифрование ключей называется упаковкой, и возможным извлечением конфиденциальной информации управляет CKA_EXTRACTABLE приписывать.

После прочтения я конвертирую их из ASCII в шестнадцатеричное представление и сохраняю их в CK_BYTE[].

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

Другие вопросы по тегам