Encriptación en PHP
Para
proteger la información de tus aplicaciones, muchas veces es necesario
encriptar la información. Existen muchos algoritmos disponibles de encriptación
y si quieres puedes crear uno propio, el único problema es que es bastante
dificil crear un algoritmo de encriptación que sea seguro.
¿Que es encriptación?
En
pocas palabras, encriptación es el mecanismo mediante el cual transformo una
cadena en otra. Por ejemplo, si tengo la cadena "Copstone" al
encriptarla podría producir un valor como "3SOg2XbS5Jk=" que
obviamente es completamente diferente a la original. De esta forma, si alguien
llegara a obtener la cadena encriptada "3SOg2XbS5Jk=" no sabría que
significa "Copstone" y así puedo decir que mi información está
segura.
La
mayoría de métodos de encriptación utilizan una cadena secreta que permite
proteger aún más la información. Esta cadena secreta se utiliza para generar la
cadena encriptada de esta forma podemos obtener para una misma cadena diferentes
valores encriptados:
Ten
en cuenta, que mientras más segura la clave secreta más segura será la clave.
Es por esta razón que se recomienda utilizar claves secretas complicadas como
por ejemplo:
jas%23jhqd#”!$qdjas8123
3!”asdhsoias/(_d%$3.
Importante!! La clave secreta es lo que le da
seguridad a tu encriptación así que la clave secreta debes protegerla a toda
costa. Nunca se la des a nadie, guardala en un lugar seguro, no la mandes por
la red ni por correo. Por ejemplo, lo más absurdo sería hacer una petición web
en la que mando una cadena encriptada y la clave secreta para que se pueda
desencriptar al otro lado. La clave secreta no debería viajar por la web,
deberías entregar la clave secreta de forma personal o por teléfono o algún
medio que no deje una huella que alguien más pueda capturar.
Existen
dos tipos de encriptación: Encriptación de dos sentidos y encriptación de un
sentido.
Encriptación de dos sentidos
La
encriptación de dos sentidos, es un tipo de encriptación en el que se puede
encriptar y desencriptar una cadena. Es decir, una cadena como
"Copstone" se puede convertir en "2IYa0gFAiGI=" si
utilizamos la clave secreta "casa" y también se puede realizar el
proceso inverso, es decir si tenemos la cadena "2IYa0gFAiGI=" y la
palabra secreta "casa" podemos obtener la palabra
"Copstone".
Esta
forma de encriptación, a pesar de ser bastante segura, sigue siendo vulnerable
debido a que siempre existe una forma de regresar a la cadena original. Me
explico:
Supongamos
que en tu servidor guardas las contraseñas de tus usuarios. Como eres
precavido, las claves las guardas encriptadas. Además en tu servidor en un
lugar seguro tienes escrita tu clave secreta. Ahora supongamos que alguien se
mete a tu servidor y obtiene estos dos datos: la contraseña encriptada
"2IYa0gFAiGI=" y la clave secreta "casa". Con estos dos
datos se puede saber que la contraseña es "Copstone", lo único que
hay que hacer es adivinar el algoritmo utilizado para encriptar (en realidad
hay varios pero no tantos como para que esto sea dificil).
Encriptación de un sentido
La
encriptación de un sentido o encriptación asimétrica, es un tipo de
encriptación en el que solo se puede encriptar una cadena y el proceso inverso
es casi imposible. Es decir, una cadena como "Copstone" se puede
convertir en "6298ed5652f7dff6fd72af530f036f31" usando
"casa" como clave secreta y no hay forma de regresar a la cadena
original.
Esta
forma de encriptación es la mas segura por el mismo hecho de que no se puede
regresar a la cadena original. Me explico:
Supongamos
que en tu servidor guardas las contraseñas de tus usuarios. Como eres
precavido, las claves las guardas encriptadas. Además en tu servidor en un
lugar seguro tienes escrita tu clave secreta. Ahora supongamos que alguien se
mete a tu servidor y obtiene estos dos datos: la contraseña encriptada
"6298ed5652f7dff6fd72af530f036f31" y la clave secreta
"casa". Como no hay forma de regresar a la cadena original utilizando
estos dos valores, es practicamente imposible que se obtenga la contraseña. La
única forma de adivinar la clave sería probar una cadena que al aplicarle el
algoritmo de encriptación con la palabra secreta "casa" se obtenga la
contraseña encriptada. Como te puedes dar cuenta esto es casi lo mismo que
adivinar la clave desde cero.
La
pregunta es: ¿Si no puedo regresar a la cadena original como sabes el valo de
la cadena original? La respuesta es sencilla. No puedes saberlo.
Combinando ambas
En
realidad, la mejor seguridad se obtiene de la combinación de ambas
encriptaciones pero dependiendo de la sensibilidad de la información que
manejes debes escoger si utilizas una o la otra o tal vez ambas.
Si
quieres combinar ambas puedes realizar la combinación que desees. Por ejemplo
podrías aplicar primero la de un sentido y luego la de dos sentidos o al revés.
También podrías emplear la de un sentido para la clave secreta o para ambas. En
realidad las podrías combinar como quieras.
Implementación
Ahora
que ya sabes de que trata la encriptación te voy a mostrar como puedes
implementarla en PHP.
Encriptación de dos sentidos
Existen
muchos algoritmos para encriptar de dos sentidos, y una gran variedad de librerías
para hacerlo. Sin embargo, la más fácil de utilizar y más común es la librería
MCrypt. Para poder utilizar esta librería tienes que asegurarte de que esté
instalada junto con tu instalación de PHP. La forma más simple de saber si está
instalada es simplemente colocando el código y si no aparece ningún error
entonces tu instalación cuenta con MCrypt. Otra forma de saber si está
instalada es crear una página web con el siguiente contenido:
1
|
<?php phpinfo(); ?>
|
Cuando
cargues esta página, si mcrypt está instalado, deberías encontrar en algún lado
de la página algo como esto:
Si
usaste el instalador de PHP para Windows, lo más probable es de que esté
instalada, si no lo está puedes conseguir la DLL libmcrypt.dll en
http://files.edin.dk/php/win32/mcrypt/.
Simplemente copia esta DLL en la carpeta ext
de tu instalación de php y en alguna de las rutas que estén dentro de tu PATH y
listo. Para mayor información de como instalar visita http://www.php.net/manual/en/book.mcrypt.php.
Si
trabajas con Ubuntu, probablemente necesites instalarla. Para instalarla basta
con ejecutar el comando sudo
apt-get install php5-mcrypt en un terminal y luego reiniciar tu
servidor apache con el comando sudo
/etc/init.d/apache2 restart.
Voy
a implementar dos funciones que me permiten encriptar y desencriptar cadenas.
Ambas funciones reciben la cadena que se quiere encriptar o desencriptar y la
clave secreta a utilizar. Estas funciones devuelven la cadena encriptada o
desencriptada.
Para
encriptar utilizaremos la función mcrypt_encrypt y para desencriptar la
función mcrypt_decrypt.
Ambas funciones reciben los siguiente parámetros:
El
problema con el texto encriptado es que tiene muchos caracteres raros,
inclusive podría ser que tenga caracteres que, al no tener una representación
visual, no se estén mostrando. También podría ser que tenga espacios en blanco
al inicio o al final. Debido a todas estas razones, no es posible almacenar
este valor de forma correcta en una base de datos o inclusive pasarlo por un
web service sin que exista la posibilidad de que se pierda un pedazo de esta
cadena.
Es
por esta razón que recomiendo convertir la cadena encriptada en base 64 para
que solo esté compuesta por caracteres con representación visual. Para
convertir a base 64 usaremos base64_encode y base64_decode. El código quedaría
algo así:
Como puedes ver, ahora la
cadena es un poco más larga pero completamente legible. Este es el valor que
deberías pasar por la red o almacenar en una base de datos.
Importante!! En este ejemplo uso como clave
secreta la palabra "casa" pero deberías usar una cadena bastante más
larga y que combine caracteres con números y signos así como mayúsculas y
minúsculas para hacerlo más seguro. Podrías usar algo como esto:
p&(oa@)+=uaq*23711!@#12psd@#239.
Asegúrate de que la cadena no sea muy larga o el algoritmo no funcionará.Encriptación de un sentido
Ahora
que ya hemos visto como realizar la encriptación de dos sentidos te voy a
mostrar como realizar la de un solo sentido.
Para
encriptar en un solo sentido no necesitas instalar nada ya que PHP a partir de
su versión 5.0 viene incluido con esta funcionalidad.
Para
encriptar en un solo sentido podemos utilizar la función hash_hmac que recibe
los siguientes parámetros:
Encriptando
en otros lenguajes
En
teoría, si utilizas un algoritmo estándar como por ejemplo Rijndael o md5, no importa
el lenguaje que utilices para encriptar la información ya que todos deberían
producir el mismo resultado si utilizas la misma clave y el mismo vector de
inicialización.
Manejo
de sesiones en PHP
Las
sesiones en PHP son una forma de mantener ciertos datos de un visitante entre
los diversos accesos una web. De esta forma se pueden crear aplicaciones donde
se le muestra al usuarios datos personalizados de acuerdo a las preferencias o
acciones del usuario.
Las
sesiones se manejan internamente por un identificador llamado SID (Session ID)
el cual esta asociado a una única sesión y que ayuda a identificar el contenido
de la sesión actual. Esta variable se propaga automaticamente a traves de
Cookies o mediante URL.
Manejo
de sesiones en PHP
Todas
la variables de sesión son accesibles mediante arrays en la variable global
$_SESSION. Adicionalmente ofrece una serie de funciones que permiten manejar
detalladamente las sesiones de manera sencilla:
·
session_start inicializa una sesión y crea el
identificador de sesión.
·
session_id devuelve el identificador de la
sesión actual.
·
session_regenerate_id genera un nuevo identificador para la
sesión actual.
·
session_unset limpia todas las variables de sesión
registradas.
·
session_destroy elimina todas las variables de sesión
registradas.
Crear
variables de Sesión
Si
deseamos crear variables de sesión para que se puedan utilizar a través de
diferentes páginas inicializamos el manejo de sesiones con al función session_start
y luego guardamos el dato deseado como variable de sesión utilizando la
variable global $_SESSION.









