Mostrando entradas con la etiqueta xml signature. Mostrar todas las entradas
Mostrando entradas con la etiqueta xml signature. Mostrar todas las entradas

martes, 8 de abril de 2008

Criptografía en PHP

La criptografía nos permite cifrar información para que pueda ser accedida sólo por las personas adecuadamente autorizadas.

En informática la criptografía se puede dividir en dos grupos:
  • Criptografía simétrica: la encriptación y desencriptación se realiza con la misma llave.
  • Criptografía asimétrica: la encriptación se realiza con una llave y la desencriptación con otra diferente.
Muchos modelos de transmisión de información segura utilizan una combinación de ambos métodos para combinar sus ventajas.

El término "llave", "clave" o en ingles "key" se utiliza para identificar la secuencia de bits utilizada como "clave secreta" para el proceso de cifrar/descifrar la información.

Una regla estándar en la criptografía es que la seguridad debe enfocarse en proteger las llaves de encriptación y no en la ocultación del algoritmo criptográfico (o cipher). De hecho es muy usual que los algoritmos sean públicos.


Criptografía simétrica
La criptografía simétrica se basa en que la misma llave de encriptación se utiliza para desencriptar.

Es relativamente rápido, fácil de implementar e implementable en hardware de bajo costo. Presenta el problema que el emisor y receptor deben conocer previamente la llave de encriptación. Esto nos lleva al problema de cómo transmitirle al receptor la llave de encriptación y este es precisamente el principal problema de este modelo.

Antiguamente el algoritmo más popular era DES (Data Encryption Standard), sin embargo en la actualidad es considerado un algoritmo inseguro ya que la llave de encriptación tiene una longitud de sólo 56 bits, una vez que se declaró este algoritmo como inseguro, se comenzó a utilizar Triple DES que tiene una llave de 158 bits.

En la actualidad el algortimo de cifrado simétrico más popular es AES (Advanced Encryption Standard) también conocido como Rijndael (que es una combinación de lo nombre de sus autores) y la llave puede tener una longitud de 128, 196 y 256 bits.

A continuación incluyo un ejemplo de crifrado utilizando Rijndael-256, es decir utilizamos una llave de 256 bits que es equivalente a los 32 caracteres del ejemplo:
<?php

// Datos de entrada
$texto = 'frase secreta';
$key = '12345678901234567890123456789012';

// Proceso de cifrado
$iv = 'abcdefghijklmnopqrstuvwxyz012345';
$td = mcrypt_module_open('rijndael-256', '', 'ecb', '');
mcrypt_generic_init($td, $key, $iv);
$texto_cifrado = mcrypt_generic($td, $texto);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);

// Opcionalmente codificamos en base64
$texto_cifrado = base64_encode($texto_cifrado);

echo "$texto_cifrado\n";

?>
Este ejemplo requiere que PHP tenga habilitado el módulo mcrypt.

A continuación muestro un ejemplo del proceso inverso donde se desencripta la información previamente encriptada:
<?php

// Opcionalmente descodificamos en base64
$texto_cifrado = base64_decode($texto_cifrado);

// Proceso de descifrado
$td = mcrypt_module_open('rijndael-256', '', 'ecb', '');
mcrypt_generic_init($td, $key, $iv);
$texto = mdecrypt_generic($td, $texto_cifrado);
$texto = trim($texto, "\0");

echo "$texto\n";

?>

Criptografía asimétrica
La criptografía asimétrica tiene la característica que utiliza una llave para cifrar y otra para descifrar. Usualmente a una de estas llaves se le denomina clave privada y a la otra clave pública. La clave privada es conocida solo por el propietario de la misma, la clave pública puede ser conocida por todos. Gracias a este modelo se soluciona el principal problema de la criptografía simétrica.

Sin embargo tiene el inconveniente que los algoritmos criptográficos son más complejos, requieren mayor tiempo de procesamiento y el mensaje cifrado requiere de mayor longitud que el mensaje original. Además para proveer el mismo nivel de dureza que la criptografía simétrica (con respecto a ataques de fuerza bruta) requiere de llaves de mayor longitud, como por ejemplo una llave simétrica de 128 bits es aproximadamente equivalente a una llave asimétrica de 1024 bits.

Gracias a la criptografía asimétrica es posible garantizar -entre otros- lo siguiente:
  • Confidencialidad: Codificar información que solo la pueda descifrar el receptor.
  • Autenticación: Validar que la persona sea quien dice ser.
  • Integridad: Asegurar que la información no haya sido alterada (ej: firma electrónica).
  • No repudio: Asegurar quién es el autor de cierta información.
Más adelante presentaré un ejemplo de cifrado asimétrico, pero antes de eso publicaré un artículo de openssl para enseñar a generar certificados digitales y llaves.


Firma electrónica
La firma electrónica (que es derivada de la criptografía asimétrica) se ha convertido en una herramienta escencial en el desarrollo de aplicaciones y es un estándar de la industria y de gobierno electrónico (e-gov) para el tratamiento de información.

La firma electrónica está construida sobre la infraestructura de llave pública (PKI) y permite asegurar la autoría e integridad de los documentos.

Usualmente la implementación de firma electrónica se realiza en base a la especificación de XML Signature [w3c] también conocida como xmldsig.

Actualmente PHP no implementa XML Signature de manera nativa, sin embargo desde PHP 5.2.1 es posible implementarla (planeo a futuro dar algunos ejemplos de su implementación). Además Rob Richards que es miembro del equipo de desarollo de PHP (autor -entre otros- del módulo DOM) está trabajando en un módulo para PHP que ojalá algún día vea la luz.