2008-11-29 13 views
7

Estoy construyendo un sistema con fuente que estoy distribuyendo en la red para proporcionar mascotas virtuales adoptables. El sistema será propiedad principalmente de niños. Como quiero que pueda ser utilizado por programadores principiantes absolutos, existen varias limitaciones de complejidad en mi sistema: no puede usar bibliotecas que normalmente no incluyen PHP, y no puede tocar una base de datos ni escribir en otro almacenamiento permanente. .Encriptación simple en PHP

Cuando se adopta a cada mascota, el visitante recibirá al azar una de una serie de variaciones ligeramente diferentes de esa mascota. Al principio, las variaciones se ven iguales, pero crecen con el tiempo para convertirse en mascotas diferentes. El visitante recibirá un código corto en HTML que enlaza con la imagen de su mascota. Dado que no hay un almacenamiento permanente disponible en el lado del servidor, el enlace de la imagen del usuario debe contener toda la información para determinar qué variación de mascota terminaron obteniendo.

Por el momento, la URL solo contiene el ID de la mascota y el ID de la variación que obtuvo el usuario. El problema con esto es que, al comparar códigos entre ellos, los usuarios pueden descubrir quién entre ellos terminó con la misma variación. Dado que algunas variaciones son más raras que otras, los usuarios pueden detectar las variaciones raras fácilmente antes de que la diferencia sea incluso visualmente evidente.

Lo que me gustaría es un sistema de encriptación para los detalles en la URL. Algo que oscurece el ID de variación para que cada usuario obtenga una URL diferente con alta probabilidad. Pensé en usar la ID de variación (3 o 4 bits) como los bits bajos o altos de un número aleatorio grande, pero los usuarios detectarán el patrón en esto. Idealmente, el sistema de encriptación se parametrizaría para que cada instalación de mi sistema utilizara un cifrado ligeramente diferente.

La biblioteca mcrypt de PHP probablemente tenga algo útil en ella, pero no parece ser muy común entre los hosters.

¿Existe una ofuscación/encriptación simple, parametrizada que pueda usar aquí?

Respuesta

9

Si está esperando un nivel de sofisticación relativamente bajo, puede hacer un cifrado "xor" muy simple y "almacenar" la clave como parte de la URL. Luego puedes usar el rand de php() o/dev/random o lo que sea para generar claves.

Los usuarios de baja sofisticación no sabrán fácilmente que todo lo que necesitan hacer es xor la mitad inferior de su ID de mascota con la mitad superior para obtener un valor que se pueda comparar con el de sus amigos. Supongo que la mayoría de las personas que podrían reconocer que eso era lo que estaba pasando no se tomarían el tiempo para resolverlo, y esas personas están fuera de su público objetivo de todos modos.

Editar: Si no era obvio, estoy diciendo que le das una llave diferente a cada mascota (ya que dar la misma no resolvería tu problema). Entonces, si la variación de la mascota (petvar) es un número de 16 bits, se genera un número aleatorio de 16 bits (rnd), entonces se hace esto: petvar = (petvar^rnd)<<16 | rnd; y luego se puede revertir esa operación para extraer el rnd y luego el petvar^rnd, y luego solo vuelve a hacerlo para obtener el petvar original.

+0

Suena como una buena estrategia. También podría XOR toda la cadena con una clave específica de la instalación. Sus intuiciones sobre el nivel de sofisticación de los "atacantes" son muy correctas ... :) – thenickdude

2

¿Por qué no simplemente le das a cada usuario una identificación larga y aleatoria y luego almacena todos los detalles sobre su mascota en el servidor? La mejor práctica es no almacenar nada en la URL, cifrado o no. Todo lo que necesitas es una identificación de sesión.

+0

Por supuesto, eso es lo que hago en mi propio servidor. Pero quiero un sistema que los niños puedan usar en su propio servidor para regalar mascotas, incluso si no hay un almacenamiento decente disponible: las bases de datos no siempre están disponibles en proveedores gratuitos y son difíciles de configurar, el almacenamiento de archivos planos requiere demasiado código . – thenickdude

16

Está buscando el cifrado "relleno de una sola vez". Toma una clave y agrega módulo a los caracteres para crear la cadena cifrada.

function ecrypt($str){ 
    $key = "abc123 as long as you want bla bla bla"; 
    for($i=0; $i<strlen($str); $i++) { 
    $char = substr($str, $i, 1); 
    $keychar = substr($key, ($i % strlen($key))-1, 1); 
    $char = chr(ord($char)+ord($keychar)); 
    $result.=$char; 
    } 
    return urlencode(base64_encode($result)); 
} 


function decrypt($str){ 
    $str = base64_decode(urldecode($str)); 
    $result = ''; 
    $key = "must be same key as in encrypt"; 
    for($i=0; $i<strlen($str); $i++) { 
    $char = substr($str, $i, 1); 
    $keychar = substr($key, ($i % strlen($key))-1, 1); 
    $char = chr(ord($char)-ord($keychar)); 
    $result.=$char; 
    } 
return $result; 
} 

Así que esa es una simple encriptación de cadenas.Lo que yo haría es serializar el conjunto de parámetros del usuario y pasarlo como una variable en el enlace:

$arr = array(
    'pet_name'=>"fido", 
    'favorite_food'=>"cat poop", 
    'unique_id'=>3848908043 
); 
$param_string = encrypt(serialize($arr)); 

$link = "/load_pet.php?params=$param_string"; 

En load_pet.php que debe hacer lo contrario:

$param_string = $_GET["params"]; 
$params = unserialize(decrypt($param_string)); 

Bam.

+0

Por supuesto, este es solo un bosquejo aproximado. Tendrás que manejar el caso en el que el usuario pasa una cadena param no válida ... por ejemplo, no se desmeritará, así que tienes que atrapar eso. –

+1

No veo nada aquí que dé diferentes resultados para la misma entrada, que es lo que estoy buscando. – thenickdude

+0

Lo siento, no entendí ... :) – thenickdude