16 03
02
2013

Encriptar y desencriptar en PHP

Hoy vamos a implementar una manera sencilla de encriptar y desencriptar cadenas de texto en PHP.

Seguramente ya conocerás que existen diferentes tipos de encriptación, que podríamos englobar en 2 grandes grupos.

  • Encriptación en 2 sentidos o reversible o simétrica: es decir, permite encriptar y desencriptar un texto. Ejemplos de este tipo de encriptación para PHP son base64 (base64_encode y base64_decode) o mcrypt.
  • Encriptación en 1 único sentido o irreversibles o asimétrica: esto es, no se permite la desencriptación del texto encriptado previamente. Dado que recuperar la cadena original se hace imposible, esto hace que la encriptación asimétrica sea más segura que la encriptación simétrica o en 1 único sentido. Ejemplos de funciones PHP de este tipo de encriptación son md5, sha1, crypt, crc32.

A partir de estas herramientras que PHP nos proporciona para realizar labores de encriptación y desencriptación, vamos a construir nuestra clase Encrypter con 2 sencillos métodos:

  • encrypt: nos permitirá encriptar un texto
  • decrypt: permitirá desencriptar un texto previamente encriptado mediante la misma clase Encrypter.

Esta clase Encrypter, con el objetivo de fortalecer la seguridad de la encriptación, se apoyará además en una clave secreta definida de forma interna en el atributo $key.

Por lo tanto, sobra decir que, toda desencriptación que queramos realizar de un texto, deberá realizarse bajo la misma clave secreta que haya sido utilizada en el proceso de encriptación.


/**
* Description of Encrypter
*
* @author jose
*/
class Encrypter {

	private static $Key = "dublin";

	public static function encrypt ($input) {
		$output = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5(Encrypter::$Key), $input, MCRYPT_MODE_CBC, md5(md5(Encrypter::$Key))));
		return $output;
	}

	public static function decrypt ($input) {
		$output = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5(Encrypter::$Key), base64_decode($input), MCRYPT_MODE_CBC, md5(md5(Encrypter::$Key))), "\0");
		return $output;
	}

}

El uso de la clase Encrypter es más que sencillo, en la primera línea del siguiente código encriptaremos la variable $texto que contiene el string “son unos corruptos”. En la siguiente línea, desencriptamos la variable $texto_encriptado previamente encriptado.

El resultado de la desencriptación guardado en la variable $texto_original, deberá ser igual que el de la variable inicial $texto.


$texto = "Son unos corruptos";

// Encriptamos el texto
$texto_encriptado = Encrypter::encrypt($texto);

// Desencriptamos el texto
$texto_original = Encrypter::decrypt($texto_encriptado);

if ($texto == $texto_original) echo 'Encriptación / Desencriptación realizada correctamente.';

Tags: , ,

16 respuestas en “Encriptar y desencriptar en PHP”

  1. Hola,Gracias por el codigo, excelente! pero tengo una duda; bien veras el codigo me funciona perfectamente bajo windows pero cuando esta bajo Linux me da error, el servidor que uso no me arroja errores así que no podría decirte específicamente cual es, tienes alguna tipo de información sobre porque este comportamiento ?

    • Hola amig@
      Este código lo tengo funcionando tanto en linux como en windows, siendo el resultado el mismo.
      Quizás el error venga de otra parte. Aunque en el servidor no tengas activados que muestre los errores, puedes mostrarlos, prueba con estas 2 líneas en tu archivo php (preferiblemente al inicio del mismo) y nos comentas resultados
      error_reporting(E_ALL);
      ini_set(‘display_errors’, ’1′);

  2. funciona bien, pero no siempre al menos en mi caso, he probado a “cafrearlo” un poquillo y por ejemplo este mail cuando lo recojo por get desde otra página no lo coge bien, en la misma página sí:
    eha_eha12_2_2@gmail.com

    el resultado en la página que lo recoge por GET sale esto:
    Y˜XîÔÚe;¾éê–Ý´ÈÍ0m•epÞh»j¼
    mientras que en la misma en la que realiza la encriptación sí lo hace bien, es algo que me trae un poco de cabeza, porque otros correos, si los recoge bien por GET y desencripta perféctamente… ¿Alguna idea?

    • CREO y solo creo que es por el tema de recoger por GET la url, ya que con el mail que he puesto antes, se generan caracteres “+” en la url, los cuales los interpreta como espacios y por ello no desencripta bien, lo que no sé es que solución tiene a priori si encuentro algo lo comunicaré por si a alguien más le puede servir

    • vale, el problema ya está resuelto parece, es cuestion de tratar la cadena que envias para que después sea recogida correctamente.
      Gracias por el aporte,

      Un saludo!

  3. Hola buenas!

    En primer lugar darte las gracias, por que la web me a sido muy útil en diversos aspectos.

    Ahora la duda. En windows no tenia problema alguno, pero al pasarme a ubuntu dejo de funcionarme mi proyecto y localice el fallo que era esta función.

    Buscando como solucionarlo trate de hacer un ejemplo que me mostrase algún dato por pantalla o algun error, pero si copio el ejemplo de arriba tal cual, el error que me sale es:

    Fatal error: Call to undefined function mcrypt_encrypt() in /var/www/prueba/encriptador.php on line 11

    Alguna idea?

    Gracias y un saludo

  4. Vaya que metedura de pata, ni se me había ocurrido, que novatada!

    Tras pelearme un par de intentos con el terminal ya esta solucionado. Mil gracias

  5. Excelente! me has ayudado mucho!!!

  6. excelente aporte amigo, justo lo que necesitaba para encriptar datos valioso… excelente dia.

  7. Gracias por el aporte tengo una pregunta no me funciona cuando le mando un input de tipo numerico por ejm ‘123’

    output me devuelve asi ‰ƒãÈŽSzp˜s’.u}¢]þ½]Ú[=wâå[&

  8. Quisiera aclarar un poco acerca de la encriptacion asimétrica, pues creo que los conceptos están un poco confusos. La encriptacion asimétrica es la conocida como de llave publica y utiliza protocolos de encriptacion como RSA, Diffie Hellman, etc si yo quiero cifrar algo no tiene sentido el que no se pueda volver a descifrar, en ese caso seria mejor destruir el texto o documento que cifro, Los algoritmos md5 y sha1, son algoritmos que hacen picadillos y como resultado dan una jerigonza de longitud fija, que se utiliza para comprobar integridad y algunas veces autenticacion(guardando el picadillo y luego al introducir la contraseña la hago picadillo y la comparo con el que esta guardado en la db).

    • Muchas gracias por tus aclaraciones Gerardo.
      Un saludo

  9. Os animo a que uséis el término “cifrar” y “descifrar”…
    Me duele el cerebro cada vez que leo “encriptar” o “desencriptar”…

  10. saludos yo uso esta encriptacion

    $md5 = base64_encode(md5($input, true));
    $md5 = strtr($md5, ‘+/’, ‘-_’);
    $md5 = str_replace(‘=’, ”, $md5);

    como podria hacer que me devuelva la solucion

  11. Hola buenas!

    Primero darte las gracias, por que el código me a sido muy útil en diversos aspectos.
    Bueno yo necesito mandar una serie de cadenas encriptadas consumiendo un servicio web, en el lado del servidor esta desarrollado en c#. Necesito saber si por el lado del servidor puedo desencriptar las cadenas antes encryptadas con tu método osea hay compatibilidad ?

Dejar un comentario