Archivar por febrero, 2010

Seguridad: Encriptación y Autentificación. Capítulo Tercero -> Certificados y Firmas Digitales

ATENCION: Los ejemplos que se van a mostrar y “tutoriales” tan solo tienen carácter educativo. En ningún aspecto comparto filosofías de invasión a la intimidad, ataques contra un sistema informático o cuestiones similares. En la medida que sea posible siempre se usarán ejemplos y formas que puedan ser usados por cualquier persona, de forma que pueda verificar los contenidos escritos. No obstante, por motivos más que obvios, materiales como contraseñas, nombres de usuarios o de hosts, serán omitidos o modificado en las capturas de pantallas realizadas (o las lineas escritas). Es decir, los ejemplos serán completamente reales, los datos mostrados a vosotros necesarios para poder pertrechar estos ejemplos no siempre lo serán (Sí lo serán los resultados). Para que esto conste de forma clara, todo material sensible modificado o falso estará resaltado en ROJO. Por motivos de seguridad, todo el material que sea expuesto aquí (exceptuando software propietario o libre, citaciones expresas o código de terceros) tanto texto, imágenes y código son propiedad del autor y está completamente prohibido su reproducción completa o parcial en otros lugares, espero que se comprenda.

 

Certificados y Firmas Digitales

El cifrado de datos es un mecanismo que garantiza que nuestros datos, aun cuando puedan ser interceptados por otros, permanecerán seguros. Por otro lado, los Hash nos dan un mecanismo para poder garantizar la integridad de un mensaje. Fue hace ya tiempo cuando se pensó en una aplicación práctica sencilla de estas dos tecnologías, y comenzó a hablar de Certificados digitales. Pronto fue igualmente necesario el concepto de firma digital, un sistema de autentificar algo.

Una tecnología se crea fundamentalmente pensando en algo. Así, el fundamento del cifrado de datos es simple, que cuando un mensaje sea interceptado no pueda ser leído o comprendido por una tercera persona a la cual no está destinado. Pero esto no impide que el mensaje pueda ser modificado, deteriorado, falseado… Imaginar una carta postal que se escribe con “tinta invisible”. Alguien que la intercepte quizás no pueda leer el contenido real de esta, pero puede coger otra carta, rellenarla con la información que desee y enviarla de nuevo al destino de esta. La pregunta es ¿Como podrá el destino saber si dicha carta ha sido modificada? En el caso de la carta quizás con un sello, una firma… aquí el concepto será el mismo, y podríamos decir que el fundamento de un Hash criptográfico es precisamente la integridad.

A raíz de la necesidad tanto de proteger el contenido de los datos en las comunicaciones, como de autentificar el emisor y el destino, como garantizar la integridad del mensaje, se creó el concepto de “Infraestructura de Clave Pública” (PKI). Este concepto no es más que la aplicación práctica en las comunicaciones de los conceptos que hemos visto anteriormente (y alguno más que veremos en este capítulo): Hash, Cifrado Simétrico y Cifrado Asimétrico.

En este capítulo vamos a intentar comprender básicamente cada uno de los elementos que constituye una infraestructura de clave pública (PKI), y veremos como cada siguiente elemento se hace necesario para el correcto funcionamiento de todo el sistema:

  • Infraestructura básica
  • Certificado: Necesidad de asociación usuario/empresa – Claves
  • Firma: Necesidad de autentificación de todas las partes e integridad


Infraestructura básica

Vamos a intentar aplicar todos los conceptos explicados a un entorno real que deseamos que sea completamente seguro. Para hacer esto tenemos que tener una serie de consideraciones, tendremos que crear una infraestructura en la cual podamos aplicar y hacer viable nuestras necesidades. Hemos dicho que el objetivo será triple a la hora de desear crear un canal de comunicación seguro entre dos partes: El cifrado, la autentificación y la integridad. Empezemos por lo tanto por la primera de las partes, el cifrado.

Lo primero que deseamos es que nuestros datos sean interceptados o no por una tercera persona, esta no pueda acceder a ellos. Hemos dicho que para ello disponemos de dos sistemas muy buenos, el cifrado simétrico y el cifrado asimétrico. Cada uno de ellos tiene ventajas e inconvenientes. ¿Cual es más factible de usar? En principio vamos a pensar que el cifrado asimétrico por una razón muy simple: Además de ser más seguro tan solo requiere de un par de claves (publica y privada) para el número que sea de canales de comunicación a entablar. Realizar esto por medio de un cifrado simétrico sería muy costodo en cuanto a infraestructura, dado que ¿Como crearías una base de datos en la cual se pudiese almacenar cada usuario un número sin fin de keys asociada cada una de ellas a un usuario o entidad diferente? Sería impensable. En cambio mediante el cifrado por clave pública esto podría simplificarse, dado que tan solo es necesario hacer pública una sola key para todos los canales de comunicación posibles, no una para cada canal. En realidad el sistema actual usado es híbrido, pero esto se verá más adelante, para nosotros simplemente decir que se opta de momento por el cifrado asimétrico, en nuestro caso RSA.

Una vez definida la necesidad de un sistema de clave pública y las ventajas que esta nos aporta, aparece el primer problema: Distribución. Hemos explicado que el sistema de cifrado asimétrico es muy eficiente e increíblemente versátil, lo que encripta una key privada lo desencripta la pública, lo que encripta la pública lo desencripta la privada. De ahí la necesidad de que la clave pública sea exactamente eso: Pública. ¿Pero como podemos hacer que cualquier usuario del planeta pueda tener acceso a dicha Key? Aquí es donde comienza a crearse la verdadera PKI, de la necesidad de ir solventando los por menores del camino. La única forma de que cualquier usuario conozca nuestra key pública es disponer de bases de datos en las que se encuentren almacenadas las claves públicas de todos los usuarios. A esto se le conoce como repositorios de claves públicas. Ahora, cualquier usuario puede enviar su clave pública asociada a un correo electrónico, nombre, apellidos… Pero de forma pareja aparece la necesidad de algún control sobre dichas bases de datos. ¿Que sucede si una key ha sido comprometida o ya no es válida? Es necesario por tanto otro Repositorio , en este caso un Repositorio de Revocación de claves públicas. Con estos dos sistemas podríamos garantizar el funcionamiento correcto del cifrado de datos entre dos usuarios. Estos repositorios existen a día de hoy, la mayoría de ellos se encuentran sincronizados con los otros para que todos tengan los mismos datos. Por ejemplo podemos visitar uno de ellos:

Repositorio de Claves Publicas del MIT

En dicho repositorio podemos buscar cualquier cadena de texto, ya sea nombre, apellidos, correo electrónico o ID de la clave:

 

Type bits/keyID     Date       User ID

pub  4096R/B9A35B9C 2009-12-02 Carmen Mendes <cmendes@transnumeric.com>

pub  2048R/F4D68EB5 2009-11-07 María del Carmen Rodríguez Sardiña <mariadelcarmen@gens-osorio.es>

pub  1024D/9BC23DEF 2009-10-15 carmenalves (ola) <carmen.alves.05@formando.gti.pt>
...

Por supuesto si continuamos el link de la KeyID nos topamos directamente con la clave pública de Carmen:

-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: SKS 1.1.0

mQENBEuGtJwBCAD0EM6+cVCIrc2t5CLWhrdwPrTbb4ZbTAKuLjAjULl3K+/usQg7JT0Y+qL6
Z/eGB8krZgzzT77bQHKVAw7NeUZGSMDl+kSIT9k5gx/vWxdyuBUeJODkd7IldiGbW5yhGz92
0LGbQ5weF2GT8DewCtawOsO46baygPIgiVR99vArzNyiX+KFnrUaniVbjbiN8KQY9Nvmdvyz
BU77W5SDRc4LbuOv5GCtnPKjlVQE5JApoelpZi2fiJkH/kKcf4ZTc0nSK8e8duHYB+zrKrxO
ICKHWXWgLBV9aZkoCH35oShK3JpSeimnV3yqwqz2zt32p/JNKO02krPNNIUL+AqVivEfABEB
AAG0SmNhcm1lbiByZXF1ZWpvICh1biBhbWlnbyBtaW8gc2UgbXVyacOzIGNvbmdlbGFkbykg
PGZvMjAxMGNhcm1lbkBnbWFpbC5jb20+iQE+BBMBAgAoBQJLhrScAhsjBQkJZgGABgsJCAcD
AgYVCAIJCgsEFgIDAQIeAQIXgAAKCRBeKv2mzKxFxS0wCACcC6fWZ9IliyKHI8gZBEl3s9Sd
WWlUJo/PNgbzEoq3N/aiy47+ITo/Qax9+PXYUUOH6Zx+CLb4NMyplSo3cESDlg4O/hzkypP6
9Yj6JflHQcqmWfGsWwqf3kiGSWopd8osKdb5bpvKfXI+JKc8Gj5l64JUa0f6BIPIL3/9/Uci
EhnEyHG0b2gJx/f3bybAG+mpBo3VnV/alTfZbX8qnen3Rqg1TPxEyfJjR6E4QrSkeHb8MJp9
ZGO58IWvWAPADJJoK2alKJMRKjeZKFjqcolr4mgNhRhg3iD77SmL1hskwfCinPXGnmimV/Xl
VH0qTX/4Jem6aTG+9aD8u8r3p4LyuQENBEuGtJwBCADALhMeR4PFXzKcxDUzn5yWbckFrz97
ONCbL1C0G/4Wg8fV3t0Vchzg6aKsEYUZSfTe5Ph0rqLWs1cfjgMxrCRYTfzmCffIWBmXixu7
iDuj6bRshY+9F03xFA0X/GJG1bZ/3JuIYTP804UU1/OsH+cFsyj1CnoUNz1zZ5rvm/76VqL1
vBskTyD7cfEPrSTh5HfBu8EatdI0rCPezyzZeE0IhWYg7OChBK6FzkaIEZifpxI7/KSadPNw
NLO0WdLmFhqLqS/Pwt4oCcMxljB9zoO/KGRyvw4nY6BilItFwaIfOjDbrVqDSnG9RZ8+Cevo
TfPi1j1VsBpc113vMqs0g14hABEBAAGJASUEGAECAA8FAkuGtJwCGwwFCQlmAYAACgkQXir9
psysRcVvjgf9F0o3Q3/MbLMriwe9naCXuy2xcceWyZ9vp6ZPm5zoD1Tt7aWRBeFUhk/T88sa
SqcpVqZSNtsdjJl7oHXVcFKeccIebOs826GIMzWgT6kCl2r79RY4W7b0iaPzljH7ayX7Ce3Z
UM7Z0JhCmjH6aszc/dXd3JkHR9cxiY9A1HWrgGzd2RlNCYOVB1kokteVE9+CXCyJwAelSCLR
GAYl33oyxGDKxngVCdeBRxgCeTU0szL7NXMNi3Y2cQCHCiEwTspKXS+wOtos66vgYLYXdgJs
KvW0gau6bUwBouD7aXZOkubfpZ3J85X6KcLuPAQfJlhtuufimJ3y7/+B09c0TD+Osw==
=PqHr
-----END PGP PUBLIC KEY BLOCK-----

Ana desea enviar un mensaje cifrado a Carmen:

a) Ana accede a un Repositorio de Claves pública para obtener la Clave pública de Carmen, para ello busca en la base de datos por “Carmen”. Es posible que haya más de una (puesto que alguna puede estar revocada)
b) Ana con la clave en su poder verifica que esta key no se encuentre en la lista de Revocación. Dado que no está, considera que la key está en uso y es válida.
c) Ana encripta el mensaje con la clave pública de Carmen y le envía el mensaje
d) Carmen desencripta el mensaje con su clave privada.

De este modo Ana puede enviar un mensaje cifrado a cualquier usuario del mundo que esté usando un sistema de clave publica, sin necesidad siquiera que el emisor use dicho sistema, y con la garantía de que dicho mensaje tan solo podrá ser desencriptado por el poseedor de la key privada pareja a la key pública del repositorio. Este sistema logra el objetivo del cifrado de datos. ¿Pero que sucede ahora con la autenficicación?

En el ejemplo expuesto, Ana no puede asegurar de ninguna forma que la clave pública obtenida del repositorio accedido proceda de “Carmen”. Sí, es posible incluso que en dicho repositorio quedase indicado nombre, apellidos, dirección, DNI… pero dado que son repositorios a los que todos tienen acceso, cualquiera podría introducir datos falsos en ellos. Por ejemplo, podría crear una key publica/privada a nombre de otra persona, de esta forma cuando alguien quisiese enviarle a dicha persona un mensaje, lo encriptaría con mi pública. Aquí es donde nace la necesidad de autentificación, de algún sistema por el cual Ana pueda estar convencida que la clave pública obtenida pertenezca a Carmen. Para esto se opta por dos sistemas diferentes, aunque ambos se basan en la misma premisa: Cadena de confianza.

Imaginar que de algún modo se pudiese dar un punto positivo a una clave pública, de forma que cuantos más puntos positivos tenga una Key pública de un repositorio indicase a terceras personas que dicha key es válida. Así por ejemplo yo podría dar un punto positivo a la clave púplica de mis hermanos, puesto se fehacientemente cual es la que pertenece a cada uno de ellos. De este modo, si una tercera persona desease enviarme un mensaje cifrado a mí, se fiaría en caso de duda más de aquella clave pública que tenga más puntos positivos de personas diferentes. Ahora imaginemos que Ana desea enviar un mensaje cifrado al mismísimo Linus Torvalds (El cual espero no le importe que use su nombre para estos ejemplos) para consultarle un bug crítico en el kernel de linux. Lo primero que haría sería acceder al repositorio y buscar por “Linus Torvalds”, dado que ni siquiera conoce su correo electrónico. El repositorio le devolvería lo siguiente:

Type bits/keyID     Date       User ID

pub  1024D/825D2E82 2008-09-03 Linus Torvalds (Teste) <linus@linux.org>

pub  1024D/D080B7A0 2008-07-26 *** KEY REVOKED *** [not verified]
                               Big Gay Al (kay) <letsseesomelove@love.com>
                               REVOKED KEY (u suck) <FUNBO@T>
                               Linus Torvalds (revoke revoke revoke) <werfsdfasdf@fakefakefake.com>

pub  1024D/006D1B6D 2005-11-11 *** KEY REVOKED *** [not verified]
                               Danilo G. Magrini <danilo.magrini@gmail.com>
                               Danilo G. Magrini <danilomagrini@uol.com.br>
                               Danilo G. Magrini <danilo@onclicksistemas.com.br>
                               Danilo Gustavo Magrini (Linus Torvalds) <danilomagrini@uol.com.br>

pub  1024D/8BC6EDEF 2005-11-10 Danilo Gustavo Magrini (Linus Torvalds) <magrini_sp@superig.com.br>

pub  1024D/76E21CBB 2005-04-23 Linus Torvalds (tag signing key) <torvalds@osdl.org>

pub  1024D/CE904A82 1999-11-21 Linus Torvalds <vnixroot@netscape.com>

pub  1024D/449FA3AB 1999-10-05 Linus Torvalds <torvalds@transmeta.com>

pub  1024R/A86B35C5 1996-06-08 Linus Torvalds <Linus.Torvalds@Helsinki.FI>

 

Ana es una chica lista, pero según el repositorio existen 8 posibles claves públicas supuestamente todas correspondientes al bueno de Linus. Sin dificultad Ana descartaría de forma automática las que están marcadas como Revocadas, lo que deja el listado con 6. La primera se podría descartar dado que aunque el correo podría ser legítimo, pone (Test)… podemos imaginar que fue creados con fines de testeo, además, la fecha de la clave es relativamente nueva. La cuarta la excluimos porque el nombre ni siquiera pertenece al de Linus. De este modo tan solo nos quedarían como posibles las 4 últimas. la quinta no obstante puede leerse como (tag signing key) que podríamos suponer que se trata de una clave tan solo para firmas (esto se verás más adelante), así que de momento la descartamos también. Las otras tres restantes podría parecer legítimas a simple vista. Como Ana quiere asegurarse, quiere ver lo que hemos llamado como “votos positivos” de ellas. Si accedemos a la sexta obtenemos la siguiente información:

pub  1024D/CE904A82 1999-11-21            

uid Linus Torvalds <vnixroot@netscape.com>
sig  sig   CE904A82 1999-11-21 __________ __________ [selfsig]
sig  sig   8061A830 2005-05-30 __________ __________ Dan Mundy <harob02@earthlink.net>

sub  2048g/1EEE5A92 1999-11-21
sig sbind  CE904A82 1999-11-21 __________ __________ []

