Encriptar y desencriptar cadena con PHP

Cualquier programador Web ha podido necesitar pasar datos por $_GET – en la url – , es una forma fácil y cómoda de pasar valores de una página a otra, pero… en algunos casos puede no ser recomendable y habría que tener un mínimo de precaución, y para estos casos – y otros muchos – se puede utilizar esta clase que un día vi – no se donde, si lo supiese pondría la fuente – y sobre la que me veo obligado a escribir, mas que nada para tenerla presente yo mismo y darla a conocer a quien pueda necesitarla.

Ya de paso, esto puede servirnos en algún que otro caso para evitar inyecciones SQL, y así evitar que alguien nos mangonee lo que no debe.

Primero: Encriptar

function encrypt($string, $key) {
   $result = '';
   for($i=0; $i<strlen($string); $i++) {
      $char = substr($string, $i, 1);
      $keychar = substr($key, ($i % strlen($key))-1, 1);
      $char = chr(ord($char)+ord($keychar));
      $result.=$char;
   }
   return base64_encode($result);
}

Se utiliza un código secreto, que es el que se pone en $key y que cuando desencriptemos necesitaremos saberlo para que lo haga correctamente.

Para encriptar una cadena escribimos

$cadena_encriptada = encrypt("LA CADENA A ENCRIPTAR","LA CLAVE");

Segundo: Desencriptar

function decrypt($string, $key) {
   $result = '';
   $string = base64_decode($string);
   for($i=0; $i<strlen($string); $i++) {
      $char = substr($string, $i, 1);
      $keychar = substr($key, ($i % strlen($key))-1, 1);
      $char = chr(ord($char)-ord($keychar));
      $result.=$char;
   }
   return $result;
}

Y para desencriptar la cadena escribimos

$cadena_desencriptada = decrypt("LA CADENA ENCRIPTADA","LA CLAVE QUE SE USÓ PARA ENCRIPTARLA");

Comentarios (76)

buena, pero me gustaria sabe como se utiliza, al momento de hacer de presionanr un link con datos en el get. gracias…

Muy Bueno muchachos, justo lo que necesitaba, lo probé funciono perfecto, lo bueno es que cada uno le pone la palabra clave que quiere.
Muchas Gracias

A ver … si creamos un usuario, guardara una clave encriptada en la base de datos …

si queremos hacer un login tendriamos que desencriptar la clave y compararla con lo que se ingreso como contraseña.

A la hora de desencriptar la clave de la base de datos devuelve caracteres ASCII ilegibles como rombos(�) o figuras (si saben de lo que hablo verdad ?) que son imposibles de comparar con lo que el usuario ingreso.

¿ hay algunos caracteres que no se pueden ingresar ?
por ejemplo la clave 123 la tengo encriptada como «hIJm»
la desencripto y me devuelve cualquier cosa menos 123.

Me di cuenta que el metodo encriptar siempre te da la misma cadena encriptada – OJO!

esto significa que para la cadena 123 encriptara hIJm segun la SEMILLA que uses.

lo que hice fue encriptar la cadena que ingresa el usuario y compararlo con lo que tengo en la base de datos. Felicidad!

recomiendo cambiar el valor de $key Periodicamente ya que si lo usamos un largo tiempo la contraseña puede ser deducida facimente si se sabe la semilla.

Claro que da siempre el mismo resultado, si no, no se podría desencriptar, esa es la gracia.

Si lo que quieres es sólo usarlo para comparar, deberías usar otro tipo de encriptación como md5, para la que no exista, almenos en la teoría, forma de desencriptar la cadena.

excelente metodo,
me haz ahorrado mucho.
gracias por tu aporte..

y para roger:
claro que tiene que dar igual, el chiste es encriptar una cadena y guadarlo en la BD y luego usar la clave para obtener texto legible…

Una vez que se insertan los datos encriptados, y después quieres realizar consultas no coinciden para las busquedas, Ejemplo:
Nombre: usuario apellido1 apellido2
En BD : Azxdcvd aRdhcksow Ghradscda

