We're trying to import an RSA key pair using C# and PKCS#11 into our HSM. Importing the private key using:
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);
Fails with the error code CKR_TEMPLATE_INCONSISTENT
. Unfortunately, it doesn't say what is inconsistent. I tried various other combinations of attributes and it always fails :-(
How to properly import the private key via PKCS#11?
Note: Importing the public key using very similar code works:
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);
Unfortunately PKCS#11 API does not provide details which exact attribute from supplied template caused the error but many PKCS#11 libraries support some kind of internal logging mechanism which may reveal the real cause of error. Exact steps needed to enable logging should be present in the documentation provided by the PKCS#11 library vendor.
My guess is that you're receiving
CKR_TEMPLATE_INCONSISTENT
because you are settingCKA_SENSITIVE
totrue
. Private key imported in plain form has already lost its "sensitivity" because it was exposed to an external environment. I'm successfully using following template in Pkcs11Interop.X509Store project:The answer is: you can't directly import a private key into a SafeNet Luna HSM. You have to first encrypt (wrap) the private key and can only then transfer it to the HSM. See PKCS#11 unwrap private key to HSM for an answer on how to do this.