Los votos positivos que hemos nombrado en realidad son firmas, dado que aun no hemos hablado de ellas tan solo imaginamos que son algo así como voto de confiabilidad. En este caso vemos que tan solo posee una firma creada por él mismo “selfsig” y otra firma (voto) creado por un tal Dan Mundy. Ana, que no es tonta, imagina que una persona como Linus, de tener una clave pública en estos repositorios tendrá seguro bastantes votos de confiabilidad. Luego la rechaza.

Esto deja a Ana con dos opciones, las dos últimas. Ana conoce un poco la vida de Linus y le suena que trabajó o tubo relación con trasmeta.com, luego parece un buen punto de partida. No obstante sabe también que Linus es finlandés, nacido en Helsinki, lo que quiere decir que las dos claves que aparecen podrían ser completamente legítimas. Y en este caso las dos pertenecen a él. No obstante, si nos adentramos en la última de ellas, generada nada más y nada menos que en 1996!!, esto es lo que obtenemos:

pub  1024R/A86B35C5 1996-06-08 __________ 

uid Linus Torvalds <Linus.Torvalds@Helsinki.FI>
sig  sig   A86B35C5 1996-06-08 __________ __________ [selfsig]
sig  sig   2A960705 1997-04-24 __________ __________ H. Peter Anvin <hpa@zytor.com>
sig  sig   29BC0185 1998-01-24 __________ __________ george a. r. hill <9x>
sig  sig   0C00E6AD 1998-08-21 __________ __________ Alexander Smith <Sabin84@usa.net>
sig  sig   CCBEA8D2 1998-09-02 __________ __________ Kenyon Ralph <kenyon@san.rr.com>
sig  sig   ACF5A545 1998-12-17 __________ __________ H. Peter Anvin <hpa@zytor.com>
sig  sig   A4679654 1999-01-30 __________ __________ Drizuid <drizuid@drizuid.net>
sig  sig   F0C36E09 1999-01-30 __________ __________ Drizuid <dark-druid@geocities.com>
sig  sig   29B0C351 1999-06-18 __________ __________ Jens S�lwald <j.suelwald@gmx.de>
sig  sig   FEEFE90B 1999-09-15 __________ __________ []
sig revok  FEEFE90B 1999-09-15 __________ __________ []
sig  sig   6470AB26 2000-03-02 __________ __________ Cedric Blancher <cblancher@cmc.fr>
sig  sig   A4C70528 2000-03-15 __________ __________ Alexander Smith <sentinel@freshshell.de>
sig  sig   A24D8B4E 2000-08-10 __________ __________ C�dric Blancher <cblancher@startem.net>
sig  sig   24901EE8 2001-05-31 __________ __________ Simon A Soanes <simon@nullifynetwork.com>
sig  sig   9CD30D3D 2001-10-09 __________ __________ ZC Wong <zcwong@hotmail.com>
sig  sig   01B45CE2 2001-10-09 __________ __________ ZC Wong <zcwong@hotmail.com>
sig  sig   D925418D 2004-04-18 __________ __________ Kevin W. Peters (Guitarman) <guitarman@ntdf.com>
sig  sig   6422D07C 2004-05-23 __________ __________ Fabian Foerster (Root CA) <fabian_foerster@web.de>
sig  sig   0C877B34 2004-05-23 __________ __________ The Root Networks (Root CA) <root-networks@web.de>
sig  sig   FA81F1E6 2004-06-14 __________ __________ Thomas Shea <lrmm@comcast.net>
sig  sig   AAE6022E 2004-12-28 __________ __________ Karlheinz Geyer (RBOS) <karlheinz.geyer@lhsystems.com>
sig  sig   4D34B354 2004-12-28 __________ __________ Karlheinz Geyer (DKB) <karlheinz.geyer@lhsystems.com>
sig  sig   8061A830 2005-05-30 __________ __________ Dan Mundy <harob02@earthlink.net>
sig  sig3  099A79AC 2005-07-12 __________ __________ Konstantin Vinakovsky <kvinakovsky@earthcam.com>
sig revok  AAE6022E 2005-07-28 __________ __________ Karlheinz Geyer (RBOS) <karlheinz.geyer@lhsystems.com>
sig revok  4D34B354 2005-07-28 __________ __________ Karlheinz Geyer (DKB) <karlheinz.geyer@lhsystems.com>
sig  sig   6BEEAF8D 2008-08-02 __________ __________ Kristoffer Warming <heavyhenning@gmail.com>

 

Ana comprende que efectivamente no solo ese puede ser un correo válido de Linus, sino que también lo es su clave pública. Puede comprobar que tiene una serie de firmas en su clave que de un modo reafirman que dicha clave pertenece a él. Se puede observar que 3 de las firmas (votos) están igualmente revocados, pero aun así parece claro que esta es una clave válida y legítima. La última forma pertenece a 2008, lo que nos puede hacer pensar que la cuenta está aun en activo.

pub  1024D/76E21CBB 2005-04-23 Linus Torvalds (tag signing key) <torvalds@osdl.org>

Pertenece también a él, es un correo que es más que conocido por programadores y otros que frecuentan listas de correos del kernel de linux, lo que sucede es que aparentemente por ese nombre podemos deducir que Linus la usa tan solo para firmar, y no para encriptar (esto se verá como he dicho más adelante)

Llegados a este punto, Ana ha logrado dos objetivos. El primero cifrar los datos y el segundo asegurarse que dichos datos están cifrados efectivamente y tan solo para Linus Tolvards, gracias al anillo de confianza que generan estos votos (que no son sino firmas digitales). Pero aun le queda a Ana un problema. La integridad. Como puede estar Ana convencida que el mensaje que reciba Linus no haya sido modificado por un tercero. Ana desea que en el peor de los casos y que este haya sido modificado, Linus pueda conocer que este ha sido modificado, así pueda contactar de nuevo con Ana y solicitarle de nuevo el envío del mensaje legítimo.

Después de un rato de meditación, Ana recuerda la funcionalidad del Hash criptográfico. Ana no podrá garantizar nunca que el mensaje llegue sin modificación alguna, pero puede garantizar que de ser modificado Linus se percatará de ello. ¿Como? Ana recuerda que si aplica por ejemplo un Hash SHA-1 al mensaje cifrado y envia tanto el hash como el mensaje cifrado, Linus podría verificar si el hash especificado por Ana y si coincide con el Hash real del mensaje. Una tercera persona sino, podría interceptar el mensaje, crear un mensaje nuevo, cifrarlo con la key Pública de Linus y enviárselo en nombre de Ana. No obstante, según este esquema una tercera persona podría igualmente interceptarlo, y como conoce el Hash que ha usado Ana, tan solo tendría que redactar el mensaje, encriptarlo, calcularle el nuevo Hash y enviar los datos a Linus. Es aquí donde aparece la necesidad de la firma digital.

Ana ha comprendido las técnicas de los hackers que quieren modificar su mensaje cifrado (sin saber siquira que hay dentro de dicho mensaje) así que ha descubierto la solución definitiva. Ana, que también tiene usa sistemas de clave pública tiene su propia clave pública y privada:

a) Ana redacta el mensaje y lo encripta usando la clave pública de Linus
b) Ana calcula un Hash SHA-1 al mensaje encriptado y este mismo hash lo encripta con su clave privada (A esto se le llama firma digital)
c) Ana envía tanto el mensaje cifrado como la firma a Linus.
d) Linus accede al repositorio de claves públicas y busca la correspondiente a Ana y a dicha dirección de correo (del mismo modo que hizo Ana). Encuentra la que busca con muchos “votos” a su favor, y con la clave pública de Ana es capaz de desencriptar el hash de Ana. Linus calcula el Hash SHA-1 al mensaje cifrado y verifica que ambos valores coinciden!! Luego el mensaje ha conservado su integridad y tanto Ana como Linus han sido autentificados el uno al otro y establecido un canal seguro cifrado.

Si un tercero intentase de nuevo interceptar el mensaje de Ana, cualquier cambio que produjese en él destruiría el hash del mensaje, Linus al descifrar el Hash de Ana comprobaría que este no coincide con el Hash del mensaje, luego comprende que el mensaje ha sido comprometido y rechaza la comunicación. El atacante podria redactar un nuevo mensaje, cifrarlo, calcularle el hash y firmarlo (encriptarlo con su clave pública), pero entonces Linus sabría perfectamente que la clave pública necesaria para desecifrarlo no correspondería a la Ana!! Sino a la del atacante, con lo que jamás la aceptaría. Es aquí donde radica la importancia del círculo de seguridad, la necesidad de saber fehacientemente que una clave pública pertenece a quien dice pertenecer.

Este esquema PKI es básicamente lo que se lleva a cabo en los sistemas de clave pública PGP/GPG, pero ahora veremos las herramientas para el esquema SSL/TLS.

 

Certíficado Digital

Ahora sí es la primera vez que lo nombramos. Un certificado digital no es más que un documento, un archivo que identifica/asocia a un usuario con su clave pública. Cuando veíamos los repositorios de claves públicas y realizábamos una búsqueda, cada entrada tenía asociada un nombre, descripción, clave pública y firmas (los votos que hablábamos) de verificación de otras personas. Un certificado es lo mismo (con algunos matices).

El esquema PKI anterior (llamado Web of Trust) tiene el problema de la confianza, de la legitimidad. Es un buen paso hacia delante el firmar las claves ajenas para avalar su legitimidad, y está bien para trámites particulares, personales, encriptar archivos, correos a familias y amigos… pero si una organización mundial, un gobierno, un particular o una empresa quieren garantizar que dicha clave pública pertenece sin lugar a dudas a quien dice pertenecer, es necesario un sistema más fiable. Es aquí donde aparece la “Autoridad de Certificación” (CA). Se van a continuar firmando los certificados sí, pero no por cualquier persona o grupo de ellas. Un certificado Digital asocia una serie de datos personales a una clave pública, y será un tercero, llamado Autoridad de Certificación, quien garantice que esos datos corresponden a dicha clave pública. Visto de otro modo, se trata de eliminar todas las firmas y sustituirla tan solo por una, una entidad, empresa, gobierno… cuya firma tendrá mucho más valor que cualquier otra, dado que posiblemente se ha encargado previamente de verificar y asegurar que los datos son correctos.

Los CA de máximo nivel se les llama CA raíces o root. Existen CA que delegan autoridad a otros CA secundarios para permitirles otorgar y firmar otros certificados. Esto se debe a la cadena de confianza. Yo como máxima autoridad certifico a una empresa como CA secundaria de la cual tengo plena confianza, permitiéndole emitir y firmar certificados a ellos mismos. Si cualquiera quiere verificar un certificado emitido por un CA secundario o terciario, se realizará una verificación ascendente, primero al CA superior, el certificado de dicha CA se verificará por el CA por encima… hasta llegar al CA raíz, el cual emite él mismo su propio certificado.

Los CA son los que emiten los certificados, y al firmarlos les otorgan plena legitimidad dado que todos nos fiamos de ellos, dado que son la máxima autoridad de certificación. Podemos decir que los CA son también esas bases de datos de claves públicas/certificados de cada usuario. Pero el CA no es la única autoridad que existe. Por otro lado suele ser necesaria (no obligatoria) la presencia de la “Autoridad de Registro” (RA). El papel de un CA puede acabar aquí, y encargarse tan solo de la emisión y firmado. Muchas veces cuando se desea cotejar/verificar si un certificado es correcto, es el RA quien se encarga de verificar dicho certificado, siendo él el que conecta con el CA. Otra figura menos usada es la “Autoridad de Validación” (VA), la cual tendría un papel similar, verificar si el certificado es válido atendiendo a fechas de tiempo y otros datos. Aun así, como digo, lo normal es ir unificando las autoridades de verificación, y de paso las comunicaciones son más eficientes. Así el mismo CA actúa como RA y como VA. Hace unos años los CA raíces eran muy pocos, lo que hacía muy útil estas autoridades intermedias. Cada vez son más los CA raíces y los sistemas más eficientes, siendo innecesaria la presencia de otras autoridades intermedias. Muchos de los lectores conocerán el nombre de algunos de ellos, actualmente el listado de CA raíces debe de rondar las 90 entidades (sin contar con los CA estatales, como CA de países, aunque estos no suelen considerarse como “universales”. Entre ellos los más importante con diferencia son: VeriSign, Thawte, GoDaddy, GeoTrust, RSA Security Inc (la empresa)…

En los tiempos actuales, no es raro ver como gobiernos, grandes instituciones o multinacionales están considerados también como CA, lo que sucede es que normalmente estos CA no emiten certificados a cualquier persona. Por ejemplo, el gobierno español tiene al menos dos Autoridades de Certificación, la FNMT (certificados CERES) y La dirección General de Policía (Certificados para el DNI-e). Pero estas dos instituciones tan solo emiten certificados a los que tenemos nacionalidad española. Otro ejemplo de esto podría ser Intel o Microsoft. Ambos están considerados como CA raíz, pero no se dedican al negocio de los certificados digitales. Esto le permite a estas grandes multinacionales no depender de terceros, ahorrar costes y gestionar ellos mismos sus propios certificados, aunque evidentemente tan solo usan dichos certificados para ellos mismos, sus servidores, sus empleados quizás… por eso podemos dividir estos dos grandes grupos como aquellos CA comerciales y aquellos que no lo son.

Con esto, el esquema anterior PKI se modifica ligeramente y es el CA, el RA o el VA quien valida o garantiza la legitimidad del certificado.

Hay que destacar que no existen dos certificados, uno que sea público y otro que sea privado. El certificado es tan solo el vehículo de la clave pública. Es cierto que los certificados personales almacenados en el equipo se “guardan” con la clave privada junto a este, lo cual es completamente lógico, puesto que sin clave privada no podríamos firmar o desencriptar. En realidad esto no es del todo cierto, dado que las claves privadas de estos certificados suele estar guardadas en un anillo de seguridad del sistema/equipo. Esto no obstante ocasiona un problema de seguridad importante dado que si alguien se hace con la clave privada, el sistema quedaría completamente expuesto. Es por ello que cuando se requierer una seguridad avanzada, tanto certificados personales como las claves privadas, jamás serán almacenados en un equipo, sino en soportes extraíbles como un pendrive (en el peor de los casos) o una SmartCard (Tarjeta Inteligente) en el caso ideal, o incluso un dispositivo TPM. Esto quiere decir que nuestra clave privada residirá en nuestro DNI-e o tarjeta CERES o… protegida además por un PIN por si es extraviada o sustraída. Cuando se requiere su uso es necesario un lector de tarjetas y el software adecuado para tomar de esta la clave privada y el certificado.

El Certificado no solo indica el nombre y apellido de quien representa, sino que incluye información del CA que lo ha emitido, algoritmos de cifrado y hash que usa, fecha de revocación, validez, tipo de certifiado… toda esta información es necesaria. Por ejemplo el certificado de identificación o cifrado de un servidor no tiene nada que ver con un certificado de cliente que podamos usar nosotros, o el certificado raiz de un CA es diferente a los otros dos. Por otro lado no todos los certificados se emiten para todos los propósitos. Lo normal es emitir los certificados con ciertas características. Por ejemplo, si se desea usar un certificado para cifrar correo electrónico será necesario que el certificado especifique una dirección de correo, y este certificado quedará anclado a él. Otro buen ejemplo es un certificado con unas características concretas para el control de acceso de una empresa o para cifrar datos en un equipo. Así, nuestro DNI-e por ejemplo tiene dos funciones principales, autentificación y firma (hablaremos más detenidamente del DNI-e en otro capítulo).

Vamos a ver unos certificados de ejemplos: Un certificado de un servidor para SSL/TLS (Gmail), un certificado CA raíz (VeriSign) y un certificado personal para identificación SSL/TLS, firma y cifrado de correo que no de datos (Mi Certificado CERES):

Hay que decir que estos datos son totalmente públicos, cualquiera que acceda a gMail o descargue el certificado de gMail podrá verlo. Firefox divide el certificado en dos pestañas. La primera es un resumen sobre el emisor, a quien representa y si el certificado es válido para los propósitos marcados (en este caso el propósitos es para un servidor SSL). Recordar que cada vez que un certificado es usado, lo normal es verificarlo. ¿Cómo? Verificando la firma de la entidad firmante. Podemos ver en la primera pestaña que el emisor es Thawte (que es el CA de dicho certificado), que está a nombre de Google Inc para la web mail.google.com (gMail). Se puede ver también la fecha, que aunque no hemos hablado de ella es importante, ya que cuando se emite un certificado este suele tener un tiempo limitado. Tras el cual, el certificado pasa a ser revocado (anulado) y se emite otro (normalmente antes de que expire) con nuevas claves privadas y públicas, esto se hace por seguridad evidentemente.

La segunda pestaña desglosa completamente el contenido del Certificado. En caso de este certificado, Firefox nos muestra en la parte superior la jerarquía de CA que intervienen en dicho certificado, es decir la cadena de confianza. Así, el certificado de google para mail.googl.com es emitido por el CA “Thawte SGC CA”. Este CA no es un CA raíz, sino un CA secundario. El certificado de este CA a su vez es el que ha sido emitido por el CA raíz “Verisign Class 3 Pubblic…”. Por último se muestra la clave pública contenida en dicho certificado.

 

El primer certificado pertenece a un certificado raíz de VeriSign, el mismo que estaría arriba del todo del certificado de gMail para la web. En este caso el uso que se indica es el de “Status Responder Certificate”. Es decir, tan solo es usado prácticamente para atender a las peticiones OCSP que pueda recibir de sus CA secundarios, es decir… verificar si los certificados están o no revocados. En este caso no se considera un CA dado que el papel de verificación de CA lo realizará el CA que esté a su servicio. Este certificado raíz fue el que emitió/validó el certificado de “Thawate SGC CA”, y es este último quein actuó realmente como CA del certificado de mail.google.com. El certificado CA intermedio será por tanto realmente el que en su descripción de uso rece: “SSL Certificate Authority”, puesto que el certificado Raíz tan solo atiende a peticiones de revocaciones. Se puede observar que efectivamente es un certificado raíz dado que el emisor (Issued By) y el destino del certificado (Issued to) no se encuentran presente, es él mismo emisor y destino, está firmado por él mismo.Si vemos la fecha por otro lado de expiración, vemos un intervalo muy grande, un certificado ahora con más de 14 años de antiguedad, que usa un algoritmo de hash MD2, un hash ya muy antiguo.

Por último tenemos un certificado de CERES. He preferido poner este en vez del DNI-e porque este es más útil, tanto y cuando además de poseer las características de autentificación en internet (Cliente SSL), permite también la firma de correo (Email Signer) y su Encriptación (Email Recipient). Podemos ver que el emisor es la FNMT, y dado que mi navegador tiene instalado el certificado Raíz de estos y considerado fiable, el certificado de CERES lo es también, podemos leerlo arriba: “This Certificate has been verified…” Por motivos de seguridad he eliminado mi nombre, DNI y esas cosillas.

 

Firma Digital

En realidad poco más o menos ya se ha comentado que es y cual es su utilidad. Cuando explicábamos una PKI, exponíamos que cada clave pública se “votaba” para que los otros usuarios pudiesen así garantizar que era legítima. Esto es realmente una firma. Una firma tiene la característica de no repudio, es decir, una vez se ha firmado algo un usuario o una entidad no puede desquitarse de ello, dado que la firma lo identifica a él de forma irreversible, sin que este pueda negar que lo ha hecho.

Las firmas digitales usan de forma conjunta dos tecnologías, la inviolabilidad de un sistema de cifrado asimétrico tipo RSA y la integridad de datos que ofrece un Hash criptográfico como SHA-1 o MD5. Si un usuario desea cifrar un documento o un mensaje para que tan solo podamos ser capaces de descifrarlo nosotros, tan solo tiene que cifrarlo con nuestra clave pública, y tan solo nosotros poseedores de nuestra clave privada podremos descifrarlo. Pero esto puede usarse de manera inversa. Si yo cifro algo con mi clave privada, la clave pública lo descifra. Dado que todos tienen acceso a mi clave pública, todos pueden descifrar aquello que yo cifre con mi clave privada. ¿Pero entonces para que vale esto? Porque un certificado garantiza la asociación de una clave pública a una persona física. Luego quien descifre algo con mi clave pública obtendrá un contenido que tiene la certeza fue cifrado solo por mí. Y por parte del Hash, otorga integridad al mensaje. El proceso es simple:

a) Se calcula un Hash criptográfico al mensaje, documento… a firmar, por ejemplo un Hash SHA-1.
b) Ahora se encripta por medio de nuestra clave privada dicho Hash, lo cual obtenemos un Hash cifrado.
c) A partir de este momento, al documento se le incrusta (adjunta) la firma. El destinatario, se topará con que existe una firma de dicho documento, con su certificado público correspondiente, y por supuesto con las validaciones pertinentes. El destinatario puede descifrar el hash y obtener el Hash que aseguró el remitente que era el idóneo. El destinatario calcula el mismo Hash al mensaje recibido. Si los dos Hash coinciden, el destinatario comprende que el mensaje es legítimo y que no ha sido modificado de ningún modo.

