Contraseñas seguras: porqué más es siempre mejor

Seguramente, al registrate en un sitio web, banca electrónica, o cualquier otro servicio que solicite contraseña, has encontrado un mensaje como el siguiente:

La contraseña debe contener al menos 8 caracteres, pero no más de 12, y debe incluir al menos una letra y un número

(Ciertamente es una pobre política de contraseña segura, pero se entiende el ejemplo)

¿Porqué es esto? Bueno, es probable que hayas escuchado que esto hace más segura a tu contraseña. Pero… es cierto esto?

Dejemos de lado por un momento la posibilidad de que alguien se robe tu contraseña directamente de los servidores del sitio (eso es tema para otro post, coming soon). Supongamos que lo que queremos evitar es que alguien la “adivine”. Seguramente, gatito33 es lo suficientemente “diferente” para que alguien la adivine (a diferencia de, digamos, “gatito” a secas). Y probablemente estaremos en lo cierto, si por “alguien” nos referimos a un humano común y corriente. El problema es que, cuando alguien quiere obtener tu contraseña, usualmente no se la pasa adivinando y probando manualmente una por una (sí hay casos así, pero, a diferencia de lo que Hollywood nos quiera hacer creer, son los que menos nos preocupan). No, la preocupación mayor es lo que se conoce como un ataque de fuerza bruta.

Mediante este método, un atacante puede intentar adivinar miles (dependiendo de los recursos de cómputo a su disposición, puede ser millones) de contraseñas por minuto. Evidentemente, tiene que probar todas las combinaciones. Por ejemplo, si quisiera yo adivinar una contraseña de 4 caracteres o menos que utilice sólo letras minúsculas, tendría que probar:

a
b

z
aa
ab

az
ba

zz
aaa

zzzz

Si mi contraseña es “gato”, estará en esa lista. Y… cuántas son las que tiene que probar? Si recuerdas tus clases de probabilidad y estadística, esto se calcula fácilmente. Son todas las permutaciones de las letras del alfabeto en 4 lugares – o, en fórmula: 26^4 (26 elevado a la cuarta potencia). Esto es, 26*26*26*26, o bien, 456,976. Un numerote.

Pero, si dijimos que un atacante puede adivinar miles (o, en casos extremos, millones) de contraseñas por minuto, cuánto tiempo puede tomarle adivinar mi pequeña contraseña? Muy poco. Digamos que un atacante puede intentar un millón de contraseñas por minuto. En menos de 30 segundos, ya tendrá mi contraseña.

Uff! Entonces una contraseña de 8 caracteres será mucho más segura, no? Efectivamente. Y más del doble, de hecho. Consideremos que para adivinar una contraseña de máximo 8 caracteres, la fórmula sería:

26^8 = 208,827,064,576 = Doscientos ocho mil ochocientos veintisiete millones (!) y fracción.

Nuestro mismo atacante tardará… pues 208,827 minutos en adivinar esta contraseña. Lo cual es igual a… 145 días. Más de 4 meses. Caray, pero nuestro estimado de un millón por minuto puede ser bajo. Las botnets permiten controlar miles de computadoras a la vez! Démosle más ventaja a nuestro atacante. Supongamos que puede calcular 1 millón de contraseñas *por segundo*. De ser así, calcular todas las contraseñas de máximo 8 letras le tomaría 2.4 días.

NOTA: Hay que considerar que las políticas de contraseña, sin embargo, no suelen decir “de 1 a 8 caracteres”. No, en realidad dicen algo así como “mínimo 6 y máximo 10 carácteres”. Si solo utilizaramos letras, las posibilidades son 26^10 – 26^6 = 1.411667867×10^14 = un numerototote (141 billones y fracción). De ahora en adelante seguiremos con estas consideraciones.

Pensemos ahora en la política de contraseña arriba descrita: “La contraseña debe contener al menos 8 caracteres, pero no más de 12, y debe incluir al menos una letra y un número”. Esto significa que nuestra base (el 26) cambia, porque ahora consideramos las letras (26) y los números (10). Entonces nuestra fórmula sería: 36^12 – 36^8 = 4.738378517×10^18 (o bien, 4.7 trillones). Nuestro atacante (el de un millón de contraseñas por segundo) debería pasar 150,252 AÑOS intentando obtener nuestra contraseña, de todas las posibles.

