使用PKCS#11导入私钥

时间:2018-12-12 11:14:24

标签: c# rsa pkcs#11 pkcs11interop

我们正在尝试使用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);

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

答案 2 :(得分:0)

不幸的是,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())
};
相关问题