带有 PKCS11Interop 的 AWS CloudHSM PKCS#11 为 Wrap 操作提供错误 CKR_ARGUMENTS_BAD

AWS CloudHSM PKCS#11 with PKCS11Interop giving error for Wrap operation CKR_ARGUMENTS_BAD

我正在使用最新的 AWS 云 HSM,并且有 PKCS 供应商库和 PKCS11Interop c# 库。
尝试从 AWS PKCS Samples

中模拟 CKM.CKM_RSA_AES_KEY_WRAP 的示例代码

包装 AES 256 密钥时出现以下错误。

Net.Pkcs11Interop.Common.Pkcs11Exception: 'Method C_WrapKey returned CKR_ARGUMENTS_BAD' at Net.Pkcs11Interop.HighLevelAPI80.Session.WrapKey(IMechanism mechanism, IObjectHandle wrappingKeyHandle, IObjectHandle keyHandle)

我的示例代码

    public ActionResult<string> WrapUnwrap(string keyAlias)
        {
            using (IPkcs11Library pkcs11Library = Settings.Factories.Pkcs11LibraryFactory.LoadPkcs11Library(Settings.Factories, Settings.Pkcs11LibraryPath, Settings.AppType))
            {
                // Find first slot with token present
                ISlot slot = Helpers.GetUsableSlot(pkcs11Library);

                // Open RW session
                using (ISession session = slot.OpenSession(SessionType.ReadWrite))
                {
                    // Login as normal user
                    session.Login(CKU.CKU_USER, Settings.NormalUserPin);

                    // Generate asymetric key pair
                    IObjectHandle publicKey = null;
                    IObjectHandle privateKey = null;
                    GenerateRSAKeyPair(session, out publicKey, out privateKey);

                    //Generate symmetric key : AES 256
                    var keyToWrap = GenerateAESKey(session);

                    // Specify wrapping mechanism
                    var oaepParams = session.Factories.MechanismParamsFactory.CreateCkRsaPkcsOaepParams(
                                                        ConvertUtils.UInt64FromCKM(CKM.CKM_SHA256),
                                                        ConvertUtils.UInt64FromCKG(CKG.CKG_MGF1_SHA256),
                                                        ConvertUtils.UInt64FromUInt32(CKZ.CKZ_DATA_SPECIFIED),
                                                        null);

                    var rsaParams = session.Factories.MechanismParamsFactory.CreateCkRsaAesKeyWrapParams(256, oaepParams);
                    IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_RSA_AES_KEY_WRAP);

                    // Wrap key
                    byte[] wrappedKey = session.WrapKey(mechanism, publicKey, keyToWrap);
                    if (wrappedKey == null)
                        throw new Exception("Failed to wrap key.");


                    // 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, true));

                    // Unwrap key
                    IObjectHandle unwrappedKey = session.UnwrapKey(mechanism, privateKey, wrappedKey, objectAttributes);


                    session.DestroyObject(privateKey);
                    session.DestroyObject(publicKey);
                    session.DestroyObject(keyToWrap);
                    session.DestroyObject(unwrappedKey);

                    session.Logout();
                }
            }
            return Ok();
        }



    private static void GenerateRSAKeyPair(ISession session, out IObjectHandle publicKeyHandle, out IObjectHandle privateKeyHandle)
        {
            // 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)); // Throws InvalidAttribute Value
            publicKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ID, ckaId));
            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_ID, ckaId));
            privateKeyAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_UNWRAP, true));

            // Specify key generation mechanism
            IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_RSA_X9_31_KEY_PAIR_GEN);

            // Generate key pair
            session.GenerateKeyPair(mechanism, publicKeyAttributes, privateKeyAttributes, out publicKeyHandle, out privateKeyHandle);
        }

private static IObjectHandle GenerateAESKey(ISession session, string keyAlias = null)
        {
            byte[] ckaId = null;
            if (string.IsNullOrEmpty(keyAlias))
                ckaId = session.GenerateRandom(20);
            else
                ckaId = Encoding.UTF8.GetBytes(keyAlias);

            // Generate symetric key
            // Prepare attribute template of new 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_VALUE_LEN, 32));// means 256 bit
            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_PRIVATE, true));
            objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_EXTRACTABLE, true));         
            objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_ID, ckaId));       
            //objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_WRAP_WITH_TRUSTED, false));
            objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_DESTROYABLE, true));         
            objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_TOKEN, true));
            //objectAttributes.Add(session.Factories.ObjectAttributeFactory.Create(CKA.CKA_SIGN, false));

            // Specify key generation mechanism
            IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_AES_KEY_GEN);

            // Generate key
            IObjectHandle generatedKey = session.GenerateKey(mechanism, objectAttributes);

            return generatedKey;
        } 

我做的一切都很好,只是忘了在调用时发送初始化的 rsaParams。

IMechanism mechanism = session.Factories.MechanismFactory.Create(CKM.CKM_RSA_AES_KEY_WRAP,rsaParams);