Desmitificando la Encriptación (Parte II)

Por Patrick Mac Kay Tepper

Contenido

 Introducción
 Encriptación Asimétrica
 Encriptación Asimétrica + Simétrica
 Hash
 Conclusiones
 Respuestas a las Preguntas

Introducción

En esta segunda y última parte de este artículo, se explicarán los algoritmos asimétricos y el Hash. Habiendo revisado ya la encriptación simétrica, procedamos ahora a revisar qué es la encriptación asimétrica y cuándo debe utilizarse.

 

Encriptación Asimétrica

La encriptación asimétrica permite que dos personas puedan enviarse información encriptada, sin necesidad de compartir la llave de encriptación. Se utiliza una llave pública para encriptar el texto y una llave privada para desencriptar. A pesar de que puede sonar extraño que se encripte con la llave pública y desencripte con la privada, el motivo para hacerlo es el siguiente: si alguien necesita que le envíen la información encriptada, deja disponible la llave pública para que quienes le desean enviar algo lo encripten. Nadie puede desencriptar algo con la misma llave pública. El único que puede desencriptar es quien posea la llave privada, quien justamente es el que recibe la información encriptada.

Los algoritmos de encriptación asimétrica más conocidos son:

  • RSA ( Rivest , Shamir , Adleman )
    Creado en 1978, hoy es el algoritmo de mayor uso en encriptación asimétrica. Tiene dificultades para encriptar grandes volúmenes de información, por lo que es usado por lo general en conjunto con algoritmos simétricos.

  • Diffie-Hellman (& Merkle )
    No es precisamente un algoritmo de encriptación sino un algoritmo para generar llaves públicas y privadas en ambientes inseguros.

  • ECC ( Elliptical Curve Cryptography )
    Es un algoritmo que se utiliza poco, pero tiene importancia cuando es necesario encriptar grandes volúmenes de información.

El tamaño de la llave es el siguiente:

Algoritmo
Largos válidos (bits) Largo por defecto (bits)
RSA 384 a 16.384 (incrementos de a 8) 1.024

Mientras más larga sea la llave, más seguro será. La relación con los algoritmos simétricos no es directa. En este caso, una llave de 1024 bits de RSA es equivalente en seguridad a una de 75 bits de un algoritmo simétrico.

Como era de esperar, en nuestra demostración utilizaremos el algoritmo de mayor uso, RSA. Debido a que el funcionamiento es diferente comparado con el algoritmo anterior, la pantalla varía levemente. Existirá una zona donde se desplegará la llave pública generada, dejándole el almacenamiento de la llave privada a la clase miRSA.

La idea de esto es que exista una clase que provea una llave pública, para que el cliente encripte la información y luego éste le envíe lo encriptado a la misma clase, para que con la llave privada la desencripte. En este caso, se ha dejado el método desencriptar como público, por que se necesita para pintar el resultado en el formulario. Este no debiera ser un método público en una implementación real.

Antes de ver la demo, es necesario revisar el siguiente capítulo, debido a que la encriptación con RSA no es eficiente y tiene limitaciones de tamaño.

 

Encriptación Asimétrica + Simétrica

Debido a que la encriptación asimétrica es casi 1000 veces más lenta que la simétrica, cuando la información a encriptar es mucha, se utiliza una combinación de algoritmos. El algoritmo simétrico se utiliza para encriptar la información y el asimétrico para encriptar la llave del algoritmo simétrico con que se encriptó la información. Entonces, el proceso es mucho más rápido. Esta técnica se utiliza hoy en SSL en la negociación entre el navegador del cliente y el servidor. En cada ida y vuelta al servidor se generan nuevas llaves y se realiza todo el proceso. También es utilizada por Windows en la encriptación de los archivos.

Otro motivo para utilizar esta encriptación combinada es la necesidad de encriptar textos largos. La encriptación asimétrica además de ser ineficiente en tiempo, tiene limitaciones de tamaño. El tamaño máximo depende del largo de la llave. En la demostración, puedes probar colocando mucho texto y verás que se cae.

Estas limitantes nos obligan a utilizar el método combinado.

Nuestra demostración implementa ambos métodos, y se decide cuál utilizar con la selección del check Utilizar Simétrico. La aplicación se ve como se muestra en la Figura 1 y Figura 2. Antes de hacer cada demo, se debe seleccionar si se utilizará en conjunto con encriptación simétrica.

