【问题标题】:How to fix method C_GenerateKeyPair returned CKR_FUNCTION_FAILED如何修复方法 C_GenerateKeyPair 返回 CKR_FUNCTION_FAILED
【发布时间】:2019-03-24 19:12:13
【问题描述】:

当我生成公钥/私钥时,我正在尝试使用 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_RECOVER)
0x00002478:0x00001af8:pValue:0597E850
0x00002478:0x00001af8:ulValueLen:1
0x00002478 : 0x00001af8 : *pValue: HEX(01)
0x00002478 : 0x00001af8 : 属性 8
0x00002478:0x00001af8:属性:263 (CKA_UNWRAP)
0x00002478:0x00001af8:pValue:0597E830
0x00002478:0x00001af8:ulValueLen:1
0x00002478 : 0x00001af8 : pValue: HEX(01)
0x00002478 : 0x00001af8 :
结束属性模板 *
0x00002478:0x00001af8:phPublicKey:0643EA74
0x00002478 : 0x00001af8 : *phPublicKey: 0
0x00002478:0x00001af8:phPrivateKey:0643EA70
0x00002478 : 0x00001af8 : *phPrivateKey: 0
0x00002478 : 0x00001af8 : 返回 6 (CKR_FUNCTION_FAILED)
0x00002478:0x00001af8:****************************** 2019-03-22 16:37:32 *
0x00002478 : 0x00001af8 : 调用 C_CloseSession
0x00002478:0x00001af8:输入
0x00002478:0x00001af8:hSession:2490369
0x00002478 : 0x00001af8 : 返回 0 (CKR_OK)
0x00002478:0x00001af8:****************************** 2019-03-22 16:37:32 *
0x00002478 : 0x00001af8 : 调用 C_Finalize
0x00002478:0x00001af8:输入
0x00002478:0x00001af8:保留:00000000
0x00002478 : 0x00001af8 : 返回 0 (CKR_OK)

【问题讨论】:

  • 请使用正确的格式。如果您希望人们利用他们的空闲时间来解决您的问题,那么您至少应该花一些时间将问题转化为可呈现的形式。正确的缩进和换行是理解代码的关键。你把它扔在这里是对你希望帮助你的人的粗鲁。我已经完成了你一开始就应该完成的工作。
  • 尝试使用极少的模板配置创建Public KeyPrivate Key 对象。首先,只需在两个模板中设置tokenlabelid 属性,然后查看是否能够创建密钥对对象。如果您能够成功创建它们,请尝试设置您可能需要的其他属性。仅供参考,公钥和私钥对象可能由 id 关联,因此请尝试在两个模板中使用相同的 id。
  • FalcoGer,感谢您的建议和更正。
  • always_a_rookie_to_learn ,谢谢你的建议 我试过了但还是没有成功。
  • 考虑检查现有密钥对的属性(由官方客户端生成)并使用类似的值。另一种方法是使用 pkcs11-logger(您似乎已经熟悉)记录官方客户端在生成密钥对期间使用的模板...祝您好运!

标签: c# .net pkcs#11 pkcs11interop


【解决方案1】:

如果面对CKR_FUNCTION_FAILED,请检查使用的别名。如果有多个别名,则一一检查并传递给keystore。

【讨论】:

    【解决方案2】:

    不幸的是,PKCS#11 API 没有提供任何关于为什么C_GenerateKeyPair 函数失败的详细信息,但是许多 PKCS#11 库支持某种内部日志记录机制,这可能会揭示错误的真正原因。启用日志记录所需的确切步骤应包含在 PKCS#11 库供应商提供的文档中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多