Una forma digital puede usarse para varias tareas. Por ejemplo, evidentemente como sustituto natural de nuestra firma física. No obstante ya hemos hablado que se usa para los certificados. Los certificados que nos emiten los CA deben de estar firmados por estos. La firma de estos en nuestro certificado funciona del mismo modo. Cuando se verifica un certificado, entre otras cosas como comprobar la fecha de validez o las listas de certificados revocados, se verifica que la cadena de confianza es correcta. ¿Esto que implica? Ir verificando uno a uno todos los certificados implicados en un certificado. Esto es verificar la firma del firmante de nuestro certificado, lo cual para ello es necesario verificar que el certificado de este CA está firmado por otra CA que sea igualmente válido… así hasta llegar al CA raíz. Si en cualquier lugar de la cadena falla la verificación, la cadena entera se rompe y el certificado no puede garantizarse como seguro.

Otro uso común es la firma de un código. Esta es una práctica cada vez más expandida en el mundo del software. Un método de proteger un sistema operativo frente a ataques, como pueda tener Windows Vista o Windows 7, es que los drivers deben de estar firmados obligatoriamente por Microsoft (en este caso), de forma que esto garantiza que los drivers no son dañinos y son legítimos. Esto puede verse también en las partes más críticas del sistemas, en las que los archivos o el contenido más sensible para el correcto funcionamiento del sistema se firma de forma que el propio sistema no permite su ejecución si la firma no es válida. El problema que ocasiona esto no obstante es que se puede hacer un uso intensivo de esto para evitar la libertad. Por ejemplo el iPod Touch/iPhone, en el que cualquier contenido que se desee ejecutar, debe de estar obligatoriamente firmado por Apple, si no lo está no se puede ejecutar. Esto implica que (sin JB) tan solo las aplicaciones aprobadas del AppStore pueden ser usadas, al margen de que pudiese ser posible o no instalar otro tipo de aplicaciones, al margen del degradamiento de rendimiento por tener que estar continuamente verificando las firmas. Desde mi punto de vista la diferencia del buen uso y el abuso es la intencionalidad. Proteger con una firma una bios o un bootloader tiene un sentido muy simple, es una parte crucial del sistema y cualquier virus o modificación dañina produciría que el sistema sea inutilizado, lo cual implica que es positivo. Pero debería de ser una opción, no una obligación. Por ejemplo, se dijo mucho sobre los drivers de Windows x64 y que nadie podría crear drivers para ellos dado que todos tienen que estar firmados por Microsoft. Esto no es tampoco tan así. Se pueden instalar drivers firmados por uno mismo si se quiere, lo que pasa es que el sistema nos advertirá sobre la procedencia del certificado y categorizará el driver como no seguro, avisándonos del peligro que ello implica. Pero a fin de cuenta la libertad es del usuario.

Lo habitual por tanto es ver una firma digital como un documento adjunto en un correo (extension p7s), incluida en el mismo cuerpo del mensaje en el caso de usar PKI como PGP/GPGo como un “añadido” a un documento. Al final del todo veremos aplicaciones prácticas de todo ello de todas estas cosas. De cara a un gestor de correos o cualquier otro programa que acepte contenido firmado, simplemente sabrá como interpretarlo y verificar dicho contenido.

 

Visto todo esto podemos hacernos una imagen de lo que es un certificado digital y la firma electrónica:

a) Ana descarga el certificado de Carmen, lo ha descargado del servidor LDAP de la empresa (o de la web de Carmen). Al instalarlo en su equipo (y sin que ella lo sepa) el certificado de carmen es comprobado. Dado que el certificado de Carmen está firmado por VeriSign, el equipo de Ana tan solo tiene que verificar que la firma de VeriSing es válida. Dado que el certificado raiz de VeriSign está incluido en el equipo, el equipo de Ana desencripta la firma de Verisign del certificado de Carmen con la clave pública que se encuentra en el certificado raiz de VeriSign. El equipo de Ana obtiene así el Hash del certificado de Carmen, el cual coincide a la perfección con el propio certificado, luego Ana está convencida de que el certificado que tiene en su poder es sin duda el de Carmen.
b) Ahora que Ana está convencida, redacta el mensaje y lo encripta con el certificado de Carmen y lo firma con su clave privada. Lo envía a Carmen.
C) El mensaje llega a Carmen y lo primero con lo que se topa es la firma. El gestor de correo busca la clave pública perteneciente a dicho correo electrónico accediendo posiblemente al repositorio del CA emisor y el nombre y apellidos de Ana. Carmen no se fia de que sea Ana, pero el certificado que ha encontrado efectivamente tipifica dicho correo electrónico y dichas credenciales, y está emitido y firmado por la FNMT (se verifica la firma de la FNMT, que a su vez verifica el certificado de Ana). Cuando está seguro del certificado de Ana, desencripta la firma con él, dado que la clave pública de Ana desencripta el hash que fue encriptado con la clave privada de esta. Carmen verifica la firma y con su clave privada desencripta el mensaje y lo lee.

Seguridad: Encriptación y Autentificación. Capítulo Segundo -> Cifrado de Datos

ATENCION: Los ejemplos que se van a mostrar y “tutoriales” tan solo tienen carácter educativo. En ningún aspecto comparto filosofías de invasión a la intimidad, ataques contra un sistema informático o cuestiones similares. En la medida que sea posible siempre se usarán ejemplos y formas que puedan ser usados por cualquier persona, de forma que pueda verificar los contenidos escritos. No obstante, por motivos más que obvios, materiales como contraseñas, nombres de usuarios o de hosts, serán omitidos o modificado en las capturas de pantallas realizadas (o las lineas escritas). Es decir, los ejemplos serán completamente reales, los datos mostrados a vosotros necesarios para poder pertrechar estos ejemplos no siempre lo serán (Sí lo serán los resultados). Para que esto conste de forma clara, todo material sensible modificado o falso estará resaltado en ROJO. Por motivos de seguridad, todo el material que sea expuesto aquí (exceptuando software propietario o libre, citaciones expresas o código de terceros) tanto texto, imágenes y código son propiedad del autor y está completamente prohibido su reproducción completa o parcial en otros lugares, espero que se comprenda.

 

Cifrado de datos

Este no es un término nuevo, y desde tiempos inmemorables es algo que se ha ido haciendo de un modo u otro. Y es que seamos honestos… no nos suele gustar la idea de que puedan invadir nuestra intimidad o interceptar cartas, mensajes, ideas… que van hacia otra persona. Evidentemente esto toma una importancia mayúscula cuando esta información es sensible o de suma importancia. Quzás el primer gran ejemplo de criptografía en el ámbito de las comunicaciones fue sin duda la máquina Enigma.

Para quien no lo sepa, la máquina Enigma fue un dispositivo similar a una máquina de escribir diseñada allá por los años 30, siendo famosa por ser usada por los Alemanes durante la Segunda Guerra Mundial. Era un dispositivo creado con inteligencia. Digamos que poseía tres discos con 26 posiciones cada uno. En cada una de esas posiciones se mapeaba una letra. Cada letra de cada disco a su vez se encontraba conectada con el disco vecino, y dependiendo de la posición inicial de cada uno de los discos, la letra era mapeada de disco en disco en una o en otra. Se diseñaba de tal modo que al presionar una tecla de la máquina, esta quedaba asociada con una letra mapeada del primer disco. En el primer disco la letra se mapeaba a la letra de salida del primer disco (que no correspondía a la de entrada) y en dicha salida se conectaba el segundo disco. El segundo disco tomaba de entrada la salida del primer disco e igualmente que como hacía este, internamente esa letra de entrada la mapeaba a la salida. El tercer disco hacía lo propio, tomaba la letra de salida del segundo y según su posición en dicho momento la transformaba en otra diferente a su salida. Despues de todo esto, un 4 disco (no obligatorio) hacía que existiese un camino de retorno, de forma que se pasase de nuevo por el tercer disco, despues por el segundo y después por el primero. La salida se conectaba a una bombilla que indicaba la letra codificada. Para evitar separaciones de palabra, todo el mensaje era enviado sin espacios.

Posiblemente fue la primera máquina seria para cifrar comunicaciones. Hay que decir que, según dicen, gracias a que la alianza fue capaz de desencriptar la mayoría de las comunicaciones de los alemanes (gracias a que pudieron romper en gran medida el sistema de Enigma) la guerra duró dos años menos de lo que podría haberse alargado. Un buen ejemplo sin duda alguna de criptología.

 

Para nosotros es cosa del pasado. Vivimos en un mundo digital y un mundo en el que las comunicaciones juegan un papel a día de hoy imprescindible. Por lo tanto es de sentido común que existan sistemas que podamos considerar seguros tanto para almacenar datos de forma protegida como para ser capaces de crear canales seguros de comunicación entre dos puntos cualquieras del mundo. Precisamente porque las comunicaciones se han convertido en algo imprescindible y de uso constante, no podemos hacer oídos sordos y pensar erróneamente que nuestros datos no son de la importancia de nadie. Dado que los canales de los que hacemos uso son públicos, nuestra información, nuestros datos están expuestos a todos. Puede que a nadie le importe que otros puedan saber en un momento dado en que blog escribe, que vean las fotos que tienen guardadas o las recetas archivadas. Pero seguro que a nadie le gustaría que humeen en su correo, en sus cuentas bancarias, en todo aquello que pueda ser de índole personal. Lo que pasa es que se presupone que todo es seguro y que no existirá nunca una intervención externa… y esto no es así. Como vimos con el Spoofing o como veremos en otros artícuos como el Sniffing, la intención rara vez encaja con la realidad.

Por todo ello vamos a introducirnos un poquito en los sistemas reales de protección que podemos encontrar a día de hoy. Y digo reales porque posíblemente gracias tan solo al cifrado de datos es posible garantizar una intimidad a la cual tiene derecho todas las personas. No vamos a estudiar la máquina enigma de ningún modo, vamos a ver los dos sistemas de cifrado que disponemos en la actualidad, cada uno con sus pros y sus contras, claro está:

  • Cifrado Simétrico
  • Cifrado Asimétrico

 

Cifrado Simétrico

Un cifrado simétrico no es más que algún sistema por el cual se encripta un contenido aplicándole una clave (o key, del ingles llave) y se desencripta usando la misma clave. Podemos pensar de un modo más específico en una contraseña, pero esta no es más que una particularidad de un cifrado simétrico. Por ejemplo, la máquina enigma era un dispositivo de cifrado simétrico, en el que la key era la posición inicial de los discos y el cableado interno que mapeaba las teclas a los discos. Se usaba por tanto la misma disposición si se deseaba recuperar el mensaje original. En la era digital, nuestras key suelen ser lo que comunmente llamamos “contraseñas”, aunque no todas las contraseñas son para cifrar. Así por ejemplo llamamos contraseña a la cadena de caracteres que debemos de teclear para poder encriptar un documento, pero también llamamos contraseña a la cadena de caracteres que debemos de teclear para acceder a nuestro correo, y no se usa en modo alguno para cifrar nada, solo como método de control de acceso. En cualquier caso, esta key (no usaremos el termino “contraseña”) en los cifrados simétricos sería la misma para encriptar un dato que para desencriptarlo.

Como vimos en su momento con los Hash, podríamos suponer que con el cifrado simétrico lo que sucede es algo similar. A un dato de entrada se le aplica una función que depende de una key para producir una salida. Pero a diferencia de los hash, la encriptación no es un camino único, es decir, la salida puede convertirse bit a bit exactamente igual a la entrada cuando el mensaje se desencripta. Esto implica que la función que sea aplicada a la entrada no será sino una serie de modificaciones que se realizarán a los datos de entrada para ocultarlos. Esas modificaciones dependerán íntegramente de una key.

Según el sistema usado por el sistema de cifrado, se puede clasificar dos tipos de cifrados simétricos: Cifrado de bloques y cifrado de flujo. Pese a que pueda ser más o menos complicada la matemáticas detrás de cada algoritmo de cifrado, no lo es tanto comprender su funcionamiento.

 

