使用 PKCS#11 导入私钥
Import a private key using PKCS#11
我们正在尝试使用 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 正确导入私钥?
注意:使用非常相似的代码导入 public 密钥:
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);
不幸的是,PKCS#11 API 没有提供详细信息,提供的模板中的确切属性导致了错误,但许多 PKCS#11 库支持某种内部日志记录机制,这可能会揭示错误的真正原因。 PKCS#11 库供应商提供的文档中应包含启用日志记录所需的确切步骤。
我猜您收到 CKR_TEMPLATE_INCONSISTENT
是因为您将 CKA_SENSITIVE
设置为 true
。以明文形式导入的私钥已经丢失 "sensitivity" 因为它暴露在外部环境中。我在 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())
};
答案是:您不能直接将私钥导入 SafeNet Luna HSM。您必须先加密(包装)私钥,然后才能将其传输到 HSM。有关如何执行此操作的答案,请参阅 。
尝试"CKA_PRIVATE = false":
新的 ObjectAttribute(CKA.CKA_PRIVATE, false)
我们正在尝试使用 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 正确导入私钥?
注意:使用非常相似的代码导入 public 密钥:
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);
不幸的是,PKCS#11 API 没有提供详细信息,提供的模板中的确切属性导致了错误,但许多 PKCS#11 库支持某种内部日志记录机制,这可能会揭示错误的真正原因。 PKCS#11 库供应商提供的文档中应包含启用日志记录所需的确切步骤。
我猜您收到 CKR_TEMPLATE_INCONSISTENT
是因为您将 CKA_SENSITIVE
设置为 true
。以明文形式导入的私钥已经丢失 "sensitivity" 因为它暴露在外部环境中。我在 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())
};
答案是:您不能直接将私钥导入 SafeNet Luna HSM。您必须先加密(包装)私钥,然后才能将其传输到 HSM。有关如何执行此操作的答案,请参阅
尝试"CKA_PRIVATE = false": 新的 ObjectAttribute(CKA.CKA_PRIVATE, false)