Busqueda: apellido1
Encriptada: Jkyts
Query: SELECT nombre from user WHERE 1=1 AND nombre like ‘%Jkyts%’ ORDER BY id ASC LIMIT 0, 5

No coincide aún que el nombre si contiene apellido1

Gracias Josep por tu aporte, era lo que estaba buscando.
Pero no me funciona a la hora de desencriptar, parte de la ruta descifrada la muestra correctamente pero otra parte la devuelve con caracteres ASCII ilegibles. ¿Que estoy haciendo mal? Dime algo si puedes y disculpa por darte la lata.

Excelente funcion, pero segun entiendo es simplemente para encriptar parametros enviados por la URL, el chiste entiendo es que los usuarios no logren determinar los valores que se enviar por dicha URL, lo cual me parece muy bueno el ejemplo

ese cod tengo

<?php

function encrypt($string, $key) {
   $result = '';
   for($i=0; $i<strlen($string); $i++) {
      $char = substr($string, $i, 1);
      $keychar = substr($key, ($i % strlen($key))-1, 1);
      $char = chr(ord($char)+ord($keychar));
      $result.=$char;
   }
  return base64_encode($result);

}

function decrypt($string, $key) {
   $result = '';
   $string = base64_decode($string);
   for($i=0; $i

Me han encantado las funciones. Ya usaba un método parecido, pero mas complicado por una parte, y rudimentario por otra.

Por otro lado, después de varias pruebas satisfactorias me he encontrado con algo bastante problemático a la hora de utilizar el siguiente código de ejemplo:

Si le hago un decrypt a ese $argumento, funciona perfectamente y me devuelve ‘logout=1’.

El problema: Al pasar por url ese ‘4OLI2+nnnp0=’ el método $_GET lo interpreta como ‘4OLI2 nnnp0=’, con lo que al acceder a una url tipo ‘pagina.php?a=4OLI2+nnnp0=’ pasa lo siguiente:

Mi primera chapuza ha sido cambiar ‘salt’ por otras cadenas y solucionaba ese aparatoso ‘+’, pero podría aparecer en cualquier otra cadena que quisiera encriptar.

La solución que estoy usando ahora es la siguiente:

$argumento=urlencode(encrypt('logout=1', 'salt'));

Tomando la precaución de NO USAR urldecode después en el $_GET.

Espero que sea util mi aportación.

Lo siento, parece que mi comentario anterior ha perdido el php que le había puesto. Reenvio quitando las etiquetas ‘code’.

Me han encantado las funciones. Ya usaba un método parecido, pero mas complicado por una parte, y rudimentario por otra.

Por otro lado, después de varias pruebas satisfactorias me he encontrado con algo bastante problemático a la hora de utilizar el siguiente código de ejemplo:

Si le hago un decrypt a ese $argumento, funciona perfectamente y me devuelve ‘logout=1’.

El problema: Al pasar por url ese ‘4OLI2+nnnp0=’ el método $_GET lo interpreta como ‘4OLI2 nnnp0=’, con lo que al acceder a una url tipo ‘pagina.php?a=4OLI2+nnnp0=’ pasa lo siguiente:

Mi primera chapuza ha sido cambiar ‘salt’ por otras cadenas y solucionaba ese aparatoso ‘+’, pero podría aparecer en cualquier otra cadena que quisiera encriptar.

La solución que estoy usando ahora es la siguiente:

Tomando la precaución de NO USAR urldecode después en el $_GET.

Espero que sea util mi aportación.

Hola Javier, tampoco se han visto los códigos en el segundo comentario : ) no te preocupes; ya se entiende lo que quieres decir.

Miraré de editar el articulo para explicar lo que comentas, la verdad es que nunca había pasado por esa situación y puede que sea el motivo por el que hay algunos comentarios diciendo que no funciona bien…

Gracias.

Una codificacion en 64 Segura:

function encrip($cadena,$clave) {
global $core;
$resultado = »;
for($i=0; $i<strlen($cadena); $i++) {
$char = substr($cadena, $i, 1);
$keychar = substr($clave, ($i % strlen($clave))-1, 1);
$char = chr(ord($char)+ord($keychar));
$resultado.=$char;
}
return str_replace(array('+', '/', '='), array('-', '_', ''), base64_encode($resultado));
}

function decrip($cadena,$clave) {
global $core;
$resultado = '';
$cadena = base64_decode($cadena);
$cadena = str_replace(array('-', '_'), array('+', '/'), $cadena);
for($i=0; $i<strlen($cadena); $i++) {
$char = substr($cadena, $i, 1);
$keychar = substr($clave, ($i % strlen($clave))-1, 1);
$char = chr(ord($char)-ord($keychar));
$resultado.=$char;
}
return $resultado;
}

No funciona si el texto a encriptar y desencriptar contiene ñ o tildes, entiendo que no vale para cadenas tipo utf-8 como Árabe, Persa, etc

tenía el mismo problemita, pues yo lo hice con un salt aleatorio y a veces me salía el + y lo distorcionaba todo, buenas las funciones y el aporte, aunque sería
así:
$cadena = base64_decode($cadena);
$cadena = str_replace(array(‘-‘, ‘_’), array(‘+’, ‘/’), $cadena);
en lugar de:
$cadena = base64_decode($cadena);
$cadena = str_replace(array(‘-‘, ‘_’), array(‘+’, ‘/’), $cadena);

lo envíe mal era, primero remplazar y luego decodificar
así:
$cadena = str_replace(array(‘-’, ‘_’), array(‘+’, ‘/’), $cadena);
$cadena = base64_decode($cadena);

en lugar de:
$cadena = base64_decode($cadena);
$cadena = str_replace(array(‘-’, ‘_’), array(‘+’, ‘/’), $cadena);

No creo que sea la solución, que pasaría si encriptas la cadena «300_400», al encriptar y desencriptar me cambiaría la _ por /, no? No lo he probado pero creo que iría por ahí.

Salud.

Muy buen aporte, solo una cosa extraña q me sucede: al generar una contraseña con números aleatorios (específicamente las terminadas en 30, 31, 32, 34 hasta 39) al encriptarlas y al desencriptarlas me aparece este simbolo «/» , «.» o «0» en lugar de los números mencionados anteriormente. me gustaría saber a se debe esto, y si tiene una explicacion, muchas gracias de antemano

Que clase tan mala… He visitado varios sitios ya y solo he encontrado scripts para niños, es mala tu codificación porque siempre te regresa el mismo resultado ejemplo

holamundo = aG9sYW11bmRv

Siempre sera ese valor, deberia de variar.

Perfecto, me ha servido mucho, muchas gracias.

A lo mejor llego un poco tarde, pero para los que han puesto los comentarios sobre el login: NO USÉIS ESTE MÉTODO PARA GUARDAR CONTRASEÑAS.
Cuando encriptas una contraseña, siempre se puede desencriptar, por eso no es seguro. Una función hash lo que hace es generar una cadena única para cada valor de entrada, e irreversible, por lo que nunca se podrá desencriptar (buscad sha256 para más información).

Y si no se puede desencriptar, ¿cómo comprobamos que el usuario la escribió bien?
Muy fácil, le aplicamos la función hash a la contraseña que ha introducido el usuario y comparamos los hash en vez de la contraseña. Un mismo texto siempre dará el mismo hash.

Las funciones estas no son 100%, porque si bien permiten el uso de una «semilla», si ésta difiere en una letra ya comienza a mostrar parte del texto originalmente escrito, lo cual es algo peligroso.

Si se puede usar para encriptar una clave, ya que si hacemos un MD5 del valor encriptado generará una encriptación nueva (no reversible), con lo que estaríamos aplicando 2 encriptaciones. Luego, al retomar la clave, que siempre se hace por comparación, debido a que MD5 no permite volver a convertirse al texto original, se debe hacer la encriptación de la clave enviada por el usuario, usando el código este, luego volverlo a encriptar con MD5 y compararlas.
Podríamos decir que es un poco paranóico, pero es otra de las tantas posibilidades al momento de encriptar una clave, sobre todo en el supuesto caso de que alguien nos pudiera robar la base de datos. Así sería mucho más difícil poder lograr descifrar cual es la clave, porque habría que saber cual fue la semilla que se usó en la primera encriptación y luego pasarlo a MD5 (que, dicho sea de paso, también se le puede poner una semilla, con lo que se hace más «resistente» aún).

Y para los que decían que les aparecen rombos o codificaciones raras, deben verificar la codificación de la página en cuestión así como también la codificación de la base de datos, que puede ser UTF-8, Latin1 (ISO-8859-1), etc… También pueden valerse de las funciones ICONV, UTF8_ENCODE y UTF8_DECODE. Con la utilización de estas funciones, pueden resolver cualquier problema de rombos y/o códigos raros.

Saludos!

funciona bien, pero he visto un fallo que no logro ver por qué es y me trae loco… si pongo por ejemplo la cadena «puliendo2@gmail.com» en la misma página la encriptacion y desencriptacion funciona perfectamente, pero al mandar por GET a otra página, ese mail en concreto, no lo desencripta luego bien, en cambio otros como pepe12@gmail.com o lo q sea, sí lo hace…. la verdad que no entiendo qué ocurre

ya he solcionado el problema, era un conflicto de caracteres recogidos, no del método para encriptar/desencriptar

Creo que el problema es que, si la cadena resultante de encriptar contiene el carácter +, al pasarlo get, interpretará el + como un espacio (y lo eliminará).

Diría que alguien ya lo ha comentado en alguno de los 54 comentarios que tiene ya este post : )

