【问题标题】:How to Set/Create a Key Value for AES Secret Key on Network Luna HSM?如何在 Network Luna HSM 上设置/创建 AES 密钥的密钥值?
【发布时间】:2018-08-30 19:17:50
【问题描述】:

尝试创建密钥时;我被告知不可能创建自己的键值,它们必须在 HSM 上生成/解包。如果这不是真的,我已经附上了两种尝试/方法,以防我遗漏了一些东西。任何帮助将不胜感激!

环境: Network Luna K6 5.1

库: PKCS11Interop.Net

尝试 1:使用创建对象

错误: 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) {}

我应该生成另一个密钥并使用它来解包吗?

【问题讨论】:

  • 你能显示变量keyLabelValue的类型和值吗?
  • 在第二次尝试中,您首先创建密钥,然后解包到它。如果我没记错的话,密钥会自动创建;无需提前指定/创建密钥对象。请注意,在第二次尝试中,模板中有很多重复的字段。这并没有显示处理加密所需的精度。
  • 对不起,我已经为 keyLabel 和 Value 添加了类型和值。该值由用户创建为十六进制值。不小心发布了测试属性和尝试的创建密钥对象,现在上面的那些已经更新并与下面的日志语句匹配,再次抱歉。重复项会引发不同的错误,并且同意不够精确,无法处理一致的模板:) 至于创建键方法,我认为首先创建对象并让展开函数用展开的值键覆盖无值键。这行不通。
  • 在您的尝试 2 中,您是否厌倦了在解包之前使用带有 IV 的 CBC 模式加密密钥?
  • 在展开之前使用带有 IV 的 CBC 模式就可以了。谢谢@always_a_rookie_to_learn!我确定我以后必须更改属性以检查密钥值,但我注意到当我对两个新密钥使用相同的密钥值时,它们似乎至少与加密和解密的文本不匹配网络 HSM。关于为什么会这样的任何想法?

标签: c# cryptography pkcs#11 hsm pkcs11interop


【解决方案1】:

显然,在与金雅拓和几个 cmets 交谈后,这无法在非保护服务器系列的网络 HSM 上完成。该过程非常适用于保护服务器 HSM(他们现在有一个保护服务器网络 HSM)。在更新我的解包过程以使用带有 IV 的 CBC 模式后,我能够创建键但不能使用指定的键值..

【讨论】:

    【解决方案2】:

    更新:在示例中添加了 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);
            }
    
    

    【讨论】:

    • 能否请您发布 Helpers.GenerateKeyPair(session, out asymKeyEncrpytionPublicKey, out asymKeyEncryptionPrivateKey, "KEK");尝试相同,我得到以下机制错误:CKM_RSA_X9_31_KEY_PAIR_GEN C_GenerateKeyPair failed with error CKR_ATTRIBUTE_VALUE_INVALID : 0x00000013
    猜你喜欢
    • 1970-01-01
    • 2018-05-13
    • 1970-01-01
    • 1970-01-01
    • 2017-02-05
    • 2018-05-31
    • 1970-01-01
    • 2017-04-16
    • 2016-06-11
    相关资源
    最近更新 更多