Bb972217.art218-img01-482x392(es-es,MSDN.10).jpg
Figura 1: Encriptación utilizando solamente RSA.Volver al texto .

Bb972217.art218-img02-482x392(es-es,MSDN.10).jpg
Figura 2: Encriptación utilizando RSA con Rijndael.Volver al texto .

El resultado de la encriptación es notoriamente más largo.

Como vemos, si generamos una llave y luego procedemos con los siguientes pasos, la encriptación se produce en un lado y la desencriptación en otro. Incluso .NET provee el método ToXmlString() de RSACryptoServiceProvider que retorna la llave en formato XML, ideal para ser enviada por algún medio público (Web Service, Archivo XML, etc.).

Dependiendo de si se utiliza en conjunto con algún algoritmo simétrico, la encriptación y desencriptación es diferente. Como algoritmo simétrico se utiliza AES ó Rijndael.

El código de nuestra clase miRSA es el siguiente:

public class miRSA
{
       private RSACryptoServiceProvider _objRSA = null;
 
       public miRSA()
       {
              this._objRSA = new RSACryptoServiceProvider(1024);
       }
 
       public string ObtenerLlavePublica()
       {
              return this._objRSA.ToXmlString(false);
       }
 
       public string DesEncriptar(byte[] bytEncriptado, bool blnConSimetrico)
       { 
              if (blnConSimetrico)
              {
                     byte[] keyArray = new byte[_objRSA.KeySize/8];
                     byte[] encrypted = new byte[bytEncriptado.Length - keyArray.Length];
                     Array.Copy(bytEncriptado, 0, keyArray, 0, keyArray.Length);
                     Array.Copy(bytEncriptado, keyArray.Length, encrypted, 0, encrypted.Length);
 
                     byte[] simKey = this._objRSA.Decrypt(keyArray, false);
 
                     return MiRijndael.Desencriptar(encrypted, simKey);
              }
              else
              {
                     return System.Text.Encoding.UTF8.GetString(this._objRSA.Decrypt(bytEncriptado, false));
              }
       }
} 

Y el código del cliente público es el siguiente (declarado en algún lugar del formulario):

private miRSA _objKey  = null; 
 
public Form1() 
{ 
       InitializeComponent(); 
       _objKey = new miRSA(); 
} 
 
private void btnAsimEncriptar_Click(object sender, System.EventArgs e) 
{ 
       byte[] _bytEncriptado = null; 
 
       //Creamos una instancia del encritador publico 
       RSACryptoServiceProvider _objEncriptadorPublico = new RSACryptoServiceProvider(); 
       //Le asignamos la llave genarada 
       _objEncriptadorPublico.FromXmlString(this.txtAsimLlavePublica.Text); 
 
       if (this.chkSimetrica.Checked) 
       { 
              //Se declara la memoria para almacenar la llave utilizada por nuestro Rijndael personalizado 
              byte[] _bytKey = (Rijndael.Create()).Key; 
 
              //Se encripta el texto y se obtiene la llave que se utilizó para la encriptación 
              byte[] _bytEncriptadoSimetrico = TransEncripHash.MiRijndael.Encriptar(this.txtAsimAEncriptar.Text, 
_bytKey); 
 
              //Se encripta la llave con el algoritmo RSA 
              byte[] _bytEncriptadoLlave = _objEncriptadorPublico.Encrypt(_bytKey, false); 
 
              //Se copia en un arreglo la llave encriptada y el encriptado de Rijndael 
              _bytEncriptado = new byte[_bytEncriptadoLlave.Length + _bytEncriptadoSimetrico.Length]; 
              _bytEncriptadoLlave.CopyTo(_bytEncriptado,0); 
              _bytEncriptadoSimetrico.CopyTo(_bytEncriptado, _bytEncriptadoLlave.Length); 
       } 
       else 
       { 
              _bytEncriptado = _objEncriptadorPublico.Encrypt(System.Text.Encoding.UTF8.GetBytes
(this.txtAsimAEncriptar.Text), false); 
       } 
       this.txtAsimEncriptado.Text = Convert.ToBase64String(_bytEncriptado); 
} 
 
private void btnAsimDesEncriptar_Click(object sender, System.EventArgs e) 
{ 
       this.txtAsimDesEncriptado.Text = this._objKey.DesEncriptar(Convert.FromBase64String
(this.txtAsimEncriptado.Text), this.chkSimetrica.Checked); 
} 
private void btnAsimGenerar_Click(object sender, System.EventArgs e) 
{ 
       this.txtAsimLlavePublica.Text = this._objKey.ObtenerLlavePublica(); 
}