Ahora, un poco de matemática aburrida (y no, lo de arriba no fue matemática aburrida). Si ya estás por dormirte, sáltate el siguiente párrafo, y lee las conclusiones.

Nótese que cada que agregamos un nuevo caracter (es decir, aumentamos el tamaño de la posible contraseña) disparamos exponencialmente el tamaño de la contraseña; no así cuando aumentamos el tamaño de la base (el crecimiento es más bajo). Esto cimenta la teoría de que es mejor utilizar contraseñas largas (ej. “estaesunacontraseñalargaquenosepuedeadivinarfacilmente” – 26^55) que una contraseña más corta pero con más caracteres (ej. “U7w!5q3qw&” – 60^10 considerando 8 símbolos especiales), en particular porque a la persona promedio se le hace mucho más sencillo recordar la frase que el garabato del segundo ejemplo. Más fácil de recordar + más difícil de vulnerar es una muy buena combinación 😉

El punto es: usa más en tus contraseñas. Si vas a utilizar contraseñas cortas (nunca abajo de 8, pero no superiores a 10 o 12 caracteres) es *imprescindible* que utilices letras mayúsculas, minúsculas, números, y símbolos especiales. Si no te gustan esos garabatos, utiliza contraseñas MUY largas, de más de 20 o 30 caracteres. Una forma fácil es utilizar frases, quitando espacios, acentos y puntuación. Por ejemplo:

“El respeto al derecho ajeno es la paz” –> elrespetoalderechoajenoeslapaz ==> 26^30.

Y, por supuesto – no olvides cambiarla con frecuencia. Buen consejo para la ropa, buen consejo para las contraseñas 🙂

Cómo utilizar DLLs externos en un programa de C#

…Después de la catarsis…

Hace poquito escribí acerca de mi alegría en obtener una rápida y eficiente solución a un problema que me estaba preocupando, específicamente de cómo copiar de manera segura archivos utilizando C#. Me encontré una biblioteca que hace justamente eso, utilizando el buen y viejo SCP. En pruebas todo estaba bien, terminé otras actualizaciones al proyecto, y como siempre, lo subí a un servidor donde la versión más nueva es descargable por los usuarios del sistema (o en resumen: “actualicé el servidor de actualizaciones”).

…Y que me avisan – esto no sirve. Terriblemente apenado, revisé inmediatamente la situación (ERT: 10 mins) y descubrí que C# me mostraba un error horrible a la hora de querer actualizar:

"[...]El archivo XXXX ya existe."

Mmm… huh? Pues claro que ya existe, babas. Era uno de los archivos .DLL que agregué para utilizar su funcionamiento. Pero… porqué se quejaba el instalador de ello?

La moraleja en versión breve es: lo agregué dos veces. Primero lo agregué como archivo al proyecto (Proyecto | | Incluir recurso existente) y luego agregué la referencia (Referencias | Agregar referencia). El manifiesto se confundió y chilló sin tregua.

Lección aprendida: Si vas a agregar un DLL externo, solo tienes que agregarlo como referencia. No es necesario agregarlo como archivo – Visual Studio se encarga de incluirlo con tu proyecto en el deployment.

Scp y C#

Hay veces que la vida te hace sentir inseguro, triste, alicaído, dolido y débil…

Then again, hay veces que… bueno, un video dice más que 1M palabras:

El código relevante:

Scp bule = new Scp(servidor, user, pass);
bule.Connect(puerto);
bule.Put(archivo origen, archivo destino);

Y la biblioteca relevante:

http://www.tamirgal.com/blog/page/SharpSSH.aspx

😀

Yujú!

Misión: rotar una imagen para su impresión en C# (counter-clockwise 90º)

Tiempo estimado de completado: 1-3 horas (dependiendo de lo que Dios Google me dijera)

Resultados preeliminares de búsqueda (re: Google):

Already done

Tiempo real de completado: 5 minutos