Salud.

Alguien me puede decir como llamo la funcion desde el formulario que voy a enviar, que coloco en el action.

Le agradesco su colaboracion. Gracias

esta es la solución mas completa que les puedo aportar.

En la pagina inicial:
index.php

<?php
function encrypt($string, $key)
{
   $result = '';
   for($i=0; $iusuario = encrypt('luis',"UFPSOUSUARIO");
$objeto->clave = encrypt('123456',"UFPSOCLAVE");

$argumento=urlencode(serialize($objeto));
?>

location.href="destino.php?argumento=";

y en la pagina destino.php:

<?php 
function decrypt($string, $key)
{
   $result = '';
   $string = base64_decode($string);
   
   for($i=0; $iusuario." ( ".decrypt($objeto->usuario,"UFPSOUSUARIO")." ) ";
echo "";
echo $objeto->clave." ( ".decrypt($objeto->clave,"UFPSOCLAVE")." ) ";
?>

En la vida hay que ser agradecido, asi que muchas gracias me fue de mucha utilidad gracias a esto paso la materia hahahahaha Mil Gracias y cerramos php ?>

No me funciona, tengo ese problema con la url del + y cuando hago una peticion con urlencode me salta:

Not Found

The requested URL /video/wsO3tcWthWDjmZ2SYamgaX3PwnGmxNa+mvCdldGi3J9nh4m4t6q/5oWEvnu4poLCtYSXnn6WiZXEmoPHfbWqdKPdpoM= was not found on this server.

Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.

Alguna solución en la que no se tenga que usar los caracteres como + ?

Hola, es un articulo muy antiguo, tiene ya 6 años. Seguro que encuentras mejores formas de hacer lo que aquí se propone.
Si quieres usar lo que proponía en su día, creo que en los 63 comentarios que acumula a día de hoy hay algunas respuestas que pueden servirte.
A mí lo primero que se me ocurre es que puedes codificar el valor en criptado en base64 para pasarlo por la url y luego decodificarlo antes de desencriptarlo.

Salud.

para JOSEP VICIANA Mira el código que propone el blog para encriptar y desencriptar se basa en —-base64—- entonces no es ningún aporte nuevo decir que—– «A mí lo primero que se me ocurre es que puedes codificar el valor en criptado en base64 para pasarlo por la url y luego decodificarlo antes de desencriptarlo.»

A mi me funciono muy bien y con un par de trucos añadidos, la encriptacion esta segura; lo tengo trabajando en una aplicacion real….. Noviembre 03 2017

Ademas que la encontre muy simple, con un poco de imaginacion salio muy bien.

Gracias

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.