Primero veamos el cifrado simétrico de flujo. El cifrado de flujo se pensó idealmente para aquellas tareas en las que se desea cifrar algo que se está generando en tiempo real. Es decir, en un principio pensado para las comunicaciones. Esto tiene su lógica, si deseamos encriptar un archivo de 20MB en disco por ejemplo, conocemos a priori no solo el tamaño completo del archivo, sino también cada uno de sus byte. En cambio cuando los datos a transmitir son en tiempo real (por ejemplo) el modelo anterior no vale, tan solo podemos ir codificando pequeños fragmentos de un todo, fragmentos tan pequeños como bytes o incluso bits. Es decir, cada byte (por ejemplo) que se genera, se encripta y se envía. El fragmento enviado por tanto tiene significado propio, puesto que aunque pertenece a un todo, el mismo byte (en este caso) se desencripta directamente en el destino.

Pese a la complicación que esto pueda parecer, es relativamente simple en concepto. La idea es poder cifrar unidades mínimas de contenido sin que estas dependan de nada más. Pero esto crea un problema… Si la misma key fuese usada para todos los bytes, sin siquiera conocer la key sería muy facil atacar un cifrado en flujo, dado que las unidades codificadas son muy pequeñas, sería fácil encontrar mensajes o partes de estos, patrones… Para evitar esto lo que se hace con los cifrados de flujos es generar también un flujo constante de keys. Esto suena raro… el algoritmo de cifrado simétrico de flujo aplica una serie de operaciones matemáticas “seguras” para generar a su salida un flujo constante de bits, no predecibles claro está, que a su vez son los que son usados para cifrar a su vez el flujo de datos. Vamos a ver un ejemplo sencillo de esto aplicando posiblemente uno de los cifrados más básicos que existe, el cifrado XOR. XOR es una operación lógica que dice lo siguiente:

style=”text-align: justify;”>Si A = B => A XOR B = 0. Es decir, se puede expresar como A XOR A = 0
style=”text-align: justify;”>Si A != B => A XOR B = 1. Es decir, se puede expresar como A XOR 0 = A

Al igual que con los hash, imaginemos una función tal que F (key) = Kflujo

Si tenemos lo anterior en cuenta, ahora imaginemos dos flujos de datos constantes de bits:

Datos para Enviar Mensaje XOR Key Datos Enviados
Mensaje Original: 10100111 0 1011001
Kflujo: 11001011 1 1100100
Mensaje Final: 10100111 1 0111101

Es decir, el flujo constante de datos a enviar se combina mediante una operación XOR con un flujo de datos constantes también generado por una Key inicial gracias a un algoritmo dado. El receptor en nuestro ejempli tan solo tendría que generar el mismo flujo de datos desde la key original y aplicar la misma operacion XOR a los datos recibidos, de ese modo el mensaje original se reconstruiría. De este modo, a partir de un cifrado simple y lleno de problemas como pueda ser un cifrado XOR, se logra que sea consistente gracias al flujo constante de bits derivados de la key original.

No obstante, por regla general los cifrados en flujo son mucho menos robustos que los cifrados en bloques, y estos a su vez pueden actuar como cifrados en flujos, lo que poco a poco deja a los cifrados simétricos de flujo en desuso. No obstante, a día de hoy continúan siendo una fuerte columna vertebral de las comunicaciones, siendo su buque insignia el cifrado RC4. Aunque es un cifrado que ya no podríamos considerar seguro dado a los ataques pertrechados hacia él con relativo éxito, continúa siendo un cifrado extremadamente simple de implementar y de procesar, lo que lo hace ideal para tareas en las que la seguridad a lo mejor no es crucial, pero si importante. Por ejemplo, RC4 es el cifrado que usan las redes WIFI que usan WEP, el algoritmo de cifrado es RC4, y como todos sabemos WEP es un sistema a día de hoy completamente roto. Otros ejemplos de RC4 fue su uso (cada vez menos habitual) en certificados digitales (ya veremos esto más adelante). Y posiblemente los amantes de las redes Torrent podrán ver en muchos de sus clientes la opción de cifrar todo mediante RC4. Como vemos, aunque no nos otorga un grado de seguridad completo, para muchas tareas es bastante útil. En la actualidad existen otros cifrados de flujos más seguros que RC4, como por ejemplo las alternativas eStream. Personalmente no creo que vuelvan a ponerse de moda los cifrados en flujos, y que se continuará con la tendencia de los cifrados en bloque.

 

El cifrado simétrico en bloques difiere en concepto del cifrado en flujo. En este caso no se pretende a priori cifrar bit a bit un contenido, sino aplicar a un bloque de un tamaño preestablecido una serie de transformaciones (evidentemente reversibles) para dar como resultado una salida encriptada de dicho bloque. La pregunta podría estar entonces, que si dicho bloque es pequeño y el cifrado de flujos actúa sobre unidades “grandes”, ambos conceptos podrían ser iguales. Y esto es cierto.

En el caso del cifrado en flujo lo importante es la forma en la que se generará el flujo de keys y el sistema que se realizará para “combinar” los dos flujos. Aquí el sistema es mucho más complejo y sólido normalmente. Normalmente un mensaje que se quiere cifrar es dividido en bloques (de ahí su nombre) de tamaños de 64-256 bits cada uno. Lo ideal por tanto es siempre encriptar un contenido que sea cientos de veces dicho número, con lo que se tendrían cientos de bloques independientes. Cada bloque suele funcionar del mismo modo, las mismas operaciones que se aplican a uno se aplican a otro. No obstante, al igual que sucediese con los cifrados de flujo, lo normal es que la key original tan solo sea key del primer bloque, siendo la key del resto de ellos una key derivada ya no solo de esta, sino del contenido encriptado, lo cual hace ya de por sí complicada su “búsqueda”. La diferencia por lo tanto entre los diferentes cifrados de bloques radicará en esas transformaciones realizadas dentro de los bloques para obtener el resultado.

Normalmente, a estas transformaciones se les denominan “Etapas”, y no es extraño ver cifrados de bloques con varias de ellas. Por ejemplo el Cifrado AES consta de entre 10 a 14 etapas, dependiendo de la longitud de su Key. Al final de todas las etapas de cada bloque, se genera el mensaje cifrado, que en contraposición con el cifrado de flujo, aquí normalmente cada bloque cifrado es dependiente de todo su bloque, no existe una correspondencia bit cifrado – bit descifrado.

Pese a que cada algoritmo es diferente, los cifrados de bloques igualmente tienen diferente modos de operación. Cada uno de ellos no difieren por el tipo de transformaciones aplicadas, sino más bien por las interacciones entre sus bloques. Así por ejemplo, el sistema más sencillo de cifrado por bloques sería aplicar a cada bloque una función matemática tipo Fbloque(Key) = Bloque_Cifrado. Es decir, a cada bloque se le aplicaría siempre la misma key de forma independiente. Este esquema se contempla, y se llama sin ir máss lejos ECB.

Un paso más allá sería algo similar a lo que se ha visto con el cifrado de flujos. En este caso cada bloque no es independiente. En el modo CBC el bloque cifrado se combina mediante una operación lógica XOR con el bloque aun sin cifrar del siguiente bloque, y el resultado será el bloque que, ahora sí, se pasará a cifrar. De este modo simple, se logra una dependencia completa de cada uno de los bloques, haciendo inviable muchos ataques criptográficos.

Aunque existen otros sistemas de funcionamiento de los cifrados de bloques, la mayoría aplican el concepto explicado para CBC (Cifrado de bloques en cadena) pero en diferentes partes. Por ejemplo, se podría realizar la operación XOR en vez de entre el bloque cifrado y el bloque siguiente sin cifrar entre el bloque sin cifrar y el bloque cifrado de un mismo bloque y realizar a continuación otra XOR con el bloque sin cifrar siguiente, y a esto se le llamaría PCBC.

 

Estos modos de funcionamiento que pueden parecer no tener importancia, la tienen y mucha. Un test bastante conocido para comprobar la resistencia de un sistema de cifrado frente a la posible repetición de patrones, es la codificación de una imagen. Una imagen suele tener patrones que se repiten constantemente, es decir, en una imagen suelen existir zonas uniformes que pueden tener el mismo contenido. Luego una imagen es un ejemplo perfecto para atacar a un cifrado. ¿Como se realiza esto? Una imagen no son más que puntos distribuidos uniformemente sobre toda una superficie, cada cual con un color. Si quisiésemos almacenar una imagen en nuestro sistema, el método más simple sería simplemente tomar cada punto de la imagen de forma consecutiva e ir añadiéndolo a un archivo binarios simplemente especificando su color. Esto se comprende mucho mejor con un ejemplo. Pensar en que tenemos una imagen de 5 x 5 pixeles, cada uno de los pixeles está codificado en RGB con 1 byte para cada canal, es decir, que cada punto se representaría en una matriz de (5×3)x5 en la cual cada elemento constituye un byte (un valor entre 0 y 255) . Esta podría ser nuestra imagen expresada como una matriz de puntos:

128 045 135 236 002 237 112 222 012 087 158 255 000 055 099
128 045 135 236 002 237 112 222 012 087 158 255 000 055 099
128 045 135 236 002 237 112 222 012 087 158 255 000 055 099
128 045 135 236 002 237 112 222 012 087 158 255 000 055 099
128 045 135 236 002 237 112 222 012 087 158 255 000 055 099

En un archivo binario esto se almacenaría simplemente un valor tras otro. Para visionar dicha matriz de puntos tan solo tendríamos que conocer esta distribución y aplicarla a la pantalla de nuestro monitor. Sabemos que es una imagen de 5×5 con 3 canales de color, con lo que el PC tan solo debería de tomar los valores de 3 en 3. Cada 3 valores obtendrá el color de cada pixel, y su ubicación dentro de la matriz corresponderá a la ubicación del pixel en la pantalla. Este sistema no obstante no puede aplicarse a los algoritmos de imágenes actuales como JPG, PNG, TIFF… ya que estos de un modo u otro aplican compresión a las imágenes (ya sea con pérdida o sin ella), y no se podría comprobar lo que queremos explicar. Podríamos llamar a esto una imagen RAW, el problema de llamarlo así sería la confusión que ocasionaría con las imágenes RAW de las cámaras de fotos.

Visto esto, veamos la aplicación real. Primero partiremos de una Imagen RAW Fuente creada para tal ejemplo a la que he llamado egocéntricamente “Theliel”, “Alma Oscura” era muy largo para este propósito:

Evidentemente la imagen mostrada aquí no es una imagen RAW (Entendiendo RAW no como imagen de las cámaras de fotos), es una conversión a png para que el navegador pueda mostrarla. ¿Pero que es lo que sucede cuando la codificamos con un algoritmo como AES-256 (el cual veremos más adelante)? Para ello se ha realizado dos simples conversiones, una usando el método ECB y otra usando el método CBC:

La primera pertenece a la codificación ECB, mientras que la segunda imagen corresponde a la codificación CBC. Ambas imágenes hablan por si mismas. Si se accede a las versiones grandes, se puede comprobar aun mejor que incluso cuando se está codificando con AES-256 (un cifrado muy fuerte), cuando se realiza en ECB la imagen puede ser adivinada, incluso el texto es completamente legible. La imagen no es del todo clara, pero se puede apreciar perfectamente el contorno de la manzana de Apple. Esto nos plantea lo que a mi parecer es uno de los grandes problemas de la seguridad, y es que el problema no radica ya en encontrar sistemas que sean seguros, sino en el uso que se den de ellos. Que exista el método ECB no implica que sea una buena opción usarlo. El resultado de un cifrado en ECB de cada bloque es el mismo si el bloque a encriptar no varía. En una imagen, no es raro encontrar estos patrones, y dado que podemos representar de una forma gráfica esta encriptación, obtenemos un resultado realmente curioso, como el que hemos mostrado. En contrapartida, al usar CBC, cada bloque tenga o no tenga la misma información, será codificado de forma diferente, dado que la codificación de cada bloque depende del anterior. El resultado es una nube de píxeles de colores sin sentido alguno, quedando la imagen real completamente oculta.

Los cifrados de bloques según lo explicado, no obstante deja algunas incógnitas como que sucede cuando el contenido a cifrar no corresponde a un tamaño múltiplo del tamaño de bloque o que sucede con aquellos bloques que requieren de un bloque anterior (o posterior) y no lo poseen dado que son el primero o el último.

Respecto al primer problema, el tamaño de bloque, se acude a una técnica mas que conocida por la mayoría de los programadores, el Padding. Es decir… rellenar. Si los bloques son por tanto de 64bits y el último bloque tan solo tiene 32, los 32 bits restantes se rellenarían. Esto hace a su vez aparecer un problema añadido… la salida tendrá un tamaño siempre mayor que la entrada, dado que será necesario añadir tantos bits como sea el caso para poder completar el bloque. Y el segundo problema que aparece es con que datos rellenar ese Padding, lo que produce a su vez que sea complicado esclarecer el tamaño REAL del mensaje original. Para esto existen diferentes técnicas más o menos elaboradas, pero decir al menos que rellenarlo todo con simples carácteres “null” (nullo) no sería recomendado.

Respecto al segundo problema, lo normal es que exista una entrada adicional a la Key y al contenido a cifrar en el sistema, que se denomina como vector de inicialización (IV). No obstante, dado que estos vectores no pertenecen al algoritmo dado y normalmente no es dado tampoco como dato de entrada, lo normal es que la propia implementación del algoritmo lo establezca. Otra solución sería no usarlo o suponer que de no expresarlo, el vector de inicialización será una cadena de ceros.

No han sido pocos los cifrados de bloques que han existido y existen. Muchos de ellos buscando siempre ser el mejor en cuanto a seguridad se refiere, otros por ser los más rápidos, otros por ser mejores en otros fines… y se llegó al absurdo de que existían un sin fin de cifrados de bloques que eran usados. Todo ello por supuesto sin contar con el secretismo. Antes se pensaba que cuanto más secreto fuese un cifrado, más invulnerable era. Esto parecía lógico, si nadie sabe como se implementa o como funciona, lograr desencriptarlo sería complicado. El problema no obstante es que un millón de cabezas piensan más y mejor que unas cuantas cabezas de ingenieros que en su día crearon dicho algoritmo.

Así, posiblemente el primer cifrado por bloques que llegó a convertirse en un estándar y publicado como tal fue DES (Estandar de encriptación de datos). DES contaba con una key de 56bits, bloques de 64 bits y un total de 16 rondas. Al margen de lo seguro o no que pudiese ser, hoy por hoy sería impensable un sistema de cifrado con key de 56bits. En el peor de los casos por simple fuerza bruta serían necesarias 256 comprobaciones, y con el hardware actual sería un valor fácilmente alcanzable. En 1998 se creó un hardware “barato” que fue capaz de obtener una key DES por fuerza bruta en tan solo 56 horas, aunque un año más adelante tan solo necesitó 22 horas. Esto hizo replantearse seriamente el uso de DES. Después de esto, se comenzó con el uso del sucesor de DES, llamado Triple DES, publicado en 1998 y que básicamente era igual a DES, pero usaba un conjunto de 3 Key DES de 56 bits cada una. En algunos esquemas estas Keys eran independientes, en otros eran keys derivadas. Y aun que a día de hoy se puede considerar Triple DES como seguro, la realidad es que en 2001 fue publicado oficialmente AES. Al igual que se hiciese con los Hash SHA, el período de estandarización de AES fue de 5 años. 5 años en los que compitieron los mejores algoritmos de cifrado de la época, algunos de ellos conocidos dentro del mundo de la criptografía: RC6, Serpernt, Blowfish… y por supuesto el ganador: Rijndael, que pasaría a ser llamado AES (Estandar avanzado de encriptación). AES se estandarizó con 3 longitudes de key diferente, así existe a día de hoy AES-128 AES-192 y AES-256, con un tamaño de bloque de 128 bits. No obstante, el algoritmo original permitía bloques de diferente tamaños y keys.

AES a día de hoy es completamente seguro. Tal es así, que el gobierno de EEUU aceptó el uso de AES-256 para su uso en su material clasificado como “Alto secreto” y AES-128 AES-192 para su material clasificado como “Secreto”. Es decir… actualmente y posiblemente por muchos muchos años, AES permanecerá como cifrado simétrico estandar y seguro.