YUJU!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Poniendo colores de fondo diferentes a diferentes elementos de un ComboBox

Los comboBox son un control que permite seleccionar uno (y solo uno) de una lista de elementos. Algunos lenguajes los nombran dropDownBox, en HTMl es una etiqueta SELECT, etc.

En la familia .NET, no existe forma “sencilla” (objeto.propiedad) de cambiar el color de fondo para diferentes elementos. Pero con un poquito de investigación, descubrí que es posible redefiniendo el método que se encarga de dibujar cada elemento de la lista, en el control. Esto se logra:

1. Modificando la propiedad DrawMode del control, de “Normal” a “OwnerDrawFixed” u “OwnerDrawVariable” (este último es útil si se quiere modificar el tamaño de los elementos, de otra forma Fixed nos funciona perfecto).

2. Agregando un método al evento DrawItem del control.

3. Poniendo en ese método algo como:

private void _DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
Graphics g = e.Graphics;
switch ()
{
case 0:
g.FillRectangle(new SolidBrush(Color.LightGreen), e.Bounds);
break;
case 4:
g.FillRectangle(new SolidBrush(Color.LightCoral), e.Bounds);
break;
case 8:
g.FillRectangle(new SolidBrush(Color.LightYellow), e.Bounds);
break;
case 12:
g.FillRectangle(new SolidBrush(Color.LightBlue), e.Bounds);
break;
default:
g.FillRectangle(new SolidBrush(Color.LightGray), e.Bounds);
break;
}
string text = ((ComboBox)sender).Items[e.Index].ToString();
Brush brush = Brushes.Black;
e.Graphics.DrawString(text, ((Control)sender).Font, brush, e.Bounds.X, e.Bounds.Y);
e.DrawFocusRectangle();
}

🙂

Acerca de .Net, el manifiesto y los requisitos previos

Pues llevo la mejor parte de la noche (ok, ok, apenas un par de horas, pero es bastante para mí!) lidiando con un problema interesante. Explicaré un poco de los preeliminares, para que todos nos entendamos.

La plataforma de .Net es, para mi gusto, una verdadera maravilla. Si vas a desarrollar para Windows (y no te importa mucho obligar a tus usuarios a que instalen X dependencias que bien pueden ser molestas), te permite utilizar una serie de lenguajes muy parecidos entre sí, sólidos, con una gran base de desarrolladores que pueden ayudarte, código disponible en línea, e incluso bibliotecas listas para ser aprovechadas. Como Java, pues, pero sin la molestia de tener que usar… *eso*. Si tú desarrollaste en Visual Basic, VB.net es prácticamente lo mismo; si trabajaste en Java, C# es un camino bastante directo. Tiene gran versatilidad para desarrollar aplicaciones web, permite redistribución de dependencias (recuerden esto), tiene soporte para actualizaciones automáticas de tu aplicación… bueno, las bondades son demasiadas. En fin, es una plataforma que personalmente, me agrada bastante.

Nosotros, los programadores eventuales (es decir, que en realidad no nos dedicamos a esto para vivir), tenemos muchas malas mañas. Generamos código sucio, no muy organizado ni comentado; nuestra documentación puede catalogarse como garabateadas en servilletas y hojas de papel que acaban tiradas por ahí; y tendemos a vivir en el modo “debug”, nunca preocupándonos por cómo va a quedar la aplicación final cuando el usuario final decida instalarla – digo, podemos dejarlo hasta el final, no? El problema con esto es que cuando llega el famoso final… es una pesadilla.

De entrada, les recomiendo esto: no utilicen acentos para nombrar a su aplicación. No, .Net no truena con eso. Pero si quieren utilizar la funcionalidad de actualizaciones, su servidor web puede darse de topes con ustedes, porque va a buscar archivos y cadenas no fácilmente codificables. Solo… tómenlo como una recomendación amable.