En este ejemplo, la encriptación se produce en un lugar, luego de solicitar la clave pública a la clase (pero que perfectamente puede ser un servicio Web), la información encriptada se puede enviar a este servicio Web sin problemas de violación de seguridad, y sin necesidad de conocer ambas llaves. Si bien es cierto que la clase o servicio conoce ambas llaves, la llave pública no le es de ninguna utilidad.

Antes de finalizar con este algoritmo, cabe mencionar que donde puede haber problemas es en la generación de la llave. Por eso, Diffie-Hellman (& Merkle) se especializa en mejorar ese proceso, ya que es de vital importancia la generación de llaves.

Nota: Existe cierta codificación que puede haber pasado desapercibida hasta ahora. Esta es la utilización de distintos métodos para transformar textos en arreglos de bytes, y viceversa. Los métodos reales para hacerlo son los que están implementados en los encodings de .NET, como por ejemplo System.Text.Encoding.UTF8.GetString(bytes) y System.Text.Encoding.UTF8.GetBytes(string). En las demos se ha cambiado algunos deliberadamente por Convert.ToBase64String(bytes) y Convert.FromBase64String(string) para poder desplegarlo en los controles del formulario Windows. El resultado de una encriptación genera carácteres visibles y no visibles. Si no se transforman a Base64 y desde Base64 mientras son almacenados en un control, se pierde información. Si el resultado de la encriptación no va a ser desplegado sino que será almacenado en algún medio, los bytes de éste pueden escribirse sin problemas en el medio que sea.

 

Hash

Por último, nos quedan los algoritmos de tipo Hash. Estos son algoritmos del tipo de los que se conocen como de sólo ida, ya que no es posible desencriptar lo que se ha encriptado. Puede ser que a primera vista no se le vea la utilidad, pero en los siguientes dos escenarios éste es el tipo de algoritmo necesario para realizar el proceso. El primero de ellos está dirigido a proteger información muy valiosa encriptando el contenido; y el segundo busca validar que no se modifique la información que se está enviando desde un lugar a otro.

  • Escenario 1: Almacenar contraseñas de un sistema. Las contraseñas de cualquier sistema serio jamás debieran poder desencriptarse. El motivo es simple. Si se pueden desencriptar, el riesgo de que alguien conozca la llave y tenga acceso a todo el sistema con todos los usuarios es muy grande. Entonces, si no puedo desencriptar una contraseña, ¿Cómo puedo saber entonces si una contraseña entregada es válida? La respuesta es muy simple. Se encripta la contraseña entregada y se compara el resultado de la encriptación con la contraseña previamente almacenada.

  • Escenario 2: Validar que cierta información no se haya modificado. Si se desea enviar un bloque de datos y se quiere estar seguro de que nadie lo ha modificado durante el camino, lo que se hace es enviar el bloque de información sin encriptar y además se envía un Hash/Digest de este mismo bloque de datos. Entonces, nuestro receptor al tener la información sin encriptar, le aplica un Hash y con el mismo criterio del Escenario 1, determina si ambos bloques son iguales. Si lo son, el bloque que no está con Hash es el original. ¿Porqué no usar un algoritmo de encriptación reversible? Porque éste podría ser desencriptado, modificado y vuelto a encriptar y el receptor jamás sabría que fue modificado en el camino. Como el Hash no es reversible, esto último no podrá suceder jamás.

Los algoritmos para hacer Hash mas conocidos son los siguientes:

Algoritmo
Tamaño del Hash (bits)
MD5 128
SHA-1 160
SHA-256 256
SHA-384 384
SHA-512 512

La robustez de un algoritmo de Hash es comparable a la mitad del largo del resultado en bits. Entonces, pensar que con MD5 se está seguro puede ser un error. SHA-256 es el indicado para obtener seguridad de 128 bits. Es un hecho que SHA-256 es mucho más lento, pero como Bruce Schneier dice “Ya existen suficientes sistemas rápidos e inseguros”.

Pero a pesar de parecer muy efectivo, existe un problema con el Hash para cada uno de los escenarios indicados anteriormente. Como son problemas conocidos, existen soluciones conocidas también. Revisemos ahora cada uno de los problemas y sus soluciones.

Problemas Escenario 1

