【问题标题】:Import a private key using PKCS#11使用 PKCS#11 导入私钥
【发布时间】:2018-12-12 11:14:24
【问题描述】:

我们正在尝试将使用 C# 和 PKCS#11 的 RSA 密钥对导入我们的 HSM。使用以下方式导入私钥:

    var privateKeyAttributes = new List<ObjectAttribute>();
    privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
    privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, ckaId));
    privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
    privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_RSA));
    privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
    privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, true));
    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));
    privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_MODULUS, privateKeyParams.Modulus));
    privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE_EXPONENT, privateKeyParams.D));
    var privateKeyHandle = session.CreateObject(privateKeyAttributes);

失败,错误代码CKR_TEMPLATE_INCONSISTENT。不幸的是,它没有说明不一致的地方。我尝试了各种其他属性组合,但总是失败:-(

如何通过PKCS#11正确导入私钥?


注意:使用非常相似的代码导入公钥:

    var publicKeyAttributes = new List<ObjectAttribute>();
    publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ID, ckaId));
    publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_LABEL, ckaId));
    publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PUBLIC_KEY));
    publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_RSA));
    publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_TOKEN, true));
    publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PRIVATE, true));
    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, publicKeyParams.Modulus));
    publicKeyAttributes.Add(new ObjectAttribute(CKA.CKA_PUBLIC_EXPONENT, publicKeyParams.Exponent));
    var publicKeyHandle = session.CreateObject(publicKeyAttributes);

【问题讨论】:

  • 真的不能像这样直接导入私钥,而必须对其进行包装/解包吗?
  • 这取决于 HSM 供应商。但是,是的,大多数供应商不允许将密钥(秘密/私有)从软件直接导入 HSM。它必须被包装和打开。
  • 你知道如何导入 RSA 私钥吗?我只找到了导入密钥(只是一个字节 blob)的示例。一个 RSA 私钥由多个 blob 组成,我不知道如何将其解包到 HSM 上。
  • 私钥也可以提取为单个 blob。你需要看看如何在 c# 中做到这一点。
  • 是的,但是 PKCS#11 需要哪种格式来解开密钥?

标签: c# rsa pkcs#11 pkcs11interop


【解决方案1】:

答案是:您不能直接将私钥导入 SafeNet Luna HSM。您必须首先加密(包装)私钥,然后才能将其传输到 HSM。有关如何执行此操作的答案,请参阅 PKCS#11 unwrap private key to HSM

【讨论】:

    【解决方案2】:

    试试“CKA_PRIVATE = false”: 新的 ObjectAttribute(CKA.CKA_PRIVATE, false)

    【讨论】:

      【解决方案3】:

      不幸的是,PKCS#11 API 没有提供来自提供的模板的确切属性导致错误的详细信息,但是许多 PKCS#11 库支持某种内部日志记录机制,这可能会揭示错误的真正原因。启用日志记录所需的确切步骤应包含在 PKCS#11 库供应商提供的文档中。

      我的猜测是您收到CKR_TEMPLATE_INCONSISTENT,因为您将CKA_SENSITIVE 设置为true。以明文形式导入的私钥已经失去了“敏感性”,因为它暴露在外部环境中。我在 Pkcs11Interop.X509Store 项目中成功使用了以下template

      var privateKeyAttributes = new List<ObjectAttribute>()
      {
          new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY),
          new ObjectAttribute(CKA.CKA_TOKEN, true),
          new ObjectAttribute(CKA.CKA_PRIVATE, true),
          new ObjectAttribute(CKA.CKA_MODIFIABLE, true),
          new ObjectAttribute(CKA.CKA_LABEL, ...),
          new ObjectAttribute(CKA.CKA_ID, ...),
          new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_RSA),
          new ObjectAttribute(CKA.CKA_MODULUS, rsaPrivKeyParams.Modulus.ToByteArrayUnsigned()),
          new ObjectAttribute(CKA.CKA_PUBLIC_EXPONENT, rsaPrivKeyParams.PublicExponent.ToByteArrayUnsigned()),
          new ObjectAttribute(CKA.CKA_PRIVATE_EXPONENT, rsaPrivKeyParams.Exponent.ToByteArrayUnsigned()),
          new ObjectAttribute(CKA.CKA_PRIME_1, rsaPrivKeyParams.P.ToByteArrayUnsigned()),
          new ObjectAttribute(CKA.CKA_PRIME_2, rsaPrivKeyParams.Q.ToByteArrayUnsigned()),
          new ObjectAttribute(CKA.CKA_EXPONENT_1, rsaPrivKeyParams.DP.ToByteArrayUnsigned()),
          new ObjectAttribute(CKA.CKA_EXPONENT_2, rsaPrivKeyParams.DQ.ToByteArrayUnsigned()),
          new ObjectAttribute(CKA.CKA_COEFFICIENT, rsaPrivKeyParams.QInv.ToByteArrayUnsigned())
      };
      

      【讨论】:

      • 在没有 CKA_SENSITIVE 的情况下尝试过 -> 没有成功。甚至完全尝试了您的模板->没有成功。
      • @D.R.请按照 SafeNet 文档中的说明启用日志记录并浏览/共享日志。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      相关资源
      最近更新 更多