Beruflich Dokumente
Kultur Dokumente
Criptografía
La criptografía es la ciencia relacionada con el ocultamiento de
la información. Existe prácticamente desde la invención de la
escritura. En sus comienzos se usaban métodos simples de
substitución, había una tabla de conversión y para descifrar el
mensaje oculto se reemplazaban los caracteres de un texto por
97
los de la tabla y se obtenía el mensaje original. Se denomina
criptograma al mensaje cifrado.
98 Almacenando contraseñas
Uno de los usos de los métodos de clave simétrica es la
construcción de funciones de hash. Estas funciones toman como
entrada un mensaje y su salida, usualmente llamada digest, es
una cadena de largo fjo que varía según la función. Estas
funciones están diseñadas de tal manera que no es posible
obtener el mensaje original a partir del digest. Y además es muy
importante que no tengan colisiones. Existe una colisión
cuando para dos mensajes diferentes el resultado es el mismo
digest. Algunos ejemplos de funciones de hash conocidas son
SHA-1, SHA-2 y MD5. SHA-2 es una familia de funciones
cuyos nombres indican la longitud en bits de su salida: SHA-
224, SHA-256, SHA-384 y SHA-512.
$ irb -rdigest/sha1
ruby > Digest::SHA1.hexdigest('Ministro de
Ahorro Postal')
=> "d1ec5299ce555b9c0e2bdf0c7cdf7e5cc1850737"
ruby > Digest::SHA1.hexdigest('a')
=> "86f7e437faa5a7fce15d1ddcb9eaeaea377667b8"
Almacenando contraseñas 99
Casos prácticos
Vamos a analizar diferentes opciones de cómo almacenar las
contraseñas teniendo en cuenta lo que ahora sabemos de
criptografía. Vamos a empezar desde la opción más sencilla de
implementar y la más vulnerable hasta llegar a las más
complejas y efectivas.
Texto plano
Esta es sin duda la opción más naíf. Consiste en almacenar la
contraseña del usuario tal cual como fue ingresada por él. Esta
opción es usada generalmente porque no requiere ningún
esfuerzo extra. También se cree que dado que la información
queda almacenada en la base de datos de la aplicación y sólo
puede ser accedida por los desarrolladores o el DBA, la
información está sufcientemente segura. Quienes piensan así
no tienen en cuenta que un atacante puede ser interno y que
cualquiera que tenga acceso a la base de datos (incluyendo al
DBA o los desarrolladores) podrá ver esas contraseñas. Además,
si algún atacante externo logra el acceso a la base de datos, al
tener la información de los usuarios es probable que pueda
acceder a todas las cuentas de los mismos. No olvidemos que
muchas personas usan la misma contraseña para casi (o todas)
las cuentas que tienen en diferentes sitios, así, saber la clave de
un usuario y su dirección de correo electrónico es casi como
tener acceso a todo el contenido e información que tengan en
otros sitios.
Cifrado
Si ya nos convencimos de que almacenar las claves en texto
plano es una muy mala idea, podemos pensar que con poco
esfuerzo conseguiremos una versión encriptada (y casera) de las
claves. Decidimos entonces hacer un cifrado de las contraseñas
y para ello reemplazamos cada caracter de la clave por el que le
sigue 42 posiciones más adelante. Aplicamos la substitución no
sólo a las letras del abecedario (de la a a la z) sino a todos los
caracteres posibles. El siguiente ejemplo lo haremos en Java.
Creamos una clase Cipher que se encargará de
encriptar/desencriptar los mensajes:
public class Cipher {
private int x;
public Cipher(int x) {
this.x = x;
}
import org.junit.Before;
import org.junit.Test;
@Before
public void setUp() {
cipher = new Cipher(42);
}
@Test
public void encrypt() {
final String x = "ABC";
@Test
public void decrypt() {
final String x = "Saber demasiado nunca
simplifica las decisiones";
assertEquals(x,
cipher.decrypt(cipher.encrypt(x)));
}
}
CBB7C0B7BEBFC1BFB7C0C6C1B7C0C3C7B7BEBEB7B9B3C4C
1C0B3BEB3C6B7C4C4B3CCB3BEB3BFBBC4B3B6B3C5B7BEB7
C5C2B7C4B6BBC1B6B7C2C4C1C0C6C1BFB3C5B3BEBEB3B6B
7BEC2B3BEBFB7C4B3BEB7C0B7BEBAC1C4BBCCC1C0C6B7BB
C0BFB7C0C5C1B3BCB3C0BBC0B7BEB7C2B3C4B7B5BBC1C3C
7B7B7BEB5BBB7BEC1B7C0C6B7C4C1C4B7C5C1C0B3B4B3B7
C0C7C0B3C0C1C6B3B8C4B3B9C1C4C1C5B3CBB4C4B7C8B7
Letra(s) Frecuencia
EA 13%
O 9%
S 8%
RNI 7%
DL 5%
CTU 4%
MP 3%
(1..2).each do |size|
puts "frequency (length=#{size})"
freqs = Hash.new { |h,k| h[k] = 0 }
encoded.chars.to_a.each_cons(size) do |x|
freqs[x.join] += 1
end
freqs.sort_by { |k, v| v }.reverse.each do |
k, v|
p [k, v] if v > 2
end
end
Símbolo
Frecuencia
(longitud = 1)
B7 29
B3 22
C0 16
C1 16
BE 15
C4 14
Símbolos
Frecuencia
(longitud = 2)
B7BE 8
B7C0 7
B3BE 5
C1C0 4
C4C1 4
C4B3 4
Símbolo Substitución
B7 E
B3 A
BE L
C0 N
C1 O
CBenelBFoBFenC6oenC3C7elleB9aC4onalaC6eC4C4aCCa
laBFBBC4aB6aC5eleC5C2eC4B6BBoB6eC2C4onC6oBFaC5a
llaB6elC2alBFeC4alenelBAoC4BBCConC6eBBnBFenC5oa
BCanBBneleC2aC4eB5BBoC3C7eelB5BBeloenC6eC4oC4eC
5onaB4aenC7nanoC6aB8C4aB9oC4oC5aCBB4C4eC8e
CBenelBFoBFenC6oenC3