/////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        // Encrypt a ticket
        /// <include file='doc\FormsAuthentication.uex' path='docs/doc[@for="FormsAuthentication.Encrypt"]/*' />
        /// <devdoc>
        ///    Given a FormsAuthenticationTicket, this
        ///    method produces a string containing an encrypted authentication ticket suitable
        ///    for use in an HTTP cookie.
        /// </devdoc>
        public static String  Encrypt(FormsAuthenticationTicket ticket)
        {
            if (ticket == null)
            {
                throw new ArgumentNullException("ticket");
            }

            Initialize();
            //////////////////////////////////////////////////////////////////////
            // Step 1: Make it into a binary blob
            byte [] bBlob = MakeTicketIntoBinaryBlob(ticket);
            if (bBlob == null)
            {
                return(null);
            }

            if (_Protection == FormsProtectionEnum.None)
            {
                return(MachineKey.ByteArrayToHexString(bBlob, 0));
            }

            //////////////////////////////////////////////////////////////////////
            // Step 2: Get the MAC and add to the blob
            if (_Protection == FormsProtectionEnum.All || _Protection == FormsProtectionEnum.Validation)
            {
                byte [] bMac = MachineKey.HashData(bBlob, null, 0, bBlob.Length);
                if (bMac == null)
                {
                    return(null);
                }

                Trace("Encrypt: MAC length is: " + bMac.Length);

                byte [] bAll = new byte[bMac.Length + bBlob.Length];
                Buffer.BlockCopy(bBlob, 0, bAll, 0, bBlob.Length);
                Buffer.BlockCopy(bMac, 0, bAll, bBlob.Length, bMac.Length);

                if (_Protection == FormsProtectionEnum.Validation)
                {
                    return(MachineKey.ByteArrayToHexString(bAll, 0));
                }

                bBlob = bAll;
            }


            //////////////////////////////////////////////////////////////////////
            // Step 3: Do the actual encryption
            bBlob = MachineKey.EncryptOrDecryptData(true, bBlob, null, 0, bBlob.Length);
            return(MachineKey.ByteArrayToHexString(bBlob, bBlob.Length));
        }
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        /////////////////////////////////////////////////////////////////////////////
        // Decrypt and get the auth ticket
        /// <include file='doc\FormsAuthentication.uex' path='docs/doc[@for="FormsAuthentication.Decrypt"]/*' />
        /// <devdoc>
        ///    <para>Given an encrypted authenitcation ticket as
        ///       obtained from an HTTP cookie, this method returns an instance of a
        ///       FormsAuthenticationTicket class.</para>
        /// </devdoc>
        public static FormsAuthenticationTicket Decrypt(String encryptedTicket)
        {
            if (encryptedTicket == null || encryptedTicket.Length == 0)
            {
                throw new ArgumentException(HttpRuntime.FormatResourceString(SR.InvalidArgumentValue, "encryptedTicket"));
            }

            Initialize();
            Trace("Decrypting cookie: " + encryptedTicket);

            byte [] bBlob = MachineKey.HexStringToByteArray(encryptedTicket);
            if (bBlob == null || bBlob.Length < 1)
            {
                throw new ArgumentException(HttpRuntime.FormatResourceString(SR.InvalidArgumentValue, "encryptedTicket"));
            }

            if (_Protection == FormsProtectionEnum.All || _Protection == FormsProtectionEnum.Encryption)
            {
                bBlob = MachineKey.EncryptOrDecryptData(false, bBlob, null, 0, bBlob.Length);
                if (bBlob == null)
                {
                    return(null);
                }
            }

            if (_Protection == FormsProtectionEnum.All || _Protection == FormsProtectionEnum.Validation)
            {
                //////////////////////////////////////////////////////////////////////
                // Step 2: Get the MAC: Last MAC_LENGTH bytes
                if (bBlob.Length <= MAC_LENGTH)
                {
                    return(null);
                }

                byte [] bTicket = new byte[bBlob.Length - MAC_LENGTH];

                Buffer.BlockCopy(bBlob, 0, bTicket, 0, bTicket.Length);
                byte [] bMac = MachineKey.HashData(bTicket, null, 0, bTicket.Length);

                //////////////////////////////////////////////////////////////////////
                // Step 3: Make sure the MAC is correct
                if (bMac == null)
                {
                    Trace("Decrypting cookie failed to get the MAC.");
                    return(null);
                }

                if (bMac.Length != MAC_LENGTH)
                {
                    Trace("Decrypting cookie failed due to bad MAC length: " + bMac.Length);
                    return(null);
                }
                for (int iter = 0; iter < MAC_LENGTH; iter++)
                {
                    if (bMac[iter] != bBlob[bTicket.Length + iter])
                    {
                        Trace("Incorrect byte at " + iter + ", byte1: " + ((int)bMac[iter]) + ", byte2: " + ((int)bBlob[bTicket.Length + iter]));
                        return(null);
                    }
                }

                bBlob = bTicket;
            }

            //////////////////////////////////////////////////////////////////////
            // Step 4: Change binary ticket to managed struct
            int           iSize = ((bBlob.Length > 4096) ? 4096 : bBlob.Length);
            StringBuilder name  = new StringBuilder(iSize);
            StringBuilder data  = new StringBuilder(iSize);
            StringBuilder path  = new StringBuilder(iSize);

            byte [] pBin   = new byte[2];
            long [] pDates = new long[2];

            int iRet = UnsafeNativeMethods.CookieAuthParseTicket(bBlob, bBlob.Length,
                                                                 name, iSize,
                                                                 data, iSize,
                                                                 path, iSize,
                                                                 pBin, pDates);

            if (iRet != 0)
            {
                return(null);
            }

            return(new FormsAuthenticationTicket((int)pBin[0],
                                                 name.ToString(),
                                                 DateTime.FromFileTime(pDates[0]),
                                                 DateTime.FromFileTime(pDates[1]),
                                                 (bool)(pBin[1] != 0),
                                                 data.ToString(),
                                                 path.ToString()));
        }