Si bien el problema no está tan relacionado con el Hash, debido a la utilización de contraseñas de escasa dificultad, haciendo un ataque de fuerza bruta o por diccionario se podrían encontrar valores de Hash que coinciden con el Hash de las contraseñas almacenadas. Para esto se pueden ejecutar dos planes de acción independientes, pero obteniéndose el mejor resultado con la utilización de ambos.

La Solución 1 consiste en realizar varias pasadas de Hash sobre los datos, aplicándole el Hash al resultado del Hash anterior. Realizando esto varios cientos de veces (idealmente mil veces) podemos dificultar más el trabajo de un hacker. Más información de porqué se debe iterar muchas veces y las consecuencias de no hacerlo, la puedes encontrar en http://www.atrevido.net/blog/PermaLink.aspx?guid=12b1338b-171e-4692-850e-8f59ed12f24a .

La Solución 2 requiere agregar un texto adicional a la contraseña. Esto se conoce como Salt. Entonces, cada vez que un usuario cambie o esté validando una contraseña, hay que concatenarle a la contraseña este Salt y de ahí generar el Hash. De esta forma le agrega variación a las contraseñas pobremente definidas. Esta solución requiere un trabajo adicional ya que es necesario además almacenar el texto del Salt junto a la información del usuario y la contraseña encriptada. Este texto se debe crear con carácteres generados al azar.

En el ejemplo se mostrará la combinación de ambas soluciones. Como encriptación de Hash se usará SHA256. Los otros algoritmos mencionados con anterioridad están disponibles también en .NET.

El resultado de la encriptación 1000 veces de cierto texto con un Salt definido, es el que se muestra en la Figura 3:

Bb972217.art218-img03-482x392(es-es,MSDN.10).jpg
Figura 3. Volver al texto.

El código para realizar esto es muy simple y es el que se muestra a continuación:

public class HashContraseñas
{
       public static byte[] Encriptar(string strPassword, string strSalt, int intIteraciones)
       {
                                string _strPasswordSalt = strPassword + strSalt;
                                SHA256Managed _objSha256 = new SHA256Managed();
                                byte[] _objTemporal = null;
 
                                try
                                {
                                                _objTemporal = System.Text.Encoding.UTF8.GetBytes(
_strPasswordSalt);
                                                for (int i = 0; i <= intIteraciones - 1; i++)
                                                                _objTemporal = _objSha256.ComputeHash(
_objTemporal);
                                }
                                finally { _objSha256.Clear(); }
 
                                return _objTemporal;
}
} 

Qué cosas se deben clarificar en este proceso
El resultado de este Hash (Sha256) siempre retorna 256 bits, es decir, 32 bytes. Cuidado con confundir con el largo del string resultante de la conversión a Base64. Esta conversión genera más carácteres. Para verificar, puedes medir el largo del arreglo colocando un punto de interrupción en el retorno (return), y notarás que son 32 bytes.

Además, las funciones de hash no tienen limitante para el tamaño del texto de entrada. Sea cual fuere el tamaño, el largo de la salida es el mismo y se procesan todos los carácteres del string de entrada.

Para un sistema de almacenamiento de contraseñas de usuario seguro, hay que hacer algunas modificaciones a esta función, pero son mínimas. Las modificaciones no pasan por cambios en el algoritmo, sino más bien por crear una función para que genere Salt randómicos y crear la función para la comparación de las contraseñas.

Probablemente te preguntes porqué hay 2 cajas de texto con el mismo texto. Como este proceso es común, o al menos debiera serlo, .NET provee una clase llamada PasswordDeriveBytes que sirve para realizar de forma automática todo lo anteriormente visto. En el evento click, además de la llamada a la función detallada de más arriba (HashContraseñas.Encriptar), se crea una instancia de esta clase (PasswordDeriveBytes) y se le especifican los mismos parámetros que estamos utilizando en nuestro algoritmo de Hash (la contraseña, el Salt, el algoritmo SHA256 y la cantidad de iteraciones). Esto hace que en sólo pocas líneas se pueda realizar el mismo proceso.

El código ejecutado es el siguiente:

PasswordDeriveBytes _objPdb = new PasswordDeriveBytes(this.txtHashEncriptar1.Text,
 System.Text.Encoding.UTF8.GetBytes(this.txtSalt.Text), "SHA256", Convert.ToInt32(this.txtCantidad.Text));
 
this.txtHashEncriptado2.Text = Convert.ToBase64String(_objPdb.GetBytes(32));

Para comparar arreglos de bytes, se verá más adelante una función con tal objetivo.