El como funciona AES en realidad no es tan complejo si comprendemos el funcionamiento de los cifrados de bloques. Lo único que habría que conocer son las transformaciones que se realizan en los boques, esas 10-14 etapas que se llevan a acabo en cada bloque. En primer lugar lo que AES realiza es generar una subkey de bloque derivada de la key original e interpreta la hilera de bits del bloque (128 bits) como una matriz de 4×4 bytes (1 Byte son 8 bits, 4x4x8 = 128 bits). Una vez se ha creado la estructura básica del bloque, se aplica el cifrado XOR a la matriz entre esta y la subkey de bloque generada. Una vez realizada esta operación, se realizan una series de operaciones en la matriz, como desplazamiento de columnas, mezclado y otras operaciones no lineales. Para acabar se realiza de nuevo una operación XOR con la subkey que corresponda (diferente a la key de la primera XOR). La matriz resultado se envía como bloque cifrado en una sucesión de bytes.

Como vimos en el ejemplo anterior, AES-256 en realidad sí que es extremadamente seguro, pero es necesario siempre un buen uso de dichos cifrados. Para terminar un pequeño ejemplo de un esquema de codificación simétrica, mostrando muchos de los conceptos aquí tratados:


CrypTool 2 Beta


En el esquema se puede observar como existen tres elementos principales de entrada: El archivo a codificar llamado “Original”, la Key usada llamada “Key” y un generador aleatorio de IVs. Los bloques en azul claro corresponderían a los algoritmos de cifrado, en este caso se ha usado AES-256 ECB y CBC y DES ECB. Por último los archivos de salida generados de los procesos aplicados. Se observa no obstante que para los módulos AES no se ha usado una entrada IVs. Lo que sucede es que el vector de inicialización en este caso sería 0x0000000000000000 (8 bytes). DES por el contrario requiere que se incluya, por ello se ha usado un generador aleatorio de IVs, que no es más que un generador aleatorio de valores de 8 bytes en este caso, dado qeu DES requiere un IV de 8 bytes, es decir, del tamaño de cada bloque (64 bits). Cabe destacar que para la desencriptación del archivo cifrado DES sería necesario suministrar exactamente el mismo IVs, de lo contrario no sería posible recuperar el archivo original. Para esto, siguiendo el esquema, sería tan siple como incluir en la entrada del supuesto módilo de desencriptación DES otra salida del mismo generador de IVs.

El cifrado simétrico es seguro cuando se usa un algoritmo y sistema de cifrado correcto.

 

 

Cifrado Asimétrico

El cifrado simétrico es seguro, es cierto… pero estará siempre enfrentado a una serie de ataques que antes o después es posible que sean rotos. Y su principal desventaja no es esa… es la key. El cifrado asimétrico apareció como alternativa a ello. Pero vamos a ver primero la necesidad del cifrado asimétrico, sería absurdo crear un sistema que no tenga una utilidad.

Hemos dicho que el cifrado simétrico tiene dos problemas. El primero de ellos es que está basado en algoritmos de dos sentidos, es decir, prácticamente (por no decir todas) todas las transformaciones que sufre el bloque por las diferentes etapas son funciones invertibles que a través de la misma key se puede reconstruir el mensaje (dato) original. Esto implica que la fortaleza del algoritmo simétrico recaiga tan solo en las transformaciones algebraica que se realizan sobre el bloque. De ahí que prácticamente todos los cifrados simétricos que se han estudiado antes o después se descubren diferentes ataques a sus diferentes etapas. Por ejemplo, para AES existen ataques exitosos en versiones reducidas de este, es decir, AES con menos etapas. Si AES-128 posee 10 etapas, a lo mejor se ha logrado ataques que pueden considerarse una roptura (es decir, que son computacionalmente posibles) para versiones de 6 o 7 etapas tan solo. La idea de estos ataques es ir logrando cada vez más romper cada etapa, de modo que al ir añadiendo una etapa más, el coeste computacional pueda considerarse factible. Si se llega a obtener un ataque a AES-128 en el que el coste computacional obtenido sea de 280 (por ejemplo) se considerará una roptura, frente a 2128 posibilidades iniciales.

El segundo problema al que se enfrenta el cifrado simétrico es la Key. La key es necesaria tanto para cifrar un mensaje como para desencriptarlo. Esto implica que tanto origen como destino tengan que compartir dicha Key. Esto a simple vista puede carecer de importancia, pero esto quiere decir que si queremos realmente una seguridad decente, en el mejor de los casos tendríamos que tener una key diferente de comunicación con cada uno de los usuarios con los que deseamos entablar una comunicación segura, dado que no usaríamos nunca la misma key con otros usuarios, de ser así otros usuarios podrían leer los mensajes que eran destinados para otros. Esto provoca la necesidad de múltiples keys para cada usuario, lo cual es engorroso e inseguro, dado que la comodidad podría implicar usar la misma key en todas las comunicaciones y esto supondría un problema de seguridad.

 

El cifrado simétrico resuelve estas dos cuestiones. La primera de ella haciendo uso de lo que podríamos llamar “Matemática Imposible”. En el cifrado simétrico se logra un algoritmo de cifrado de un único sentido, el cual no es computacionalmente viable el invertirlo. Podemos decir así que existen en realidad dos algoritmos diferentes dentro de un esquema de cifrado asimétrico, un algoritmo que encripta y otro que desencripta. Y al contrario que sucede con las transformaciones o la álgebra aplicada a un algoritmo simétrico, en la criptografía asimétrica esta función suele ser mucho más simple, lo cual no implica que sea más rápida, todo lo contrario. Así por ejemplo el cifrado AES requiere de 10 etapas mínimas para completar el cifrado de un bloque, mientras que el el cifrado RSA esto se limita a una “simple” función, aunque lo que no es simple es la teoría y el cálculo de dicha función. Estas funciones se basan en la premisa de que es imposible invertirlas, así por ejemplo tenemos el problema matemático de la factorización (usado en RSA) y el del logaritmo discreto (usado en ElGamal). Vamos a basarnos por simplicidad y fácil compresión en RSA. Posiblemente hasta los niños más pequeños aprenden a temprana edad que es la factorización de un número. Factorizar un número no es más que encontrar sus factores, es decir, los diferentes números que lo dividen, es decir, aquellos números que al dividirlo dan como resto cero:

Factorización de 20: 1,2,4,5,10 ya que 20 mod 10 = 0 20 mod 5 = 0….

Todos sabemos factorizar un número, el problema radica en dicho método. El problema reside en que la única forma real de obtener los diferentes factores de un número (así como saber si dicho núnero es por ejemplo primo) radica en ir dividiendo dicho número por cada uno de los números desde el 2 (el 1 es factor de todos los números) hasta n-1, siendo n el número a factorizar. Si disponemos de un número relativamente pequeño como el 101, podemos simplemente ir dividiendo este por 2, por 3, por 4… hasta llegar al 99. En realidad a la hora de encontrar los factores no es necesario llegar a dicho número, tan solo es necesario realizar Raiz (n) operaciones. Es decir, en el caso que el número a factorizar fuese 101, en realidad tan solo sería necesario ir probando Raiz (n) = 10 aprox, es decir, después de 10 operaciones podríamos conocer si realmente 101 es primo: 101/2, 101/3, 101/4… 101/10. Esto podría parecer no tener complicación alguna, 10 operaciones podríamos hacerlas incluso a mano. ¿Pero que sucede cuando el número a factorizar es infinitamente mayor? Podríamos pensar que un PC actual podría manejarlo en segundos, pero esto no es así. Existen diferentes algoritmos que intentan dar una opción viable a la factorización sin necesidad de usar divisiones una a una, el problema es que estos algoritmos no son fiables al 100% ni mucho menos, produciendo lo que se conocen como falsos números primos. Aun así, cuando se manejan los números tan ingentes que pronto veremos, ni haciendo uso de estos algoritmos sería posible. Vemos por tanto en este caso, que la matemática detrás de la factorización es más que conocida, es sencilla, pero es computacionalmente imposible para grandes números.

Respecto al segundo problema comentado, la key, en el cifrado asimétrico no existe una sola key, sino dos. Una key se denomina como clave pública y la otra como clave privada. El concepto es simple. Cada una de las claves son complementarias y pueden ser usadas tanto en el algoritmo de encriptado como en el de desencriptado, es decir, lo que encripta una clave lo desencripta la otra. No hay que pensar en clave pública como clave para desencriptar, sino clave que se distribuye a todo aquél con el que deseamos entablar un canal seguro. A diferencia que el cifrado simétrico en el que es necesario una key única para cada canal de comunicación, aquí será la clave pública la que será usada para todos. Este concepto choca al principio, una clave que se da a conocer a todos. Por otro lado la clave privada será el mayor secreto para su dueño, y es aquí donde reside la vulnerabilidad desde mi punto de vista del cifrado asimétrico. Visto esto, es lógico asumir que el par de claves (privada y pública) deben de estar relacionadas de modo alguno, pero sin que pueda suponer un riesto el conocimiento de dicha clave pública.

Estas dos características hacen que el cifrado asimétrico sea a día de hoy posiblemente el sistema más seguro en cuanto a encriptación de datos, y ello puede verse diariamente. Todas las comunicaciones cifradas a día de hoy que requieren de una privacidad importante, están basadas de un modo u otro en cifrado de clave pública (o cifrado asimétrico). No obstante no todo son ventajas. El cifrado asimétrico para empezar requiere de una capacidad de computación muy superior a la del cifrado simétrico para realizar la encriptación o desencriptación, llegando a ser cientos de veces más lento. Por otro lado se requieren por regla general keys de una longitud muy superior a lo que es habitual encontrar en el cifrado simétrico. Por ejemplo AES-256 (Key de 256 bits) frente a RSA, que puede usar Keys de entre 1024-4096 bits. Aunque una Key de 4096 bits (512 Bytes) sea un tamaño irrisorio para las comunicaciones, nadie sería capaz de recordar jamás una clave de 512 caracteres. En contrapartida, con AES-256 (32 Bytes) por un lado no sería complicado recordar una frase de 32 caracteres, pero además no es necesario, dado que generalmente las subkeys usadas son generadas apartir de nuestra “clave” introducida. Pero en el cifrado asimétrico esto no funciona así, no existen keys derivadas, una para encriptar todo el mensaje, una para desencriptar todo el mensaje.

Este problema de keys grandes se une al echo de la necesidad de que una Key pública sea conocida. Si deseamos que alguien encripte un mensaje hacia nosotros, este mensaje deberá de cifrarlo usando nusetra key pública, luego dicho usuario deberá tener acceso a nuestra key pública. Del mismo modo si queremos responder a dicho mensaje, tendremos que o usar la clave publica de dicho usuario para encriptar la contestación o encriptar la contestación con nuestra clave privada, ya que el receptor dispondrá de nuestra clave pública para desencriptarlo o su clave privada. Para que esto pueda ser posible, hace ya mucho tiempo que se establecieron bases de datos de claves públicas, de modo que cualquier persona pued acceder a ellos de forma simple y conocer la clave pública de cualquier persona.

 

Posiblemente los dos algoritmos de cifrado asimétrico más conocidos sean como hemos dicho RSA y ElGamal. Cada uno de ellos se basa en una imposibilidad matemática y por comodidad vamos a explicar como funciona RSA a grandes rasgos.

RSA como hemos dicho se basa en la imposibilidad matemática de factorizar un número grande. El proceso no es muy complejo. Lo primero es generar las claves que serán usadas, tanto la privada como la pública:

  1. Tomar dos números primos, llamados ‘p’ y ‘q’, los cuales por seguridad se requiere que ambos tengan una longitud de bits similar, para garantizar en caso de un posible ataque el “peor de los casos posibles”, y por otro lado que puedan escaparse a los algoritmos conocidos de búsqueda de primos. Estos dos números es normal encontrarlos de al menos 512 bits de longitud, es decir, un número con más de 154 cifras.
  2. Se calcula n = p x q, y acto segido la función Phi de Eulerm definida como Phi (p x q) = (p-1)(q-1). La función Phi de Euler calcula el número de coprimos que existen a un número dado. dos números son coprimos si no tienen ningún factor en común salvo el 1. Es decir, aunque el 10 no es un número primo, el 14 es coprimo de 15, dado que tan solo comparten el factor común uno. Dado que tanto p como q son números primos (ta solo divisibles por 1 y por ellos mismos) poseerán cada uno un número p-1 y q-1 de coprimos cada uno.
  3. Se escoge un número ‘e’ que se encuentre entre en el intervalo 1 < e < Phi(p x q), de modo que e y Phi sean coprimos entre ellos. Si ‘e’ a su vez es primo mejor.
  4. Se calcula ‘d’ en la siguiente función: d x e = 1 (MOD Phi (pxq)). de = 1 MOD Phi(pq) es quizás el principal problema de comprensión en RSA. Esta función recibe el nombre de multiplicación modular inversa, y se calcula de forma simple gracias al método extendido de Euclides. En realidad es tan solo matemáticas aplicadas. NOTA: Los “Iguales” que son especificados en estas igualdades en las que implican operaciones modulares, no son en realidad “Iguales”, sino “Congruentes”, es decir… equivalentes. Escribir “d x e = 1 (MOD Phi (pxq))” siendo ese “Igual” el símblo de congruencia, significa que 1 = dxe MOD Phi, siendo ese Igual un Igual de los de toda la vida.

Después de estos 4 pasos, la clave privada y la clave pública estarán ya creadas. La clave privada corresponderá entonces a la tupla Clave_privada (n, d), mientras que la clave pública a la tupla Clave_pública (n, e). Una vez obtenidas sendas claves tan solo es necesario aplicar la función de encriptación o desencriptación. Por cuestiones de Padding y seguridad, el mensaje es convertido a un número entero ‘m’, menor a ‘n':

me = Cifrado MOD n -> Se obtiene así un valor en Cifrado

Cifradod = m MOD n -> El valor Cifrado será desencriptado por medio de dicha función y se obtendrá m, es decir el mensaje original. Tan solo es necesario deshacer el padding.

Como se pueden ver, en realidad las funciones de encriptado y desencriptado son sencillas. Si quisiésemos llevar esto a un ejemplo real a pequeña escala (con números pequeños):

a) p = 101, q = 103 -> Ambos números son primos, de longitud similar (aunque números muy pequeños).

b) n = p x q = 101 x 103 => n = 10403. Phy (10403) = (101 – 1) (103 – 1) => Phi = 10200

c) 1 < e < Phi => 1 < e < 10200 => e = 13. 13 a su vez es primo y coprimo de 10200. Esto puede comprobarse de forma sencilla gracias al algoritmo de Euclides.

d) d x e = 1 (MOD Phi (p x q)) => d x 13 = 1 MOD 10200. Esta ecuación se expresa del mismo modo como: d-1 = e MOD Phi. Si se aplica el método extendido de Euclides se puede obtener de forma sencilla la identidad de Bezout. El método de euclides no es más en realidad que ir dividiendo dividendo entre divisor. Una vez se realiza la operación, el divisor pasa a ser dividendo y el resto divisor y se realiza otra iteración, hasta que se obtiene un resto de 1. A cada iteración se le calcula sus dos coeficientes para generar así la igualdad de Bezout. En nuestro caso para la iteración 5 (en la cual el resto es 1) del método extendido de euclides estos son 5 y -3923. calcular estos coeficientes se obtienen por sustitución de las iteraciones anteriores. En la iteración 3 se obtienen los coeficientes sustituyendo en esta la igualdad de bezout obtenida en la iteración una y dos. Las iteraciones una y dos a su vez se conocen de antemano:

restoi= Combi = Comb (i-2) + Comb (i-1)

Ronda Divndo. Div. Cociente Resto Sustitución Combinación Coef. 1 Coef. 2
1 10200 13 - 10200 - 10200=10200*1+13*0 1 0
2 10200 13 - 13 - 13=10200*0+13*1 0 1
3 10200 13 784 8=10200-13*784 8=(10200*1+13*0)-(10200*0+13*1)* -784 8=10200*1+13* -784 1 -784
4 13 8 1 5=13-8*1 5=(10200*0+13*1)-(10200*1+13* -784)*1 5=10200*-1+13* 785 -1 785
5 8 5 1 3=8-5*1 3=(10200*1+13* -784)-(10200*-1+13*785)*1 3=10200*2+13* -1569 2 -1565
6 5 3 1 2=5-3*1 2=(10200*-1+13* 785)-(10200*2+13* -1569)*1 2=10200*-3+13*2354 -3 2354
7 3 2 1 1=3-2*1 1=(10200*2+13* -1569)-(10200*-3+13*2354)*1 1=10200*5+13* -3923 5 -3923
8 2 1 2 0=2-1*2 0=(10200*-3+13*2354)-(10200*5+13* -3923)*2 0=10200*-13+13*10200 -13

10200


