Как установить / создать значение ключа для секретного ключа AES в сети Luna HSM?
При попытке создать секретный ключ; Мне сказали, что невозможно создать собственные значения ключей, и они должны быть сгенерированы / развернуты в HSM. Если это не так, я приложил обе попытки / методы на случай, если я что-то упустил. Любая помощь будет принята с благодарностью!
Окружающая среда: сеть Luna K6 5.1
Библиотека: PKCS11Interop.Net
Попытка 1: использование Create Object
Ошибка: CKR_TEMPLATE_INCONSISTENT
string keyLabel = "CustomSecretKey"
byte[] Value = HexStringToByteArray(value);
privateKey = new List<ObjectAttribute>
{
//PKCS11V2.20 Common Attributes Defined @ 12.12.2
new ObjectAttribute(CKA.CKA_LABEL, keyLabel),
new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY),
new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_AES),
new ObjectAttribute(CKA.CKA_TOKEN, true),
new ObjectAttribute(CKA.CKA_ENCRYPT, true),
new ObjectAttribute(CKA.CKA_PRIVATE, true),
new ObjectAttribute(CKA.CKA_DECRYPT, true),
new ObjectAttribute(CKA.CKA_VALUE_LEN, 32),
new ObjectAttribute(CKA.CKA_VALUE, Value)
};
session.CreateObject(privateKey);
Это, видимо, не поддерживается?
Попытка 2: использование ключа UnWrap
Ошибка: CKR_WRAPPED_KEY_INVALID
using (Pkcs11 pkcs11 = new Pkcs11(HSM.Instance.vendorDLLPath, AppType.MultiThreaded))
{
List<Slot> slots = pkcs11.GetSlotList(SlotsType.WithTokenPresent); //Checks to see what slots have token on them.
Slot slot = slots[HSM.Instance.activeSlot];
using (Session session = slot.OpenSession(SessionType.ReadWrite)) // Open RW session
{
session.Login(CKU.CKU_USER, HSM.Instance.loginPass); // Login as normal user
try
{
byte[] Value = HexStringToByteArray(value);
if (!string.IsNullOrEmpty(keyLabel))
{
List<ObjectAttribute> wrapKey = new List<ObjectAttribute>
{
new ObjectAttribute(CKA.CKA_LABEL, "TempWrapKey"),
new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY),
new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_AES),
new ObjectAttribute(CKA.CKA_TOKEN, true),
new ObjectAttribute(CKA.CKA_PRIVATE, true),
new ObjectAttribute(CKA.CKA_ENCRYPT, true),
new ObjectAttribute(CKA.CKA_DECRYPT, true),
new ObjectAttribute(CKA.CKA_SENSITIVE, true),
new ObjectAttribute(CKA.CKA_VERIFY, true),
new ObjectAttribute(CKA.CKA_SIGN, true),
new ObjectAttribute(CKA.CKA_WRAP, true),
new ObjectAttribute(CKA.CKA_UNWRAP, true),
new ObjectAttribute(CKA.CKA_DERIVE, false),
new ObjectAttribute(CKA.CKA_EXTRACTABLE, false),
new ObjectAttribute(CKA.CKA_VALUE_LEN, 32)
};
ObjectHandle WrappingKey = session.GenerateKey(new Mechanism(CKM.CKM_AES_KEY_GEN), wrapKey);
byte[] keyValueBytes = session.Encrypt(new Mechanism(CKM.CKM_AES_ECB), WrappingKey, Value);
List<ObjectAttribute> privateKeyAttributes = new List<ObjectAttribute>
{
new ObjectAttribute(CKA.CKA_LABEL, keyLabel),
new ObjectAttribute(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY),
new ObjectAttribute(CKA.CKA_KEY_TYPE, CKK.CKK_AES),
new ObjectAttribute(CKA.CKA_TOKEN, true),
new ObjectAttribute(CKA.CKA_PRIVATE, true),
new ObjectAttribute(CKA.CKA_ENCRYPT, true),
new ObjectAttribute(CKA.CKA_DECRYPT, true),
new ObjectAttribute(CKA.CKA_SENSITIVE, true),
new ObjectAttribute(CKA.CKA_VERIFY, true),
new ObjectAttribute(CKA.CKA_SIGN, true),
new ObjectAttribute(CKA.CKA_WRAP, true),
new ObjectAttribute(CKA.CKA_UNWRAP, true),
new ObjectAttribute(CKA.CKA_DERIVE, false),
new ObjectAttribute(CKA.CKA_EXTRACTABLE, false),
new ObjectAttribute(CKA.CKA_VALUE_LEN, 32)
};
session.UnwrapKey(new Mechanism(CKM.CKM_AES_ECB), WrappingKey, keyValueBytes, privateKeyAttributes);
session.DestroyObject(WrappingKey);
response.ErrorText = "Key Created?";
Журналы попытки 2:
12:02:28 03696-5152:STRTOpenSession {Slot=1 Flgs=6 }
12:02:28 03696-5152:FINIOpenSession CKR_OK(1609ms) {Sesn=1 }
12:02:28 03696-5152:STRTLogin {Sesn=1 User=1 PIN="********" }
12:02:28 03696-5152:FINILogin CKR_OK(1734ms) {}
12:02:28 03696-5152:STRTGenerateKey {Sesn=1 Mech=(CKM_AES_KEY_GEN,"") AttrList={CKA_CLASS="04000000" CKA_KEY_TYPE="1f000000" CKA_TOKEN="01" CKA_ENCRYPT="01" CKA_LABEL="TempWrapKey" CKA_CLASS="04000000" CKA_KEY_TYPE="1f000000" CKA_TOKEN="01" CKA_ENCRYPT="01" CKA_PRIVATE="01" CKA_DECRYPT="01" CKA_VALUE_LEN="20000000" CKA_WRAP="01" CKA_UNWRAP="01" CKA_SENSITIVE="01" CKA_SIGN="01" CKA_DERIVE="00" CKA_EXTRACTABLE="00" } }
12:02:29 03696-5152:FINIGenerateKey CKR_OK(1750ms) {Obj=2000001 }
12:02:29 03696-5152:STRTEncrypt_Init {Sesn=1 Mech=(CKM_AES_ECB,"") Obj=2000001 }
12:02:29 03696-5152:FINIEncrypt_Init CKR_OK(1750ms) {}
12:02:29 03696-5152:STRTEncrypt {Sesn=1 "23724cf301e85a53fc3f5aea6384c16e" pusEncryptedDataLen=0xf91ddca0 *pusEncryptedDataLen=0 }
12:02:29 03696-5152:FINIEncrypt CKR_OK(1750ms) {"" pusEncryptedDataLen=0xf91ddca0 *pusEncryptedDataLen=16 }
12:02:29 03696-5152:STRTEncrypt {Sesn=1 "23724cf301e85a53fc3f5aea6384c16e" pusEncryptedDataLen=0xf91ddca0 *pusEncryptedDataLen=16 }
12:02:29 03696-5152:FINIEncrypt CKR_OK(1750ms) {"2e151cc889470864b5fb5a24146fecb2" pusEncryptedDataLen=0xf91ddca0 *pusEncryptedDataLen=16 }
12:02:29 03696-5152:STRTUnwrapKey {Sesn=1 Mech=(CKM_AES_ECB,"") Obj=2000001 "2e151cc889470864b5fb5a24146fecb2" AttrList={CKA_LABEL="Key2372" CKA_CLASS="04000000" CKA_KEY_TYPE="1f000000" CKA_TOKEN="01" CKA_PRIVATE="01" CKA_ENCRYPT="01" CKA_DECRYPT="01" CKA_SENSITIVE="01" CKA_VERIFY="01" CKA_SIGN="01" CKA_WRAP="01" CKA_UNWRAP="01" CKA_DERIVE="00" CKA_EXTRACTABLE="00" CKA_VALUE_LEN="20000000" } }
12:02:29 03696-5152:FINIUnwrapKey ***CKR_WRAPPED_KEY_INVALID***(1750ms) {Obj=0 }
12:02:29 03696-5152:STRTCloseSession {Sesn=1 }
12:02:29 03696-5152:FINICloseSession CKR_OK(1765ms) {}
Должен ли я генерировать другой ключ и использовать его для распаковки?
1 ответ
Обновление: в пример добавлена функция GenerateKeyPair.
Мне удалось "загрузить" ключ AES в HSM с помощью следующего кода:
// Create factories used by Pkcs11Interop library
Pkcs11InteropFactories factories = new Pkcs11InteropFactories();
// Load unmanaged PKCS#11 library
using (IPkcs11Library pkcs11Library = factories.Pkcs11LibraryFactory.LoadPkcs11Library(factories, options.PKCS11LibraryPath, AppType.SingleThreaded))
{
// Find first slot with token present
ISlot slot = pkcs11Library.GetSlotList(SlotsType.WithTokenPresent)[0];
// Open RW session
using (ISession session = slot.OpenSession(SessionType.ReadWrite))
{
// Login as normal user
session.Login(CKU.CKU_USER, options.Pin);
// Generate asymmetric key encryption key pair
IObjectHandle asymKeyEncrpytionPublicKey = null;
IObjectHandle asymKeyEncryptionPrivateKey = null;
Helpers.GenerateKeyPair(session, out asymKeyEncrpytionPublicKey, out asymKeyEncryptionPrivateKey, "KEK");
// Load aes key from file
// Generate the key with the following command: "openssl rand -out aes256-forImport.key 32"
byte[] sourceKey = File.ReadAllBytes(options.aesKeyPath);
Console.WriteLine($"Loaded AES key: {BitConverter.ToString(sourceKey)}");
// Specify wrapping mechanism
IMechanism asymMechanism = session.Factories.MechanismFactory.Create(CKM.CKM_RSA_PKCS);
// Encrypt key in file
byte[] encryptedKey = session.Encrypt(asymMechanism, asymKeyEncrpytionPublicKey, sourceKey);
// Define attributes for unwrapped key
List<IObjectAttribute> objectAttributes = new List<IObjectAttribute>();
objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_CLASS, CKO.CKO_SECRET_KEY));
objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_KEY_TYPE, CKK.CKK_AES));
objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ENCRYPT, true));
objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_DECRYPT, true));
objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_EXTRACTABLE, options.markExtractable));
objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true));
objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_LABEL, $"Unwrapped at {DateTime.Now}"));
// Symmetric unwrap key
IObjectHandle symUnwrappedKey = session.UnwrapKey(asymMechanism, asymKeyEncryptionPrivateKey, encryptedKey, objectAttributes);
}
}
-----
/// <summary>
/// Generates asymetric key pair.
/// </summary>
/// <param name='session'>Read-write session with user logged in</param>
/// <param name='publicKeyHandle'>Output parameter for public key object handle</param>
/// <param name='privateKeyHandle'>Output parameter for private key object handle</param>
public static void GenerateKeyPair(ISession session, out IObjectHandle publicKeyHandle, out IObjectHandle privateKeyHandle, string label = "")
{
// The CKA_ID attribute is intended as a means of distinguishing multiple key pairs held by the same subject
byte[] ckaId = session.GenerateRandom(20);
// Prepare attribute template of new public key
List<IObjectAttribute> publicKeyAttributes = new List<IObjectAttribute>();
////publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PRIVATE, false));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_LABEL, $"{label} public"));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ID, ckaId));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ENCRYPT, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_VERIFY, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_VERIFY_RECOVER, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_WRAP, true));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_MODULUS_BITS, 2048));
publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PUBLIC_EXPONENT, new byte[] { 0x01, 0x00, 0x01 }));
// Prepare attribute template of new private key
List<IObjectAttribute> privateKeyAttributes = new List<IObjectAttribute>();
////privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PRIVATE, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_LABEL, $"{label} private"));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ID, ckaId));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SENSITIVE, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_DECRYPT, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SIGN, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SIGN_RECOVER, true));
privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_UNWRAP, true));
// Specify key generation mechanism
IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_RSA_PKCS_KEY_PAIR_GEN);
// Generate key pair
session.GenerateKeyPair(mechanism, publicKeyAttributes, privateKeyAttributes, out publicKeyHandle, out privateKeyHandle);
}
По-видимому, после разговора с Gemalto и нескольких комментариев это нельзя сделать на семействе сетевых HSM, не защищающем сервер. Этот процесс отлично работает для HSM защищающего сервера (теперь у них есть защищенный сетевой сервер HSM). После обновления моего процесса развертывания для использования режима CBC с IV, я смог создать ключи, но не с указанными значениями ключей.