public void SymmetricKeyWrapEncryptionRoundtrip(Func <ICipherParameters> keyFactory, Func <ICipherParameters> innerKeyFactory)
        {
            const string exampleXmlRootElement = "example";
            const string exampleXml            = @"<?xml version=""1.0""?>
<example>
<test>some text node</test>
</example>";
            const string keyName = "mytestkey";

            ICipherParameters key             = keyFactory();
            XmlDocument       xmlDocToEncrypt = LoadXmlFromString(exampleXml);

            Encrypt(xmlDocToEncrypt, exampleXmlRootElement, "EncryptedElement1", key, keyName, innerKeyFactory);

            Console.WriteLine("----------------------------------------------------------------");
            Console.WriteLine("Algorithm: {0}", EncryptingAndDecryptingSymmetric.GetEncryptionMethodName(key, keyWrap: true));
            Console.WriteLine("Encrypted document:");
            Console.WriteLine();
            Console.WriteLine(xmlDocToEncrypt.OuterXml);
            Console.WriteLine();

            XmlDocument xmlDocToDecrypt = LoadXmlFromString(xmlDocToEncrypt.OuterXml);

            Decrypt(xmlDocToDecrypt, key, keyName);

            Console.WriteLine("Decrypted document:");
            Console.WriteLine();
            Console.WriteLine(xmlDocToDecrypt.OuterXml);
            Console.WriteLine();
        }
        private static void Encrypt(XmlDocument doc, string elementName, string encryptionElementID, ICipherParameters key, string keyName, Func <ICipherParameters> innerKeyFactory)
        {
            var elementToEncrypt = (XmlElement)doc.GetElementsByTagName(elementName)[0];

            ICipherParameters innerKey = innerKeyFactory();
            // Encrypt the key with another key
            var encryptedKey = new EncryptedKey()
            {
                CipherData       = new CipherData(EncryptedXml.EncryptKey(((KeyParameter)((ParametersWithIV)innerKey).Parameters).GetKey(), (KeyParameter)((ParametersWithIV)key).Parameters)),
                EncryptionMethod = new EncryptionMethod(EncryptingAndDecryptingSymmetric.GetEncryptionMethodName(key, keyWrap: true))
            };

            // Specify which EncryptedData
            // uses this key. An XML document can have
            // multiple EncryptedData elements that use
            // different keys.
            encryptedKey.AddReference(new DataReference()
            {
                Uri = "#" + encryptionElementID
            });

            var encryptedData = new EncryptedData()
            {
                Type = EncryptedXml.XmlEncElementUrl,
                Id   = encryptionElementID,

                // Create an EncryptionMethod element so that the
                // receiver knows which algorithm to use for decryption.
                EncryptionMethod = new EncryptionMethod(EncryptingAndDecryptingSymmetric.GetEncryptionMethodName(innerKey, keyWrap: false))
            };

            encryptedData.KeyInfo.AddClause(new KeyInfoEncryptedKey(encryptedKey));
            encryptedKey.KeyInfo.AddClause(new KeyInfoName()
            {
                Value = keyName
            });

            var encryptedXml = new EncryptedXml();

            encryptedData.CipherData.CipherValue = encryptedXml.EncryptData(elementToEncrypt, innerKey, false);

            EncryptedXml.ReplaceElement(elementToEncrypt, encryptedData, false);
        }