Problemas Escenario 2: Si alguien puede ejecutar un Hash sobre un conjunto de datos y obtener el resultado, ¿Porqué no podría modificar el contenido del documento que estamos enviando y generar el Hash nuevamente, reemplazando el contenido del Hash anterior? ¿Cómo se puede diferenciar mi proceso de Hash del proceso de Hash impostor? No es posible a menos que haya alguna llave de por medio.

Debido a lo anterior, se han inventado los siguientes algoritmos de Hash, que utilizan llaves para realizar el proceso. En este caso, si el resultado se sobrescribe, al obtener el Hash con la llave, el resultado jamás coincidirá con el que viene en el mensaje.

Estos algoritmos y sus llaves son los siguientes:

Algoritmo
Tamaño del Hash (bits) Tamaño de llave (bits)
HMAC-SHA1 160 64
MAC-3DES-CBC 64 8, 16, 24

Para realizar la demo, debemos primero generar una llave. Hasta ahora, las llaves se han creado manualmente, pero ahora vamos a utilizar herramientas del Framework para generarlas. Como la llave de 64 bits es del mismo largo que la que utiliza el algoritmo DES, se utilizará la clase de éste para generar una. Existe el botón “Generar Key” que es el encargado de generar y almacenar una llave. Esta se genera en la función del botón, y se almacena en una variable de formulario. El código es el siguiente:

privatevoid btnHashKey_Click(object sender, System.EventArgs e)
{
      this._objHashKey = (new System.Security.Cryptography.DESCryptoServiceProvider()).Key;
      this.lblSalt.Text = "Key : " + Convert.ToBase64String(this._objHashKey);
}

Con la primer sentencia se crea la instancia del proveedor de DES y se obtiene el Key almacenándolo en _objHashKey, una variable de formulario. Con la segunda línea, se copia el contenido de la Key en una etiqueta del formulario, previamente transformándolo en Base64. Cabe mencionar que la transformación a Base64 genera una cadena más larga que la cantidad de bytes que está recibiendo, por eso si cuentas la cantidad de carácteres del Key, no cumple con ser de 64 bits (8 bytes).

La validación es muy simple de realizar. Recuerda que lo que se quiere hacer es verificar que la información que se está enviando no se haya modificado en el camino. Entonces lo que se debe hacer es generar un nuevo Hash con el texto en cuestión y la contraseña, y comparar el resultado del Hash generado con el que se envió inicialmente. La comparación de Hash se realiza con una función para comparar arreglos (Ver Figura 4):

Bb972217.art218-img04-482x392(es-es,MSDN.10).jpg
Figura 4: Resultado de presionar Validar Hash sin hacer ninguna modificación. Volver al texto.

En cambio, si se modifica levemente el texto, agregando la palabra "me" (o cualquiera) en el círculo rojo remarcado, y se trata de validar, el resultado es erróneo inmediatamente. Con esta funcionalidad se valida que nadie haya modificado el contenido de lo que se está enviando (Ver Figura 5):

Bb972217.art218-img05-482x392(es-es,MSDN.10).jpg
Figura 5: Resultado de presionar Validar Hash con una modificación. Volver al texto.

Además, si se genera una nueva Key (con el botón Generar Key ) y se valida, el resultado es fallido, como era de esperarse. Existe otro método para realizar esta misma validación pero sin compartir las llaves. La idea es muy similar a la estudiada en los algoritmos asimétricos, en donde una de las partes tiene una llave para encriptar y otra parte tiene otra llave para encriptar también. Algo similar a esto es lo que se utiliza para la firma digital, pero por ser un tema tan amplio, no cabe en este artículo y merece un artículo completo para su explicación. Algunas claves para poder conocer como funciona esto, las siguientes clases del Framework poseen funcionalidad para lograrlo. Estas son RSACryptoServiceProvider y DSACryptoServiceProvider. Por último, algo de código. Para generar un Hash con un Key y para comparar arreglos de bytes se utilizan los siguientes bloques de código:

public class HashValidacion 
{ 
       public static byte[] Encriptar(string strTexto, byte[] objKey) 
       { 
              HMACSHA1 _objHMACSHA = new HMACSHA1(objKey); 
              try 
              { 
                     return _objHMACSHA.ComputeHash(Encoding.UTF8.GetBytes(strTexto)); 
              } 
              finally 
              { 
                     _objHMACSHA.Clear(); 
              } 
       } 
 