Pese a la aparente complejidad, si se presta atención al procedimiento realizado rápidamente se comprende como se ha realizado. Una vez obtenido los dos coeficientes, tan solo nos quedaría que d = Phi + Coef. 2 (Resto 1) => d= 10200 – 3923 = > d = 6277. Si deseamos verificar esto: d x e = 1 MOD (Phi(pxq)) => 6277 * 13 = 1 MOD 10200 => 81601 MOD 10200 = 1. Es decir, se cumple.

e) Con esto tendríamos la claves privadas y públicas calculadas:

Clave Privada (n->10403, d->6277), Clave Pública (n->10403,e->13)

Cabe destacar que todo este proceso de 4 fases es tan solo llevado acabo una sola vez, y estas claves serán las que sean usadas durante meses o años sin ningún tipo de problemas. Una vez se tienen estas dos claves, el resto tan solo es aplicar la función de encriptación o la función de desencriptación. Continuando con el ejemplo imaginemos que quisiésemos encriptar la palabra “Casas”, y que estamos usando un sistema simple de translación de dichos valores a ASCII en hexadecimal. Imaginar también que se tiene un Padding que inserta en el mensaje un valor de “0x01″ cada dos caracteres:

Mensaje Original: C -> 0x43 a -> 0x61 s -> 0x73 a -> 0x61 s -> 0x73
Mensaje Con Padding: 43 61 01 73 61 01 73. Es decir, cada dos bytes se incrusta un 01.
Tamaño de la palabra: 2 Bytes. Es decir, se especifica la cantidad de Bytes que se van a tomar para realizar la codificación, en este caso por ejemplo 2. Es decir, se divide el mensaje con el padding incorporado en grupos de 2 bytes, si el número es impar (como en nuestro caso) se añade un byte más de padding al final para rellenar

Codificación 1- >4361, Codificación 2 -> 0173 Codificación 3 -> 6101 Codificación 4 -> 7300

me = Cifrado MOD n ->Se cifrará usando la clave pública. En caso de que se quisiese cifrar con la clave privada, en vez de e se usaría d.

436113 = Cifrado MOD 10403 => Cifrado = 436113 MOD 10403 = 7905
017313 = Cifrado MOD 10403 => Cifrado = 017313 MOD 10403 = 6398
610113 = Cifrado MOD 10403 => Cifrado = 610113 MOD 10403 = 3597
730013 = Cifrado MOD 10403 => Cifrado = 730013 MOD 10403 = 3217

En mensaje cifrado por tanto correspondería a la cadena hexadecimal: “79 05 63 98 35 97 32 17“, algunos de esos valores tendrían representación en ASCII y otros no. El proceso de desencriptación sería similar:

Cifradod = m MOD n

79056277 = m MOD 10403 => m = 79056277 MOD 10403 = 4361
63986277 = m MOD 10403 => m = 63986277 MOD 10403 = 0173
35976277 = m MOD 10403 => m = 35976277 MOD 10403 = 6101
32176277 = m MOD 10403 => m = 32176277 MOD 10403 = 7300

Para poder calcular el módulo a tales cifras exponenciales no servirá una calculadora normal, es necesario recurrir a técnicas concretas para el cálculo de módulos a exponenciales. Un buen punto de partida para poder realizar esto sería: AQUI

Como se puede observar, los resultados obtenidos son exactamente los mismos que los iniciales, la cadena desencriptada correspondería a “43 61 01 73 61 01 73 00″, eliminando el Padding nos quedaría “43 61 73 61 73″ que se traduciría en ASCII de nuevo como “Casa”.

Según el esquema propuesto se puede ver la necesidad del Padding. El Padding en RSA toma una importancia aun mayor, dado que no solo sirve para añadir al final bytes que puedan faltar para rellenar, sino que es importante incluir ciertos bits o bytes (de forma reversible) en el mensaje original, de este modo RSA se hace resistente a ataques conocidos como “textos específicos”, aunque las vulnerabilidades serán tratados en el último capitulo de este artículo. El Padding debe de ser conocido por todos, no debe de ser un secreto.

Como se puede comprobar, RSA (o los algoritmos de clave pública en general) no son en realidad complejos por sus funciones, sino por la carga matemática que hay detrás de ellos. Las funciones en RSA para cifrar son muy simples, 4 variables de las cuales se conocen siempre 3 y dos operaciones, una exponencial y otra modular. La seguridad en cambio radica en que es virtualmente imposible obtener a partir de la clave pública la clave privada. Como hemos visto, la clave privada corresponde a la tupla n y d. Mientras que n es también un valor dado por la clave pública, d es calculado desde la clave privada a la hora de generar las claves. El cálculo de ‘d’ se podría intentar, pero como hemos visto anteriormente, d depende de Phi (p x q) y para calcular Phi (p x q) es necesario conocer ‘p’ y ‘q’. Aquí es donde radica el problema de la factorización. Sabemos que n = p x q y es un dato conocido, pero no conocemos el valor de ‘p’ y el valor de ‘q’ necesario para poder calcular Phi y posteriormente ‘d’. Para poder obtener ‘p’ y ‘q’ sería necesaria la factorización de ‘n’, y esto como hemos dicho no es viable. Es computacionalmente sencillo obtener dos primos con un número de bits muy grande. Es computacionalmente sencillo multiplicar dichos primos entre ellos. Y es computacionalmente imposible revertir el proceso y obtener los factores de dicho producto, es un camino solo de ida, si perdiésemos ‘q’ y ‘p’ sería imposible volver a encontrarlos.

Para aquellos que les pueda interesar RSA, recuerdo bien el programa DisMat, una herramienta para aprendizaje sobre RSA y otras cuestiones igualmente interesantes.

 

RSA no es el único sistema de clave asimétrica que existe. En la otra cara de la moneda tenemos ElGamal, que está basado en algunas asunciones similares pero en principios diferentes. No voy a detallar el funcionamiento de ElGamal por dos razones. La primera porque honestamente se escapa a los conocimientos matemáticos del redactor (es decir, a mi) y no sería ético buscar información sobre ello y plasmarla aquí sin comprenderla. Y por otro lado, aunque ElGamal es un sistema libre (RSA está patentado), su popularidad es relativa, siendo RSA inmensamente más usado y popular. De todos modos ElGamal si podemos decir que aplica otro principio de la “matemática imposible”, llamado como logaritmo discreto. Lo gracioso es que esto lo hemos visto a menos de pasada dentro de RSA. El problema reside en esta ecuación:

a = bx MOD n => x = log discretob (a)

Siendo a, b y n números conocidos y X la incógnita. El problema es poder calcular X. En RSA nos tenemos que enfrentar a esta ecuación, pero en nuestro caso no tenemos que calcular X, tan solo a. En ElGamal, poder obtener la clave privada implicaría resolver dicha ecuación, y esta es imposible de resolver computacionalmente, es decir… en un tiempo razonable, de nada sirve que pueda ser resuelto con un ordenador funcionando durante miles de años.

 

Los algoritmos de cifrado asimétrico como RSA son extremadamente seguros. El echo de que sea “lentos” comparados a los sistemas de cifrado simétrico hace que normalmente se opte por sistemas híbridos de los que serán tratados en los próximos capítulos. Dado que el potencial de computación es limitado estos sistemas suelen estar a salvo de cualquier posible ataque contra el propio sistema (no implica que no sean vulnerables a otros ataques), pero todos sabemos que la capacidad de cálculo de los dispositivos actuales se incrementa exponencialmente cada año que pasa. Esto significa que cada día que pasa se está un poco más cerca de alcanzar el reto computacional que plantean tanto los cifrados simétricos como AES-256 a cifrados asimétricos como RSA-1024. La ventaja de estos segundos, es que están diseñado para trabajar con longitudes muy superiores, mientras que no sucede lo mismo con los cifrados simétricos. Es probable que dentro de X años, AES-128 sea considerado inseguro, o incluso su sistema sea roto, como en su día lo fue RC4. En cambio encontrar una roptura en sistemas como RSA es harto más complicado.

Apple vuelve a la Censura

No es algo novedoso el tema de la Censura, pero lo trágico es que tan solo sea novedoso cuando viene de la mano de Apple.

Una vez más Apple ha decidido mover ficha en su afán de controlarlo todo. No es la primera vez que Apple usa la censura para prohibir una aplicación en su AppStore, pero parece ser que ahora lo quiere realizar como algo indiscriminado. Anteriormente Apple tenía prohibida la publicación de aplicaciones con contenido explícitamente sexual, amén por supuesto de otras tantas aplicaciones que ha vetado por uso incorrecto del idioma, imágenes que podían ser ofensivas para ellos…

No hace ni dos semanas aparecía otra noticia interesante (que no publiqué por cierto). En dicha noticia se hacía eco que programadores de aplicaciones para el Store de Apple estaban siendo presionados para eliminar de este cualquier referencia directa o indirecta hacia la plataforma Android. Así por ejemplo, aplicaciones que en sus descripciones rezaban frases como: “Número uno en Android” “Disponible también para Android” o cuestiones y sugerencias similares han sido punto de mira de Apple, y estos han enviado cartas a sus respectivos desarrolladores instándoles a que modifiquen sus descripciones para que no se aparezca la palabra Android. Es decir.. Android se está convirtiendo en una auténtica pesadilla para Apple (y lo peor aun no le ha llegado), y quiere con la censura evitar siquiera que pueda aparecer el nombre dentro de su cada vez más exclusivo Store.

Hoy Apple ha dado un paso más allá. Parece ser que Apple está dispuesto a eliminar cualquier aplicación que pueda contener ya no contenido explícitamente sexual, sino cualquier tipo de contenido erótico. Es decir, cualquier aplicación que pueda mostrar una chica o un chico en ropa interior o en pose provocadora. Según las cifras se hablan de miles de aplicaciones que podrían estar sujetas a dicha censura. Apple quiere mostrar una cara de seriedad indiscutible con su posiblemente fiasco iPad que saldrá a la venta en breve. Que por cierto, actualmente está en la lista de los peores “inventos” del año”.

Mi postura? Sinceramente no le veo ningún tipo de interés a aplicaciones que puedan tener contenido claramente sexual o simplemente erótico, pero soy igualmente respetuoso para quienes si les interese dicho tipo de aplicaciones. Para mi es una cuestión como la pornografía en Internet. Si bien es cierto que no le tengo ningún tipo de Amor, tampoco le tengo ningún tipo de Odio. Está ahí, quien quiera hacer consumo de ella tiene que tener la misma libertad de elección que puedo tener yo para no hacer consumo de ella, y la censura lo único que logra es matar el espíritu humano. Apple (o cualquier otra compañía) no puede decirme a mí como persona mayor de edad que debo de hacer ver o escuchar (siempre que todo ello sea completamente legal evidentemente). No, no me considero un consumidor de pornografía o sexo de Internet o PCs, pero me parece estupendo e incluso necesaria su existencia.

Si… he dicho necesaria. Es cierto que la vida real es la mejor vida que existe, aquella que está fuera de nuestras pantallas, se puede tocar, sentir… en definitivas vivir. Pero es cierto que no todas las personas son iguales, es cierto que la tecnología puede acercar a muchas personas incluso a dicho mundo real.

Quizás no comparta sus aficiones pero… para todos aquellos consumidores de pornografía, sexo o erotismo virtual tienen y tendrán siempre mi comprensión y mi apoyo. Espero que poco a poco, cada día más, las grandes empresas se den cuenta que el poder no está en la prohibición en la censura en el control, sino en la libertad. Evidentemente una libertad atada a unas leyes que evitan una anarquía y logran una armonía social sostenible. Apple señores no es más que una empresa que no le importa absolutamente nada sus clientes, tan solo el máximo de sus beneficios. Casi todas las empresas quieren lo mismo, no nos engañemos. La diferencia es que algunas de ellas han demostrado que haciendo las cosas bien, se puede ganar tanto o más dinero, véase Google por ejemplo, y eso que raro es el día que no tiene en su contra alguna noticia que la critica.

Apple, como ya sucediese en el pasado, vuelve y volverá a ser su propio verdugo.

Seguridad: Encriptación y Autentificación. Capítulo Primero -> Hash

ATENCION: Los ejemplos que se van a mostrar y “tutoriales” tan solo tienen carácter educativo. En ningún aspecto comparto filosofías de invasión a la intimidad, ataques contra un sistema informático o cuestiones similares. En la medida que sea posible siempre se usarán ejemplos y formas que puedan ser usados por cualquier persona, de forma que pueda verificar los contenidos escritos. No obstante, por motivos más que obvios, materiales como contraseñas, nombres de usuarios o de hosts, serán omitidos o modificado en las capturas de pantallas realizadas (o las lineas escritas). Es decir, los ejemplos serán completamente reales, los datos mostrados a vosotros necesarios para poder pertrechar estos ejemplos no siempre lo serán (Sí lo serán los resultados). Para que esto conste de forma clara, todo material sensible modificado o falso estará resaltado en ROJO. Por motivos de seguridad, todo el material que sea expuesto aquí (exceptuando software propietario o libre, citaciones expresas o código de terceros) tanto texto, imágenes y código son propiedad del autor y está completamente prohibido su reproducción completa o parcial en otros lugares, espero que se comprenda.

 


Hash

A diferencia del Spoofing, si hablamos de encriptación o autentificación se debe de establecer un orden sobre lo que vamos a ir viendo. Esto se debe a que un elemento suele requerir de otro, y este otro de otro… si no se explica adecuadamente cada uno de los elementos, será imposible comprender los que dependan den estos. Y el primero de estos elementos es el hash.

Un hash podemos definirlo como el resultado de una función matemática aplicada a una entrada arbitraria de datos, de forma que el resultado es (idealmente) asociado únicamente a la entrada dada y siempre obteniendo un resultado de longitud finita y concreta para el mismo hash. Es decir, idealmente para los hash criptográficos sería imposible volver a obtener el mismo resultado con otros datos diferentes. La idea es poder convertir la cantidad de datos que sea en un “resultado” de longitud fija (fijada por el propio hash). Veamos un ejemplo muy sencillo de esto. Imaginar uan función hash que realiza lo siguiente sobre números enteros:

Hash = numero1 + numero2 + numero3…. MODULO 100

En dicho ejemplo el hash se calcularía sumando cada numero de entrada dado y se le realizaría la operación Módulo 100. La operación módulo devuelve simplemente el resto de la división, y dado que el divisor es 100, el resto será siempre un número entre 0 y 99:


n1 = 500 n2 = 100 -> Hash = (500+100) MOD 100 = 600 MOD 100 = 0 Hash = 0 (600/100 = 6 y resto 0)

n1 = 1250 n2 = 25 n3 = 5460 Hash = (1250+25+5460) MOD 100 = 6735 MOD 100 = 35 Hash = 35 (6735/100 = 67 y resto 35)

Evidentemente esta función hash sería un tanto absurda desde un punto de vista criptográfico, dado que sería relativamente muy facil obtener el mismo resultado con dos entradas de datos diferentes. Pero sirve para dejar ver más o menos de lo que estamos hablando. En este caso tan solo existen 100 posible resultados, pero se puede observar que si modificásemos cualquier número este podría repercutir en un resultado completamente diferente. Las funciones hash hacen más o menos esto, aunque no con una precisión de 100 posibles valores y de una forma mucho más eficiente, pero la idea es la misma. Pero no solo es útil pensar en criptografía, una función Hash puede tener un valor muy importante simplemente en la detección de errores por ejemplo.

¿Para que sirve esto? Tiene una gran utilidad en muchísimos campos. Podemos decir que existen tres tipos de Hash: Hash checksums, Hash CRC y Hash criptográficos.


CheckSum

Sería el ejemplo más básico de Hash. El concepto apareció de la necesidad de verificar de algún modo la integridad de la transferencia de los datos. Es decir, si estos se habían transmitido de forma alguna de forma errónea. ¿Pero como podemos verificar esto? Podemos tratar los datos de entrada de tal forma que nos de un resultado, de modo que si el resultado es diferente en el destino, los datos son erroneos. Generalmente un CheckSum es una operación matemática basada en sumas. El ejemplo expuesto anteriormente sería un posible ejemplo de checksum. El ejemplo de checksum más simple es el bit de paridad. Imaginar que sea cual sea el bloque de datos de entrada, se le computa la paridad al dato, y esta se le añade al dato final. El checksums en sí mismo es tan solo un bit, un cero o un uno que corresponde a la paridad del dato inicial. Cuando los datos son recibidos por el destino, el destino calcula de nuevo la paridad del bloque y la compara con la paridad recibida. Si coincide los datos son válidos. Evidentemente este checksum tan solo previene contra 1 posible cambio de valor en uno de los bits transmitidos. Vamos a verlo con un ejemplo:

