I've learned that I cannot simply transfer a private key to my HSM via PKCS#11, I need to wrap it first and then unwrap it on the HSM. So I temporarily create a DES3 key on our HSM, then I'd like to wrap (encrypt) my RSA private key with it, then I want to unwrap it on the HSM.
My code looks like this:
// Create temporary DES3 key for wrapping/unwrapping
var tempKeyAttributes = new List<ObjectAttribute>();
tempKeyAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));
tempKeyAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_DES3));
tempKeyAttributes.Add(new ObjectAttribute(CKA.CKA_ENCRYPT, true));
tempKeyAttributes.Add(new ObjectAttribute(CKA.CKA_UNWRAP, true));
var tempKey = session.GenerateKey(new Mechanism(CKM.CKM_DES3_KEY_GEN), tempKeyAttributes);
// Encrypt (wrap) the RSA private key
var encryptedPrivateKeyParamsD = session.Encrypt(new Mechanism(CKM.CKM_DES3_ECB), tempKey, privateKeyParams.D);
// Define how the new RSA private key should look like on the HSM
var privateKeyAttributes = new List<ObjectAttribute>();
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_PRIVATE_KEY));
privateKeyAttributes.Add(new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_RSA));
[...]
// Unwrap the private key onto the HSM
var privateKeyHandle = session.UnwrapKey(new Mechanism(CKM.CKM_DES3_ECB), tempKey, encryptedPrivateKeyParamsD, privateKeyAttributes);
This doesn't work, it fails with CKR_INVALID_MECHANISM
.
I'm pretty sure the problem is encryptedPrivateKeyParamsD
, I should somehow encrypt the whole key instead. But how to? What is the correct format? I can't find anything in the docs about it :-(
Any ideas how to fix this? I simply want to put an existing RSA private key programmatically onto our HSM using PKCS#11.
I've found the answer: the format which must be used on SafeNet Luna HSM is PKCS#8 in binary DER encoding. I used BouncyCastle to bring my input data into the correct format: