/// <summary>
        ///     N-level encryption of existing onion ctor
        /// </summary>
        public PublicKeyEncryptionOnion(PublicKeyEncryptionOnion innerOnion, string asymmetricThumbprint)
        {
            Mandate.That(innerOnion, nameof(innerOnion)).IsNotNull();
            Mandate.That(asymmetricThumbprint, nameof(asymmetricThumbprint)).IsNotNullOrEmpty();


            AsymmetricThumbprint = asymmetricThumbprint;
            InnerOnion           = innerOnion.Clone();
            // allocate a new object so we're self contained and the calling code can do whatever it wants with the parameter object
            InnerOnion.AsymmetricEncryptedKey = null;

            using (var aes = new AESCryptoAgent())
                using (var rsa = new RSACryptoAgent(asymmetricThumbprint))
                {
                    // generate the aes key and use it to re-encrypt the original key
                    var symmetricKey = aes.GenerateKey();
                    SymmetricAlgorithmIV   = aes.GenerateIV();
                    SymmetricEncryptedData = aes.Encrypt(innerOnion.AsymmetricEncryptedKey, symmetricKey,
                                                         SymmetricAlgorithmIV);

                    // encrypt the aes key with the public key
                    AsymmetricEncryptedKey = rsa.Encrypt(symmetricKey);
                }

            // even though we're not using the param onion, we don't want to let it retain the data that's at a lower level of encryption
            innerOnion.AsymmetricEncryptedKey = null;
        }
        /// <summary>
        ///     Cloning ctor
        /// </summary>
        private PublicKeyEncryptionOnion(PublicKeyEncryptionOnion onion)
        {
            Mandate.That(onion, nameof(onion)).IsNotNull();

            SymmetricEncryptedData = onion.SymmetricEncryptedData;
            AsymmetricEncryptedKey = onion.AsymmetricEncryptedKey;
            SymmetricAlgorithmIV   = onion.SymmetricAlgorithmIV;
            AsymmetricThumbprint   = onion.AsymmetricThumbprint;
            InnerOnion             = onion.InnerOnion;
        }