Se desea transmitir la cadena “Casa” desde A hasta B. Imaginar que cada carácter es acompañado con un bit de paridad. Un carácter tiene un valor entre 0 y 255 según la tabla ASCII, es decir, un carácter ocupa 1Byte de datos (8 bits). El carácter “C” equivale al código ASCII x43 (43 en hexadecimal), lo que en binario equivale a “01000011”:

C -> 01000011 -> Se aplica Paridad Par por ejemplo (Hay número par de “unos”? si es asi el resultado es cero, de lo contrario es uno) -> 3 Unos, es impar, bit de paridad par = 1

C -> 01000011 + bit de paridad -> Datos transmitidos: 010000111

De este modo, el destino tan solo tiene que tomar los primeros 8 bits y realizar la misma operación. Si el resultado coincide no hay error o no se ha podido detectar. Si no coincide se ha producido un error y los datos no puede tomarse como válidos. En este caso caso, tan solo se podría detectar con un bit un número impar de errores: 1, 3, 5… dado que si se produce un número par de errores el bit de paridad no cambiaría.


Evidentemente existen Checksums más eficientes, aunque todo depende del uso que se le haga. En cambio todos los días tratamos con este tipo de sistemas, y no hay que profundizar siquiera en la informática. En la mayoría de datos personales que puedan ser sensibles, suele existir un carácter o caracteres de control que verifican que los datos introducidos son válidos. Por ejemplo la letra de nuestro DNI no es más que un checksum, que se obtiene aplicando un módulo 23 al número de la división. Al resultado (entre 0 y 22), se le asigna una letra ya espeificada. Por ejemplo, el Cero es la letra T, el tres es la letra A… de tal forma que si damos o introducimos nuestro DNI de forma incorrecta, es posible verificarlo simplemente comprobando la letra proporcionada y ver si coincide con la que debería de ser. A este ejemplo se le suman los carácter de control de los números de cuenta corriente, de otros datos del DNI, número de la seguridad social… es una forma simple y efectiva de detectar con prontitud cualquier error en los datos tomados.

Otro uso increíblemente extendido es en la verificación de datos en sí mismos, no solo en la transferencia de estos. Así por ejemplo, si se quiere disponer de algún tipo de archivo que pueda tener datos relativamente sensibles como bios, firmwares, datos personales… lo normal es ir aplicando checksums a determinadas partes del archivo incrustando este mismo en las diferentes partes del archivo. De este modo, el software a medida que va procesando el archivo puede ir verificando cada bloque para asegurarse de que el archivo es confiable. Pensar en una bios que se quiere actualizar y por cualquier motivo existe un error en uno solo de sus bits. Es suficiente para que el PC no arranque. Para evitar esto, se distribuye por toda la bios checksums que van verificando bloques menores,

Su uso no obstante se ha ido reduciendo con la aparición de los Hash CRC, los cuales suelen realizar operaciones similares pero de una forma mucho más efectiva. No obstante para pequeños bloques de datos o comprobaciones sencillas suele ser más fácil y barato de implementar Checksums. Entre los Checksums más habituales encontramos Sum8, Sum16, Sum32 o Sum64.


CRC

Se traduce como comprobación de redundancia cíclica. Su objetivo y uso es muy similar al del checksum, de tal modo que no es raro ver lugares en los cuales el nombre de CRC no es más que un tipo de checksum. La necesidad de la verificación de los datos es algo de suma importancia, siendo quizás su máximo exponente la firma digital, de la cual ya hablaremos de ella. Pero no solo la detección de errores es necesaria, a veces es necesaria también la corrección de estos. Aunque un checksum puede usarse para esto, es más normal ver este tipo de correctores como CRC. Aun así, los sistemas de corrección de errores suelen ser costosos en cuanto a rendimiento, precio, implementación… tanto que normalmente no compensa, y es mucho más eficiente simplemente un buen sistema de detección, y si la detección es erronea simplemente se retransmiten de nuevo los datos. Si bien los checksums pueden ser una herramienta muy extendida dentro de los propios archivos, los CRC suelen ser usado de forma mucho más extensa en la transmisión de datos, aplicado normalmente a bloques de datos de un tamaño mayor.

El peor escenario que puede darse en una transmisión de datos o en un error en un archivo, es que este no pueda detectarse, haciendo que los datos sean enviados o procesados como legítimos. Y es esto lo que se debe de evitar a cualquier precio. Por ello, los CRC son usados intensamente en la transmisión de datos sobre internet, telefonía… y por supuesto en la integridad de los datos en un disco duro, CD, pendrive y otros dispositivos. Cuando hablo aquí de integridad no me estoy refiriendo a sistemas de checksums que puedan estar implementados en la misma estructura del archivo, sino sistemas de ingreidad que poseen los propios dispositivos. Gracias a la integración hardware y la simplicidad de como opera un CRC (la mayoría de ellos), la gran mayoría de nuestro hardware implementa funciones CRC en él mismo, sin necesidad de un software. Es decir… todo el proceso es transparente a nosotros.

El funcionamiento de un CRC es simple. A un bloque de entrada se le añade primero los bits correspondiente al CRC, y el nuevo bloque se divide por un polinomio preestablecido. El resto de dicha división binaria será el CRC. Dicho CRC se añade al bloque original y se retransmite. El destino tomará el bloque y lo dividirá por el polinomio generador (que será el mismo que usó el emisor). Si el resto es cero, no hay error de transmisión, o al menos no hay error detectable. La eficiencia radica por lo cual en el polinomio generador usado y evidentemente en el número de bits usados para el CRC. El caso más simple de CRC sería el bit de paridad, que correspondería a un bit de CRC tan solo, y el polinomio generador sería X + 1, el cual se traduciría como “11” como divisor del mensaje de entrada. Un polinomio generador tal como X5+X4+X+3 se traduciría por lo tanto como “110011” y se tendría un CRC de 6 bits.

Aun en los CRC-32, no se puede considerar CRC un hash seguro, no está pensado como resultado único de una posible entrada ni como sistema de ocultación o cifrado de datos, sino como un sistema robusto de detección de errores, y francamente, hace su trabajo a la perfección. Gracias a este tipo de funciones hash, a día de hoy disponemos de medios de comunicación fiables y con una gran tolerancia a fallos. Que no apreciemos este tipo de tecnologías, no implica que las estemos usando constantemente. Para hacernos una idea de la eficiencia de los CRC, un CRC-16 tienes el siguiente índice de detección:

  • Detección del 100% de errores simples (errores que afectan tan solo a un bit)
  • Detección del 100% de errores dobles de bits adyacentes (Si dos bits consecutivos son erróneos)
  • Detección del 100% de los errores para datos de hasta 16 bits.
  • Detección del 100% de todos los errores de dos bits que no estén separados uno del otro exactamente a 216-1 bits
  • Para el resto de posibles errores, se establece tan solo una no detección en un fallo de cada 216

Es decir, un cRC-16 sería capaz de detectar aproximadamente el 99.995% de todos los errores. ¿Esto es mucho o es poco? Esto equivale a que cada 20.000 errores, uno no se detecta. Teniendo en cuenta las comunicaciones ultrarápidas de hoy en día, la cantidad de información que es manejada en segundos es simplemente impresionante, por lo cual podemos afirmar que de cuando en cuando efectamente aparecerán errores no detectados. Esto se subsana también gracias a la fiabilidad cada vez mayor de las propias redes, con menos ruido, con mejores equipos…

Los CRC más comunes son CRC8, CRC16, CRC32… aunque si se desea ver una lista de ellos con sus polinomios generadores tan solo hay que acudir a la Wikipedia, por ejemplo.


Criptografía

En realidad son los Hash que nos van a interesar a nosotros. Este tipo de hash se usan ya no solo como detectores de errores (que pueden valer para ello también). Este tipo de Hash, al igual que los que hemos visto, es u procedimiento determinista que devolverá un resultado de una longitud fija. Pero a diferencia de los CRC o checksums en los que su objetivo principal es la detección de errores, la función de un hash criptográfico va mucho más allá:

  • La imposibilidad de poder encontrar una cadena (un bloque de datos…) cuyo resultado sea un hash dado.
  • La imposibilidad de modificación de la cadena inicial, sin modificar el hash.
  • La imposibilidad de encontrar una segunda cadena que verifique un hash de otra cadena.
  • Un hash que sea computacionalmente eficiente y facil de implementar.

Hay que comprender que con imposibilidad no podemos asegurar que sea imposible, sino que el coste computacional para ello sería tan ingente que de ninguna forma sería factible. Esto evidentemente no es más que la teoría, en la práctica todo no es tan simple.

A diferencia de los CRC o los checksums que pueden comprenderse sin muchas nociones de matemáticas y parten de unos conceptos simples, los hash criptográficos son bastante más complicado de comprender (las matemáticas escondidas detrás de ellos). Cada algoritmo hash tiene sus propios fundamentos, basados en premisas diferentes, siempre intentando cumplir cada una de las premisas dadas. No obstante podemos citar los Hash criptográficos más usados a día de hoy, como pueden ser: MD4, MD5, RIPEMD, SHA-1, SHA-256, SHA-512. Por supuesto existen muchos otros, aunque menos usados. Posiblemente a muchos algunas de esos nombres les sea conocido.

Al cumplir las premisas citadas, los Hash criptográficos suelen ser usados de forma intensiva en los siguientes campos:

  • Comprobaciones de archivos
  • Firmas digitales
  • Tablas Hash
  • Integridad de un mensaje/contenido


Dado que un Hash puede ser usado para detectar errores en el envío y/o recepción de los datos, un Hash criptográfico puede ejercer función de Comprobador de archivos. Mientras que CRC o checksum suelen aplicarse normalmente a porciones de código, tramas en las comunicaciones, pequeños detectores… este tipo de hash en realidad no se diseñan como correctores de errores o para que el contenido sea reenviado si no es correcto. Este tipo de Hash se suelen aplicar sobre un archivo completo (o conjunto de ellos). Para estos Hash, no importa lo grande o pequeño que sea el dato a verificar (pensado especialmente para grandes cantidades de datos en comparación con CRC o checksum claro está).

Comprender su función en este caso es simple. Al contenido original se le apluca un Hash criptográfico el cual se adjunta al software/archivo original. Cuando el receptor lo descarga, tiene acceso a él… solo tiene que calcular el mismo el mismo Hash y comprobarlo con el Hash que ha sido descargado desde la fuenta original. La idea es que sl el hash es el mismo, tenemos la certeza de que el archivo no se ha corrompido por el envío y la recepción ha sido satisfactoria. Por un principio similar, se puede verificar la integridad y veracidad de dicho archivo, que no ha sido modificado por nadie, que es legítimo. Podemos afirmar esto dada las propiedades ya vistas de este tipo de Hash: La imposibilidad de poder encontrar o crear otro archivo que pudiese coincidir con el hash del archivo original, y por otro lado no sería posible modificar el contenido del archivo sin alterar el hash que se calcularía en el destino.

Ver esto es muy fácil con algunos ejemplos. Tan solo tenemos que buscar un software que sea distribuido por razones de seguridad con su hash. En este caso vamos a usar por ejemplo la imagen de Windows 7 x64 Ultimate ENG. Imaginad que no te quieres molestar en ir a la tienda y encuentras un vendedor supuestamente autorizado que te permite descargar una copia de la imagen de Windows 7 (la misma que he expuesto ahi). Pero claro… quieres asegurarte de que la imagen sea legítima, y no sea una imagen modificada a la que se le haya puesto una activación o algún crack para poder instalarla. Solución? Conocer el Hash de la imagen legítima. Me pongo en contacto con Microsoft o investigo un poco para conocer el Hash de la imagen original y lo que obtengo es lo siguiente:

Windows 7 Ultimate x64 ENG: 7600.16385.090713-1255_x64fre_client_en-us_Retail_Ultimate-GRMCULXFRER_EN_DVD.ISO
MD5: F43D22E4FB07BF617D573ACD8785C028
SHA-1: 326327CC2FF9F05379F5058C41BE6BC5E004BAA7

Lo único que se debe de hacer en este caso es verificar si los valores que yo obtengo al calcular el hash son esos o difieren. En teoría con el cálculo de uno de ellos es suficiente. Para hacer esto se puede usar por ejemplo la utilidad md5sum sha1sum:

E:\Windows 7 Ultimate Final (EN-DE-JP-AR)>md5sum 7600.16385.090713-1255_x64fre_client_en-us_Retail_Ultimate-GRMCULXFRER_EN_DVD.iso
f43d22e4fb07bf617d573acd8785c028 *7600.16385.090713-1255_x64fre_client_en-us_Retail_Ultimate-GRMCULXFRER_EN_DVD.iso

E:\Windows 7 Ultimate Final (EN-DE-JP-AR)>sha1sum 7600.16385.090713-1255_x64fre_client_en-us_Retail_Ultimate-GRMCULXFRER_EN_DVD.iso
326327cc2ff9f05379f5058c41be6bc5e004baa7 *7600.16385.090713-1255_x64fre_client_en-us_Retail_Ultimate-GRMCULXFRER_EN_DVD.iso

Si dicha imagen hubiese sufrido cualquier tipo de modificación el resultado sería muy diferente. Por ejemplo, si a la imagen le modifico simplemente el primer bit (que es un “cero”, y lo establezco a “uno” con un editor hexadecimal) y le recalculo el hash MD5, esto es lo que obtengo:

4420bc0022a2ca8a361111b7a4d24ea7

Es decir, modificando tan solo un bit, el hash es completamente diferente. Por los mismos principios sería en la práctica imposible modificar aleatoriamente (o a conciencia) los bits de forma que pudiese obtener el mismo hash. Y he dicho en la práctica por una razón concreta que ahora veremos.

Vamos a suponer el caso concreto del Hash MD5. El Hash MD5 es un hash de 128 bits, lo que significa que cualquier contenido al que se le aplique este hash, se obtendrá una salida de 128 bits, una cadena de 32 caracteres hexadecimales. Es decir, sin entender siquiera de paradojas o estadística, podríamos afirmar que podríamos obtener un máximo de 2128 posibles hash. Esto es un número un tanto ingente, tanto que posiblemente una mente no es capaz de cuantificar, hablamos de 3.4 * 1038 es decir… 34 con 37 ceros a su derecha. Pero aun cuando este número es mentalmente imposible de imaginar, si es posible de imaginar que en el peor de los casos, cada ese número de hash calculados estos se volverán a repetir, lo cual implica evidentemente que sería teóricamente posible encontrar dos archivos exactamente con el mismo hash. Esta afirmación en realidad no rompe los esquemas vistos, dado que no se “rompe” la veracidad al decir que es improbable modificar un archivo para obtener un hash concreto o encontrar ese segundo archivo que verifique dicho hash. Aunque teóricamente esto es posible, aun cuando solo fuese de forma estadística.

Este es por tanto uno de los principales problemas de los hash criptográficos, y a esto se le llama colisión. Al margen de lo bueno o malo que sea el Hash, estadísticamente es posible encontrar dos hash iguales. En este caso concreto visto, aunque es posible teóricamente, en la práctica si el Hash está bien diseñado sería imprácticable. Cuanto tiempo necesitaría un PC en ser capaz de encontrar una colisión? Pues haciendo números muy por encima… 15 * 1010 años en el supuesto de que toda la población mundial tenga un procesador de 4 núcleos trabajando al mismo tiempo en la misma tarea 24 horas al día. Es decir… en el peor de los casos sería virtualmente imposible.

El problema es que esta lógica no es así. Cuando se habla de una colisión en un hash hay que recordar la llamada “Paradoja del cumpleaños”. Cabe señalar de nuevo que es muy diferente encontrar un contenido que verifique un hash concreto a encontrar dos contenidos disferentes que posean un mismo hash. Lo segundo es una colisión. Es cierto que para el primer caso la probabilidad sería la ya citada, pero no para el segundo caso, y aquí aparece lo que puede parecer increible: La paradoja del cumpleaños establece que en una habitación con 23 personas, existe un 50% de probabilidad de que dos personas cumplan años el mismo día, y si fuesen 60 personas la probabilidad sería del 99%. No hay truco, simplemente se busca una coincidencia entre cualquiera de las 23 personas, no una coincidencia concreta dentro de las 22 restantes. Teniendo esto en cuenta, MD5 posee tan solo 232 posibilidades de encontrar una colisión. Es decir, 4294967296 hash calculados de 4294967296 archivos aleatorios, estadísticamente debería de existir alguna colisión, es decir, dos archivos diferentes que poseen el mismo hash. Y es evidente que este número si que es comprensible y relativamente bajo, dado que un PC normal podría generar colisiones de hash MD5 con relativa facilidad, y esto comenzaría a invalidar los puntos en los que se asienta un Hash criptográfico. Es por esto que MD5 ha dejado de considerarse un Hash seguro, y es solo cuestión de tiempo que quede en desuso, a favor de otros Hash más seguros.