Y por supuesto, el centro del problema: los requisitos previos. .Net corre sobre una máquina virtual (el “Framework”), y mi aplicación en particular utiliza un motor de bases de datos sencillo (SQL Server CE, que es algo así como el primo debilucho de SQL Server Express, que a su vez es el babas a comparación de SQL Server, que a su vez… etc etc), comparable con sqlite. El Framework, para instalarle, utiliza *otro* requisito previo, el Windows Installer (v.3.1 en este caso en particular). Estos requisitos son manejados elegantemente por el instalador generado por .Net: se descargan automáticamente de internet, si el usuario final no los tiene ya instalados. El problema es que, combinados, son alrededor de 100 Mb de descarga: ciertamente no es mucho para un geek, pero un usuario con una conexión de Infinitum a 512 (cuando le va bien) nos va a obligar a visitar a los papás. So… debemos poder incrustarlos con nuestro instalador, cierto?

La respuesta es “sí, pero te va a costar trabajo”. Resulta que estos instaladores (que se pueden bajar bastante fácil de internet) no se ponen en cualquier localidad. Deben ir en el directorio que .Net utiliza para almacenar los instaladores. Suena sencillo… hasta que nos enteramos que cada versión del Framework tiene diferentes localidades (y lo mismo para cada versión del Installer, SQL, etc), y que a su vez, cada versión de la IDE lo pone en directorios ligeramente diferentes. En mi caso?

C:Program Files (x86)Microsoft SDKsWindowsv7.0ABootstrapperPackages

¬¬ Sí te iba a encontrar, no?

Pero gracias a un valiente y hermoso post:

http://social.msdn.microsoft.com/forums/en-US/Vsexpressvb/thread/56584721-3064-46c2-81f4-6c29c01e1895/

Tuvo solución el problema. La moraleja, como siempre, es no fiarse de M$.

😀

A veces se me olvida lo lindo que es Visual Studio…

private void algunTextbox_KeyPress(object sender, KeyPressEventArgs e)
{
const char Delete = (char)8;
e.Handled = !Char.IsDigit(e.KeyChar) && e.KeyChar != Delete;
}

🙂

P.D.: Esto sirve para que, con C# (o bien, C sharp), podamos limitar el contenido de un textbox a solo digitos. En esencia, estamos aceptando teclazos si y solo si son digitos (o estamos borrando).

iOS 4.2 está bastante chido…

Pues acabo de actualizar mi iPhone a la versión 4.2 del sistema operativo. He de decir… wow. Apple acaba de hacer que mi teléfono cuente con muchísima mayor funcionalidad. Veámoslo a detalle.

1. Primero que nada, el nuevo AirPrint. Resulta que ahora puedes imprimir a cualquier impresora soportada (que tristemente, no son muchas… pero la mía sí :D) desde el mugroso iPhone. Esto incluye Fotos, Safari, Mail y Notas, así como una cantidad de aplicaciones adicionales. O sea, que la próxima vez que quiera imprimir un correo, solo debo hacer dos clicks… y voilà. Realmente de siglo 21 😀

2. Find My Iphone. Esta es probablemente la característica más payasa. Resulta que este servicio, que anteriormente tenía un costo de $100 USD al año, ahora es gratuito para todos los usuarios de iPhone 4. Y está… impresionante. En esencia es un servicio push que permite posicionar al iPhone en cuestión desde web (o incluso otro dispositivo iP*)… pero eso no es todo. Permite enviarle un mensaje (que se despliega en la pantalla del iPhone), deshabilitarlo (para que no lo puedan utilizar), o incluso, borrarle toda la información que contiene, de manera remota y confiable.

Es decir, que ya no me tienen que presumir nada los que usan su BlackBerry. Este dispositivo también tiene su remoteWipe. 😀

3. Por último, pero no menos importante… el Tethering. O sea, compartir internet. Disponible en el menú “Red” de la sección de configuración, ahora podemos compartir internet con otro dispositivo (ej. Laptop) a través de la conexión 3G del teléfono, sin necesidad del jailbreak. Ya lo probé y funciona de maravilla. Ahora, a ver si Telcel no se mancha y quiere cobrar de más por esta funcionalidad… Pero de momento, es una fantástica adición.

Creo que tiene otro par de mejoras más, pero estas fueron las que me vendieron la actualización. Gracias, Apple!