Как исправить метод C_GenerateKeyPair, возвращающий CKR_FUNCTION_FAILED

Я пытаюсь использовать библиотеку Pkcs11Interop, чтобы получить свой собственный сертификат от HSM (Safenet inc), когда я сгенерировал открытый/закрытый ключ, я получил ошибку «Метод C_GenerateKeyPair возвратил CKR_FUNCTION_FAILED»

Мой код

if (Net.Pkcs11Interop.Common.Platform.Uses64BitRuntime)
{
    loggerLibraryPath = @"C:\inetpub\wwwroot\ETPkcs11\ETPkcsII\libs\pkcs11-logger-x64.dll";
}
else
{
    loggerLibraryPath = @"C:\inetpub\wwwroot\ETPkcs11\ETPkcsII\libs\pkcs11-logger-x86.dll";
}
System.Environment.SetEnvironmentVariable("PKCS11_LOGGER_LIBRARY_PATH", pkcs11LibraryPath);
System.Environment.SetEnvironmentVariable("PKCS11_LOGGER_LOG_FILE_PATH", loogerLogFilePath);
System.Environment.SetEnvironmentVariable("PKCS11_LOGGER_FLAGS", "64");

if (System.IO.File.Exists(loogerLogFilePath))
{
    System.IO.File.Delete(loogerLogFilePath);
}

using (Pkcs11 pkcs11 = new Pkcs11(loggerLibraryPath, AppType.SingleThreaded))
{
    LibraryInfo libraryInfo = pkcs11.GetInfo();
    var aviSlot = pkcs11.GetSlotList(SlotsType.WithTokenPresent).Where(slot => slot.GetSlotInfo().SlotFlags.TokenPresent).FirstOrDefault();

    using (Session session = aviSlot.OpenSession(SessionType.ReadWrite))
    {
        // Login as normal user
        session.Login(CKU.CKU_USER, "xxxxxxxx");
        byte[] ckaId = session.GenerateRandom(20);

        // Prepare attribute template of new public key
        List<ObjectAttribute> publicKeyAttributes = new List<ObjectAttribute>();
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, false));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, Settings.ApplicationName));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY, true));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_VERIFY_RECOVER, true));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_WRAP, true));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_MODULUS_BITS, 1024));
        publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PUBLIC_EXPONENT, new byte[] { 0x01, 0x00, 0x01 }));

        // Prepare attribute template of new private key
        List<ObjectAttribute> privateKeyAttributes = new List<ObjectAttribute>();
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, Settings.ApplicationName));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SENSITIVE, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_DECRYPT, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SIGN, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_SIGN_RECOVER, true));
        privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_UNWRAP, true));

        // Specify key generation mechanism
        Mechanism mechanism = new Mechanism(CKM.CKM_RSA_PKCS_KEY_PAIR_GEN);

        // Generate key pair
        ObjectHandle publicKeyHandle = null;
        ObjectHandle privateKeyHandle = null;
        session.GenerateKeyPair(mechanism, publicKeyAttributes, privateKeyAttributes, out publicKeyHandle, out privateKeyHandle);

        // Do something interesting with generated key pair
        // Destroy keys
        session.DestroyObject(privateKeyHandle);
        session.DestroyObject(publicKeyHandle);

        session.Logout();
    }
}

Вот часть лога

0x00002478: 0x00001af8: атрибут 7
0x00002478: 0x00001AF8: атрибут: 265 (CKA_SIGN_RECOVE (01). 0x00001af8 : pValue: HEX(01)
0x00002478 : 0x00001af8 :
Конечный шаблон атрибута *
0x00002478 : 0x00001af8 : phPublicKey: 0643EA74
0x00002478 : 0 : 0afx08 *Phpubublickey: 0
0x00002478: 0x00001af8: phprivatekey: 0643ea70
0x00002478: 0x00001af8:*phprivatekey: 0
0x00002478: 0x00001af8: возвращение 6 (CKR_FUNCTION_FAILDED) *
0x00002478 : 0x0 0001AF8: Calling C_CLOSESESSION
0x00002478: 0x00001AF8: вход
0x00002478: 0x00001AF8: HSession: 2490369
0x00002478: 0x00001AF8: возвращение 0 (CKR_OK)
0x00002478: 0x001f8: 0x001f8: 0x001f8: 0x001f8: 0x. ********************* 22-03-2019 16:37:32 *
0x00002478 : 0x00001af8 : Вызов C_Finalize
0x00002478 : 0x00001af8 : Ввод
0x00002478 : 0x00001af8 : pReserved: 00000000
0x00002478 : 0x00001af8 : Возврат 0 (CKR_OK)


person Miracu    schedule 24.03.2019    source источник
comment
Пожалуйста, используйте правильное форматирование. если вы хотите, чтобы люди использовали свое свободное время для решения ВАШИХ проблем, то вам следует хотя бы уделить немного времени тому, чтобы облечь проблему в презентабельный вид. Правильные отступы и разрывы строк являются ключом к пониманию кода. вы просто бросаете это сюда, это грубо по отношению к людям, которые, как вы ожидаете, помогут вам. Я сделал работу, которую вы должны были сделать с самого начала.   -  person FalcoGer    schedule 24.03.2019
comment
Попробуйте создать объекты Public Key и Private Key с минимальной конфигурацией шаблона. Для начала просто установите атрибуты token, label и id в обоих шаблонах и посмотрите, сможете ли вы создать объекты пары ключей. Если вам удалось их создать, попробуйте установить другие атрибуты, которые могут вам понадобиться. К вашему сведению, объекты открытого и закрытого ключей могут быть связаны id, поэтому попробуйте использовать один и тот же идентификатор в обоих шаблонах.   -  person always_a_rookie    schedule 25.03.2019
comment
FalcoGer, спасибо за ваши предложения и исправления.   -  person Miracu    schedule 25.03.2019
comment
always_a_rookie_to_learn , Спасибо за совет, я пробовал, но все равно не получилось.   -  person Miracu    schedule 25.03.2019
comment
Рассмотрите возможность изучения атрибутов существующей пары ключей (сгенерированной официальным клиентом) и использования аналогичных значений. Альтернативный способ — использовать pkcs11-logger (с которым вы, похоже, уже знакомы) для регистрации шаблонов, используемых официальным клиентом при генерации пары ключей... Удачи!   -  person vlp    schedule 15.04.2019


Ответы (1)


К сожалению, API PKCS#11 не предоставляет никаких подробностей о том, почему функция C_GenerateKeyPair не удалась, но многие библиотеки PKCS#11 поддерживают какой-то внутренний механизм ведения журнала, который может выявить реальную причину ошибки. Точные шаги, необходимые для включения ведения журнала, должны присутствовать в документации, предоставленной поставщиком библиотеки PKCS#11.

person jariq    schedule 07.04.2019