En teoría cualquier Hash debería de presentar posibilidad de Colisión, aunque es evidente que si esta probabilidad es computacionalmente imposible, podemos afirmar que no existe colisión (aunque teóricamente exista). Para tener presente esto, pensar que al Hash MD4 es posible encontrarle colisiones con tan solo en 256 hash.

A raiz de las Colisiones, aparecieron las primeras herramientas que han empezado a romper del todo el Hash MD5. A día de hoy existen herramientas capaces de generar dos programas diferentes que satisfagan el mismo Hash MD5, con lo que se rompe la seguridad de MD5 para la verificación de integridad y comprobación de un contenido. Es evidente que esto tiene matices. A día de hoy continua siendo imposible generar un contenido nuevo que satisfaga un hash buscado (lo cual rompería de forma definitiva el Hash). Pero en cambio si es posible producir dos archivos o dos contenidos que satisface el mismo hash. Esto quedó de manifiesto por el doctor Xiaoyun Wang, el cual incluso liberó el código de una aplicación que es capaz de realizar esto (En la cabecera de este artículo se puede encontrar)

SHA-1 es el segundo Hash más usado a día de hoy. A diferencia de MD5 (aunque basado en sus mismos principios) es un hash de 160 bits, al cual se le ha podido establecer un índice de colisiones de 252 en el mejor de los casos. En dicho caso el cálculo de una colisión sería relativamente práctica de llevar a acabo, quizás un año o dos años en poder lograr encontrar dos contenidos que compartan el mismo hash. No obstante se le continúa considerando seguro.

SHA-2 (conocidos como SHA256 y SHA-512) funcionan de forma muy similar a SHA-1, anque en este caso producen salidas de 256 y 512 bits respectivamente. En ambos casos no se conocen colisiones posibles.

Ante todo esto y dado que podemos asumir que tanto MD5 o SHA-1 son algo así como estándares, ya está en marcha el nuevo “concurso” que será seleccionado como sucesor de SHA-1/SHA-2 y que posiblemente será el próximo estandar en Hash dentro de un par de años. Actualmente se ha comenzado la segunda ronda, y a final de este año debería de quedar todo más o menos finalizado. La idea es encontrar un Hash más seguro y que sea muy eficiente su cálculo ,es decir… la velocidad con la que se pueda calcular el hash a un contenido. Se puede acceder a una lista de todos los candidatos de la segunda ronda en la web oficial del NIST (Instituto nacional de estándares y tecnología)

 

El último uso que deberíamos explicar son las Tablas Hash. Antes de entrar en detalle sobre este tipo de prácticas sería más correcto hablar antes de la Sal o Salt (en inglés). Hasta ahora hemos visto funciones de los Hash criptográficos para comprobar la integridad de los archivos, pero ¿que sucede si queremos usar un Hash como una especie de “encriptador” de contenido? Esto podría no tener mucho sentido dado que cualquier persona puede calcular un hash MD5 por ejemplo a cualquier entrada… pero en cambio no es posible partir del hash para obtener el contenido. Esto adquiere mucha más relevancia cuando se usan un hash para proteger detrás de él un contenido pequeño como un nombre de usuario o una contraseña, y es aquí donde aparece el término y la idea de Salt. Salt es un apéndice que se añade a una cadena de entrada para generar un Hash no intuituvo

Dentro de la web, las cookies y otros contenidos que puedan ser sensibles de cara al exterior como nombres y contraseñas puede ser sometido a un hash criptográfico para esconder su “significado” original. Esto nos dará como resultado una salida “única”, con lo que se podría usar dicha salida como contraseña y nombre del usuario de cara a un servidor, en vez del texto plano. Esto incrementa de forma exponencial la seguridad de cualquier base de datos o sistema de control de acceso. Pero como hemos dicho la utilidad de esto podría ser relativa. Vamos a ver esto con 3 ejemplos que ilustrarán la eficacia o no eficacia de un Hash para estos procesos, así como la implicación de Salt:

Imaginemos que hemos robado un archivo que guarda las credenciales de acceso a una importante base de datos. Imaginemos que dichas credenciales pueden ser almacenadas en dicho archivo como texto plano, MD5 y MD5+Salt. Si abrimos ese documento encontraríamos esto para cada una de las opciones:

1º. Nombre: Theliel Contraseña: perico

2º. Nombre: 5A04B2D961488CDA31CD065F259783BE Contraseña: DFE483413E24A5B1506389D36EBFD05C

3º. Nombre: 217B11413677EE9D4806967515D66607 Contraseña: 8E50E5A474DDAF3BC370F87DD97EC7F0

En el primer caso, es evidente que si está configurado como texto plano, las credenciales serán tomadas de forma directa y rápidamente podremos acceder a la base de datos.

En el segundo caso no obstante n oparece que sea posible descifrar absolutamente nada… ¿pero que pasaría si hacemos uso de la inteligencia? Podemos intuir que es un hash, y si buscamos información del sistema podemos incluso conocer que se trata de un Hash MD5. No podemos revertir el MD5 (a priori), pero en cambio si podemos presuponer el nombre de usuario y ver si hay una coincidencia con el hash que tenemos. Dado que el atacante es listo, comenzaría por cotejar en un diccionario que ya tiene el hash. Su diccionario no es más que una lista precalculada con quizás millones de posibles nombres de usuarios a los que ya se les ha calculado el hash correspondiente. Si el hash se encuentra en su diccionario, obtendrá de forma automática le nombre de usuario. Esto mismo se puede aplicar a la contraseña. Que usuarios se probarán primero? Admin, admin, theliel, Theliel… y en este caso, el diccionario encontraría que dicho hash corresponde a la palabra “Theliel”. En caso de la contraseña es exactamente igual, si la palabra o frase empleada en la contraseña existe en su diccionario, obtendrá directamente la contraseña buscada. Es por ello que siempre es importante tener una contraseña alfanumérica de una longitud decente.

En el tercer caso la cosa es más complicada. El atacante agotaría todos sus diccionarios y no lograría encontrar el hash deseado. ¿Por qué? Porque lo que no sabe el atacante es que el programa que codificó el hash usó una Salt, un trozo de datos que simplemente añadió al final del usuario y la contraseña. Así si el usuario escribió el nombre de usuario: “Theliel”, el servidor jamás lo tomó como tal, sino que automáticamente le añadió el Salt “TATA” (en este caso). Es decir, de cara al servidor cualquier dato introducido es concatenado con “TATA”. Así, el servidor no calcularía el hash de “Theliel” o de “perico” (la contraseña), sino de “ThelielTATA” y “pericoTATA”. dicha modificación es seguro que no aparecerá en su diccionario. La única opción del atacante es conocer la Salt usada por dicho servidor, y crear así un programa que automatice el proceso, recalculando todos los hash de su diccionario con la Salt aplicada y así con suerte obtener algún resultado. Esto lo trataremos mejor cuando se vean las diferentes técnicas para romper la seguridad.

Pero volvamos a las tablas Hash. Hemos explicado que la Salt o la importancia que puede tener un hash para “esconder” unos datos, pero ¿qué es una tabla hash? Dado que el índice de colisiones es relativamente alto, podemos presuponer que no será posible dar la casualidad de tener a dos nombres de usuarios que compartan el mismo hash. Si esto es cierto, para un servidor es mucho más seguro no guardar jamas en sus bases de datos el usuario o la contraseña como tal, solo sus Hash. Al introducir los datos el usuario, son sus hash los que alcanzan el servidor y este simplemente tiene que cotejar dicho hash (el usuario) en su base de datos para comprobar si existe una coincidencia. Si existe tal coincidencia verificar el hash de la contraseña con el hash de contraseña ya almacenado. De este modo nuestros datos de sesión no serían jamás enviados como tales. Pero la utilidad de las tablas de hash radica no en la seguridad (que por supuesto también lo es) sino su eficiencia.

Hemos dicho que el servidor debería de verificar si el hash de nombre de usuario existe en su base de datos. ¿Pero como hace esto? Si nuestra base de datos posee 100 registros, en el peor de los casos la base de datos debería de hacer 100 comprobaciones, para acabar en el último registro que sería el que coincidiese con el hash del usuario introducido. Pero aun, si el usuario introducido no se encontrase en la propia base de datos, esta la habría recorrido entera buscando una coincidencia. Este proceso sería muy costoso para los servidores. Ahora bien, partimos de la premisa que el índice de colisión de un hash MD5 es relativamente alta, 4 mil millones aproximadamente. Podríamos calcularle simplemente el módulo a dicho Hash (en función del número de índices que tengamos en la base de datos), el resultado sería un número de 1 a X, siendo X el número de entradas posibles en nuestra base de datos. Es decir, pongamos que nuestra base de datos tiene 100 registros insertados y tiene una capacidad máxima de 997 (por ser un número primo). Es decir, se aplicaría la operación módulo 997 a cada hash de entrada. Esto convertiría todos los hash de entrada en un número que iría desde el 0 al 996. Este número sí podría ser usado como índice, luego el acceso al registro en la base de datos sería inmediato. Por razones de precisión, usar un número de 128 bits no es aconsejable, lo normal es acotar este número a una resolución de 64bits, tomando por ello los 64 bits primeros del hash o los 64 bits últimos de este. En el ejemplo anterior, al Hash “Theliel” se le aplicaría módulo 997, y el resultado sería: 5A04B2D961488CDA31CD065F259783BE -> 5A04B2D961488CDA MOD 997 = 763. Es decir, que el nombre de usuario Theliel sería convertido al índice 763 en la base de datos. De este modo, al introducir “Theliel” en el navegador, se calcularía el Hash, en el servidor se truncaría y daría como resultado un índice. Con este índice el acceso a la base de datos sería directo, “Acceso a elemento 763″. Asociado a dicho índice se podría encontrar por ejemplo el hash de la contraseña y se procedería a realizar una simple comparación, si los dos hash coinciden se obtiene el acceso.

Esto evidentemente multiplica exponencialmente la posibilidad de una colisión, dado que el espacio disponible ahora es de tan solo 997 elementos. Como hemos dicho la posibilidad de colisión dependerá en gran medida de la ocupación del espacio disponible. Por la paradoja del cumpleaños no obstante, se daría el caso que con unos 35-40 elementos introducidos la probabilidad de una colisión sería de un 50%!!. Para evitar esto se acude a tablas muco mucho mayores en relación al indice esperado de ocupación que se tendrá. Es decir, se sacrifica espacio en post de velocidad. En la Wikipedia aparece un ejemplo parejo, en el que se dice que con 2500 elementos introducidos en una tabla de un millón de elementos, la probabilidad de colisión ascendería al 95%. Que hacer en caso de colisión? Primero evitarlas, ya sean con grandes tablas o con crecimiento dinámico de estas. Por otro lado asumir que es posible que exista una colisión, y diseñar el sistema de forma que ante una colisión sea necesaria una segunda búsqueda en los registros afectados para determinar el destino final.

Apple comienza a banear IDs de usuarios que tienen su dispositivo JailBreak

La noticia llega de forma inesperada para muchos… y es que parece ser que Apple en un intento muy agresivo por su parte estaría comenzando o pensando en suprimir aquellos IDs de dispositivos que están JailBreak. Es decir, que si Apple detecta de modo alguno que tu iPhone o iPod Touch ha sido JB podría añadir este a una lista negra e impedir todo acceso al AppStore, siendo claro el resultado de esto, imposibilidad de poder comprar por iTunes canciones o aplicaciones para tu dispositivo.


 

Cortesía de Neowin.net

 



Apple se ha visto presionado por las compañías móviles y por sus propias ganancias. Su objetivo es evitar por todos los medios que el iphone o el ipod touch pueda ser un sistema abierto que ellos, Apple, no pueda controlar. Al margen de si es legal o no sus actuaciones, recordemos que el JB no es un procedimiento ilegal a día de hoy, y posiblemente no lo sea nunca. Luego si no es un proceso ilegal, es posible que Apple legalmente no tenga ninguna autoridad para denegar un servicio a un cliente por un acto legítimo, que en todo caso tan solo rompe las condiciones de la garantía.

Al margen de ello, lo que está claro es que Apple está intentando por todos los medios proteger su gallina de los huevos de oro que cada día que pasa pone menos y menos huevos. El índice de adiciones de aplicaciones en el Store de Apple disminuye considerablemente, el iPad (aun cuando hay que esperar) presagia un varapalo para Apple, El Nexus One comienza a asentarse y demostrar que no solo es un hardware muy superior sino que por un lado o otro otro el iphone irá cayendo poco a poco en el recuerdo. Ante todo esto Apple lo tiene claro, moverse rápido e intentar exprimir lo que queda.

De nuevo vemos una política de empresa completamente restrictiva y que cercena la libertad de los clientes. A fin de cuenta lo único que pretende Apple es el control de sus clientes. Cuando compras un iPhone 3GS no tienes BT, el video es malo, los mms son malos, no tienes acceso al sistema, ni siquiera puedes copiar un archivo. En contraste cualquier dispositivo similar actual permite no solo hacer todo ello, sino que algunos como el Nexus One te permite si lo deseas modificar a voluntad el sistema, sin pérdida de garantía, sin crispaciones, sin tonterías.

A fin de cuenta, todo se ve reflejado en números, y los números dicen que Google aumentó sus beneficios en más de un 50% en el año 2009 frente al 2010.  Es una pena que muchas empresas no comprendan que el cliente es al final quien paga tus facturas, y que por mucho que intentes engañarlos, al final responden.


Es por noticias como estas por las que uno se para a preguntar por qué cometio el error de comprarse un iPod Touch (en mi caso particular) o un iPhone, o cualquier producto de Apple. Ya no es una cuestión siquiera de dinero (Que son los productos más caros), ya no es una cuestión siquera de que sea lo mejor o peor (que no es lo mejor)… se convierte simplemente ya en una cuestión de principios.

Hace unos años cuando adquirí mi iPod Touch estaba contento con la compra, tan solo hay que remitirse a mis post más antiguos. Foros, blogs, investigaciones propias, aprendizaje… comprendía en parte las tonterías de Apple o eso creía. Excusas que se da a uno mismo para no tener que aceptar la inversión de un buen capital en algo que no lo vale. Después de un año, de dos… la perspectiva es muy diferente. Te cansas de las noticias inverosímiles, de los fallos de software y de hardware, de las carencias… pero ya no de las que puedas encontrar tu mismo!! sino en las preguntas de siempre de otros usuarios: no hay modo disco? no puedo enviar un archivo por bt? no puedo….? Y por otro lado veo el mercado que ha expandido para ofrecer productos no solo más baratos sino muy superiores!! y aun así tienes que oír a representantes de Apple escuchar frases como: “Muchas de las veces que se queda colgado un MAC es por culpa de Flash” . “La salida de Windows 7 implicará para nosotros un gran incremento en ventas”, “La garantía queda anulada porque su MAC ha estado expuesto a un ambiente tóxico, ambiente de fumadores”… y tantos otros.

Personalmente me pregunto sinceramente en que momento Apple vendió su alma en post de engañar a algunos cuantos. ¿Hoy? Simplemente otro granito más, A bloquear IDs que tengan dispositivos JB. Que por cierto, personalmente no creo que sea una idea mu positiva, lo que lograrían sería que la comunidad usase más Cydia o la búsqueda de aplicaciones piratas, aumentando aun más la piratería.

Pero esto es así. Apple es así. De cada 100 ideas de Apple, 1 revoluciona el mercado y es una idea grandiosa. Las otras 99 ideas hacen que la opinión publica (al menos la mía y la de muchos otros) piense que se cometió el error una vez en comprar algo con una manzana.

Este blog se creó en sus orígenes precisamente por el iPhone y el iPod Touch, creo que no se puede pedir que sea más imparcial, cuando todo fue para ayudar, alentar y aconsejar positivamente. Pero hace ya tiempo que esos tiempos acabaron, y no hizo falta mucho para darme cuenta de ello.

Por mi parte? Nunca Máis Apple, Nunca Máis.

Volver a arriba

Sobre Mí

Cambiar a la versión para móviles

Creative Commons License
Alma Oscura por Theliel is licensed under a Creative Commons Reconocimiento-No comercial-Sin obras derivadas 3.0 Unported License.
Basado en el trabajo de blog.theliel.es.
Para otros permisos que puedan exceder el ámbito de esta licencia, contactar en blog.theliel.es/about.