/// <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>
        ///     Root-level encryption of plain text ctor
        /// </summary>
        public PublicKeyEncryptionOnion(byte[] plainData, string asymmetricThumbprint)
        {
            if (null == plainData || !plainData.Any())
            {
                throw new ArgumentNullException(nameof(plainData));
            }

            Mandate.That(asymmetricThumbprint, nameof(asymmetricThumbprint)).IsNotNullOrEmpty();


            AsymmetricThumbprint = asymmetricThumbprint;
            InnerOnion           = null;

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

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