使用Pkcs11Interop在Thales Luna HSM中解包的AES密钥无法持久化
问题描述
在.NET应用中使用Pkcs11Interop库与Thales Luna HSM通信,采用CKM_RSA_PKCS机制通过RSA密钥解包AES密钥。解包操作成功返回密钥句柄,且可在同一会话中用该密钥加密数据,但解包后的AES密钥并未持久化到HSM中。请问是否遗漏了相关参数?
代码片段
private void keyUnwrap() { string wrappedKey = "81C6CAD32431D506113CB07A515422ED55779CEE8B8A927C9898496F3209EC115EACAE2F59673A5F1423C6878A99FAD68E9741876A2605B2969953918BB9F6D15A4120A12F69EB2C752E8634B11ABB8FD709C072765361A0FAD7877CC3B8A78F500B4E3C8107BBDBE2DB0E82061EFB6E9FC885CAC5D0575324350D2FCAA08C89401F3B6ABEFA425A922A6A0F9FD2F61FCF37DDF9F7BF918B7C2C9228F033AC3EC2F35561FA0F7D397245CC37B2BEEDFB8028A0249DB8A7D13B22384C474629473FF153BAEEA06659F2A1B521066CB39835C7B3F18D7D33249834AC9667718564A2F8E46AA40A9EB7DFC365BA9C5A784599A2D99BD2F4E1462C849E2ED54D448B"; List<ISlot> allSlots = pkcs11Library.GetSlotList(SlotsType.WithTokenPresent); using (ISession session = slot[0].OpenSession(SessionType.ReadWrite)) { // Login as normal user session.Login(CKU.CKU_USER, "CO_PIN"); // get private key object IObjectHandle privateKey = findObject(session, CKO.CKO_PRIVATE_KEY, "Wrapping_RSA_Key_Pair_PRV"); // Specify wrapping mechanism IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_RSA_PKCS); // 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_LABEL, "Unwrapped_AES_Key")); // Unwrap key IObjectHandle unwrappedKey = session.UnwrapKey(mechanism, privateKey, StringToByteArray(wrappedKey), objectAttributes); IObjectHandle newkey = findObject(session, CKO.CKO_SECRET_KEY, "Unwrapped_AES_Key"); if (newkey == null) { throw new Exception("Unwrapped object not found."); } } } private IObjectHandle findObject(ISession session, CKO objectClass, string label) { // Prepare attribute template that defines search criteria List<IObjectAttribute> objectAttributes = new List<IObjectAttribute>(); objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_CLASS, objectClass)); objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_LABEL, label)); // Initialize searching session.FindObjectsInit(objectAttributes); // Get search results List<IObjectHandle> foundObjects = session.FindObjects(1); // Terminate searching session.FindObjectsFinal(); if (foundObjects.Count > 0) { return foundObjects[0]; } return null; } public static byte[] StringToByteArray(string hex) { return Enumerable.Range(0, hex.Length) .Where(x => x % 2 == 0) .Select(x => Convert.ToByte(hex.Substring(x, 2), 16)) .ToArray(); }
问题解答
核心原因
默认情况下,UnwrapKey创建的是会话临时密钥——仅在当前会话内有效,会话关闭后自动销毁,不会持久化到HSM令牌中。你遗漏了CKA_TOKEN属性,该属性用于指定密钥是否存储为HSM上的持久化令牌对象。
修复方案
在定义解包密钥的属性列表时,添加CKA_TOKEN属性并设置为true,同时建议补充CKA_PRIVATE属性增强安全性:
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_LABEL, "Unwrapped_AES_Key")); // 关键:标记密钥为持久化令牌对象 objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true)); // 可选:设置密钥为私有,仅当前用户可见 objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_PRIVATE, true));
补充说明
CKA_TOKEN=true:将密钥从会话临时对象转为HSM令牌持久化对象,会话关闭后仍保留在HSM中;默认false为会话临时对象。CKA_PRIVATE=true:限制密钥仅对创建它的用户可见,避免其他用户未经授权访问,提升安全性。- 权限检查:确保当前登录的HSM用户拥有创建持久化密钥的权限,权限不足会导致操作失败。
内容的提问来源于stack exchange,提问作者IuR
相关产品推荐
相关产品推荐

