Como desencriptar las llamadas al handler WebResource.axd

Hace poco analizando el log de excepciones de una aplicación vi que se estaban registrando errores 404 en algunas de las llamadas al handler WebResource.axd. Este se utiliza para obtener los recursos incrustados de un ensamblado, ya sea una css, un javascript o una imagen. Se utilizan por ejemplo en los ScriptControls de ASP.NET.

La forma de estas peticiones es la siguiente:

WebResource.axd?

d=ZW84ZBYUTThg3mr0V9NcwYtSLalhseSYaewTgMXj71Vz1AXpI7tamoExhnMIKiyse_PbCeBNz_3cya0t0

&t=634208633469717278

Constan de dos variables:

· d: Nombre encriptado del recurso en el ensamblado.

· t: Es una marca de tiempo que se puede utilizar para contralar la caché o los cambios en el contenido, por ejemplo.

Investigando un poco encontré un blog de Telerik en el que explican como desencriptar dichas llamadas, de este modo, podemos saber qué recurso nos está dando el error 404.

Basándome en el código de dicha página he creado una clase para encriptar y desencriptar estos datos:

 

using System;

using System.Reflection;

using System.Text;

using System.Web;

using System.Web.Configuration;

 

namespace DevJoker

{

    /// <summary>

    /// Ofrece funcionalidad de encriptación utilizando la MachineKey

    /// </summary>

    public class MachineKeySectionUtils

    {

        #region Singleton

 

        static MachineKeySectionUtils instancia = null;

        static readonly object objectoBloqueo = new object();

 

        /// <summary>

        /// Constructor privado de la clase

        /// </summary>

        MachineKeySectionUtils()

        {

        }

 

        /// <summary>

        /// Devuelve la instancia de la clase de forma segura (ThreadSafe)

        /// </summary>

        public static MachineKeySectionUtils Instancia

        {

            get

            {

                if (instancia == null)

                {

                    lock (objectoBloqueo)

                    {

                        if (instancia == null)

                        {

                            instancia = new MachineKeySectionUtils();

                        }

                    }

                }

                return instancia;

            }

        }

 

        #endregion

 

        #region Métodos públicos

 

        /// <summary>

        /// Encripta el texto pasado por parámetro utiliando la MachineKey

        /// </summary>

        /// <param name="texto">Texto a encriptar</param>

        public string Encriptar(string texto)

        {

            //Decodificamos el texto en Base 64

            byte[] datos = HttpServerUtility.UrlTokenDecode(texto);

 

            //Desencriptamos los datos

            byte[] datosEncriptados = EncriptOrDecryptData(true, datos, 0, datos.Length);

 

            //Convertimos de nuevo a string

            return Encoding.UTF8.GetString(datosEncriptados);

        }

 

        /// <summary>

        /// Desencripta el texto pasado por parámetro utiliando la MachineKey

        /// </summary>

        /// <param name="textoEncriptado">Texto a desncriptar</param>

        public string Desencriptar(string textoEncriptado)

        {

            //Decodificamos el texto en Base 64

            byte[] datosEncriptados = HttpServerUtility.UrlTokenDecode(textoEncriptado);

 

            //Desencriptamos los datos

            byte[] datosDesncriptados = EncriptOrDecryptData(false, datosEncriptados, 0, datosEncriptados.Length);

 

            //Convertimos de nuevo a string

            return Encoding.UTF8.GetString(datosDesncriptados);

        }

 

        #endregion

 

        #region Métodos privados

 

        /// <summary>

        /// Encripta o desencripta los datos pasados por parámetro utilizando la MachineKey

        /// </summary>

        /// <remarks>

        /// Para desencriptar el texto se utilizará el método EncryptOrDecryptData de la clase MachineKeySection.

        /// Este método es privado, por lo que utilizamos Reflection para realizar la llamada.

        ///</remarks>

        /// <param name="encriptar">Indica si encriptar o desencriptar</param>

        /// <param name="datos">Array de datos en Base 64</param>

        /// <param name="indiceInicioDatos">Indice por el que comenzar</param>

        /// <param name="longitudDatos">Longitud de los datos a tratar</param>

        /// <returns>Array de Bytes tratados</returns>

        private byte[] EncriptOrDecryptData(bool encriptar, byte[] datos, int indiceInicioDatos, int longitudDatos)

        {

            try

            {

                //Obtenemos el tipo de la calse MachineKeySection

                Type machineKeySection = typeof(MachineKeySection);

 

                //Declaramos el array de tipos correspondientes a los parámetros del método EncryptOrDecryptData

                Type[] paramTypes = new Type[] {

                    typeof(bool),       //Indica si encriptar (true) o desencriptar (false)

                    typeof(byte[]),     //Datos a encriptar o desencriptar

                    typeof(byte[]),     //Modificador (null)

                    typeof(int),        //Índice de inicio

                    typeof(int)         //Tamaño de los datos

                };

 

                //Obtenemos el objeto MethodInfo del método EncryptOrDecryptData

                MethodInfo encryptOrDecryptData = machineKeySection.GetMethod("EncryptOrDecryptData", BindingFlags.Static | BindingFlags.NonPublic, null, paramTypes, null);

 

                byte[] datosTransformados = (byte[])encryptOrDecryptData.Invoke(null,

                    new object[] {

                        encriptar,

                        datos,

                        null,

                        indiceInicioDatos,

                        longitudDatos

                    }

                );

 

                return datosTransformados;

            }

            catch (TargetInvocationException ex)

            {

                throw new Exception("Error al encriptar o desencriptar los datos", ex);

            }

        }

 

        #endregion

    }

}

 

Tened en cuenta que la clave de encriptación es a nivel de máquina, por lo que no podemos coger la url de un sitio y desencriptarla en nuestro ordenador u otro servidor.

Tratándose de un sitio web, podríamos crear una página o un handler, y hacer las llamadas correspondientes. En el blog anterior, tienen una página que puedes descargar para desencriptar estas llamadas.

Como desencriptar las llamadas al handler WebResource.axd
David Andres .

David es analista y desarrollador de aplicaciones web cliente-servidor especializado en ASP.Net. En sus años de experiencia ha participado en proyectos para importantes empresas y entidades como Panda Security, Merck Sharp And Dohm, el gobierno de Navarra o Repsol. Conoce a fondo todas las versiones del framework .Net, bases de datos SQL Server y Oracle, y otras tecnologías como MS SharePoint y W4 Workflow. En desarrollo domina los lenguajes C#.Net, VB.Net, Java (J2EE, Struts), C, C++, JavaScript, T-SQL y PL/SQL entre otros.
Fecha de alta:27/05/2011
Última actualizacion:27/05/2011
Visitas totales:2533
Valorar el contenido:
Últimas consultas realizadas en los foros
Últimas preguntas sin contestar en los foros de devjoker.com