       public static bool CompareByteArray(Byte[] arrayA, Byte[] arrayB) 
       { 
              if (arrayA.Length != arrayB.Length) 
                     return false; 
 
              for (int i = 0; i <= arrayA.Length - 1; i++) 
                     if (!arrayA[i].Equals(arrayB[i])) 
                           return false; 
              return true; 
       } 
} 

 

Conclusiones

A través de las dos partes de este artículo se han explorado los métodos más comunes de encriptación, revisándose cada escenario donde se aplican. Cada escenario se ha complementado con ejemplos y código 100% funcional. Se ha  desmitificado la encriptación como un proceso complicado y nebuloso, mostrándose de forma clara cuándo y cómo aplicar cada algoritmo, además de la forma correcta de hacerlo.

 

Respuestas a las Preguntas

Revisemos entonces algunas de las preguntas inicialmente planteadas y veamos cómo podemos responderlas ahora.

  • ¿Se está almacenando la información crítica de forma segura?
    Esta pregunta la puede respnder el lector.

  • ¿Qué entendemos por seguro?
    Se ha mostrado la diferencia entre algoritmos que transforman texto con respecto a otros que realmente encriptan.

  • Si se está encriptando, ¿Qué algoritmo se está utilizando?
    Se revisaron los algoritmos más conocidos y se mostraron sus ventajas y falencias. Sea cual fuere, el algoritmo debe implementarse adecuadamente.

  • ¿Se permite la desencriptación de datos que no debieran poder desencriptarse?
    Esta pregunta la puede responder el lector , pero la respuesta debe ser NO.

  • ¿Cómo está realizándose la encriptación?
    Se revisó la forma correcta de encriptar con cada algoritmo, como también las malas prácticas y los riesgos que se corren al no hacer el proceso como debe ser.

  • ¿Dónde están almacenadas la o las llaves?
    Esta es una muy buena pregunta y la respuesta escapa al alcance de este artículo, pero como sugerencia se puede mencionar lo siguiente: se puede utilizar DPAPI o Certificate Storage. Para implementar DPAPI tanto desde aplicaciones Windows como web, puedes visitar los siguientes enlaces:

    DPAPI: http://msdn2.microsoft.com/library/aa302402.aspx
    DPAPI en Web: http://msdn2.microsoft.com/library/aa302404.aspx

    Pensamientos como el siguiente no son seguros: "si almaceno la llave en un directorio escondido, es difícil que un hacker la encuentre", como así también "A un hacker le va a tomar mucho tiempo encontrarla." Si hay algo que le sobra a un hacker es tiempo y ganas.

  • ¿Con qué frecuencia se cambian las llaves?
    La respuesta es depende, lamentablemente. Depende de la criticidad del sistema, como también del uso de las llaves. Para una conexión de transferencia, se crean las llaves, se utilizan y se descartan. En un sistema crítico tal como el de un banco, el cambio de llaves debería hacerse cada una hora, o como máximo, cada un día. Para información que va a tener mayor duración, el tiempo puede ser mayor.

  • ¿Cómo enfrento el problema de cambiar las llaves con tanta frecuencia?
    Como cambiar las llaves no es una tarea simple en recursos y tiempo, se emplea el concepto de llave maestra y llaves hijas. La información a encriptar se encripta con las llaves hijas y luego  con la llave maestra se encriptan las llaves hijas y se almacenan.  Entonces, al momento de aplicar cambio de llave, se cambia sólo la llave maestra, procediéndose a desencriptar todas las llaves hijas con la antigua y a encriptar todas con la llave nueva. Esto disminuye el tiempo a factor de N (cantidad de llaves) y no de la cantidad de bytes de información encriptada. Esto no agrega seguridad, sólo ayuda a realizar un proceso de forma eficiente.

  • ¿Con qué criterio se definen las nuevas llaves?
    Para definir una llave se puede ejecutar la función GenerateKey() que todo algoritmo simétrico posee. Esto genera una llave randómica.

Patrick Mac Kay es Ingeniero Civil en Computación de la Universidad de Chile desde 2000. Trabaja como Arquitecto de Software de un sitio de comercio electrónico B2B en Chile; a su cargo estuvo la implementación de este sitio en ASP .net y Visual Basic .net 2003 sobre Windows .net Web Server 2003. Posee 5 años de experiencia en el desarrollo de aplicaciones Web. Es MVP y cuenta con las certificaciones MCP en VB5, VB6 y ASP .net en Visual Basic.