lunes, 21 de marzo de 2011

Protegiendo la propiedad intelectual (encriptar, codificar, compilar código PHP)

Bien, todos sabemos que los scripts de PHP no pueden ser vistos de parte del cliente. Estos se ejecutan en el servidor y dan como resultado, por lo general un HTML.

Sin embargo, los desarrolladores sabemos que estos scripts de PHP son eso justamente, un archivo de texto donde se encuentra todo nuestro código. El motor de PHP en el lado del servidor se encarga de interpretar este script que está en "lenguaje de alto nivel", luego crea un opcode (que vendría a ser lo que un bytecode es para java) y luego lo ejecuta para dar como resultado el HTML.

El problema está en que estos scripts los subimos directamente al servidor donde serán interpretados y luego ejecutados. Eso quiere decir que nuestros clientes y cualquier persona que tenga acceso a los archivos de nuestro servidor podrán revisar nuestro código, cambiarlo, copiarlo o redistribuirlo sin que nosotros (los creadores de esta propiedad intelectual) tengamos algún control o beneficio.

Esto va en contra de mi filosofía porque yo soy un amante del OpenSource. Es más, muchos de mis códigos los publicaré en este blog para el beneficio de todos (incluyéndome con sus críticas). Sin embargo, hay que darnos un poco de crédito ya que esta es nuestra forma de vida.

Existe la opción de "encriptar" o "codificar" nuestro código PHP para que sea ilegible por alguna persona poco entendida en el tema. Este método se basa en la codificación con las funciones base64_decode base64_encode. De tal manera de que si se tiene el siguiente código PHP:

<?php
echo "Hello World";
?>

El script codificado sería:

<?php $_F=__FILE__;$_X='Pz48P3BocA0KNWNoMiAiSDVsbDIgVzJybGQiOw0KPz4=';
eval(base64_decode('JF9YPWJhc2U2NF9kZWNvZGUoJF9YKTskX1g9c3RydHIoJF9YLCcxMjM0NTZhb3VpZScsJ2FvdWllMTIzNDU2Jyk7JF9SPWVyZWdfcmVwbGFjZSgnX19GSUxFX18nLCInIi4kX0YuIiciLCRfWCk7ZXZhbCgkX1IpOyRfUj0wOyRfWD0wOw=='));?>

A esto se le llama encriptar, pero es una opción poco segura porque aplicando la inversa de la función se obtiene el código original.

Existe también lo que se llama ofuscar el código, que es cambiar de nombre a las variables, encriptar los textos, eliminar los cambios de línea, etc. Esto hace un poco difícil de leer y entender el código y, sumado a una encriptación como la que expliqué anteriormente, resulta una forma un poco más eficiente de proteger nuestro código.

Para encriptar nuestro código existen varias herramientas muy fáciles de encontrar en internet. Les ofrezco esta que es online: http://www.byterun.com/free-php-encoder.php.

Tenemos una opción mucho más segura que es "precompilar" nuestro código que es como crear un .class si trabajáramos con Java. Esta opción tiene varias ventajas. Primero, y lo más importante es que nuestro código no puede ser interpretado de manera inversa. Además, contrariamente a la encriptación, ahorra recursos de procesamiento ya que no es necesario interpretar el script. El método de encriptación por el contrario lo que hace es incluir un proceso más de "desencriptado" y esto hace más lenta la ejecución de este script. Se puede especificar una fecha de caducidad, se pueden manejar licencias, etc. Así que está bastante bueno para hacer aplicaciones web distribuíbles y propietarias.

Existen varias herramientas gratuitas para hacer esto pero yo voy a enseñar cómo usar la más común ZendGuard. Ésta no es una herramienta libre, tiene un costo. Así que tendrán que pagar la licencia si lo quieren usar así como yo ya la estoy usando. El Zend Guard, así como el Zend Studio están en una interfaz gráfica de Eclipse que todos conocemos muy bien.

Es necesario mencionar que, del lado del servidor, es necesario tener instalado el servicio Zend Optimizer. Pero este software es gratuito y está instalado en todos los servicios de alquiler de host por defecto.

Ahora, hagamos un pequeño ejercicio. Luego de instalar el Zend Guard en nuestras computadoras y luego de que logremos que funcione la licencia, lo abrimos y creamos un nuevo proyecto indicando todos los campos necesarios:




Seleccionamos el output que es la carpeta donde se guardarán nuestros archivos compilados, yo lo he puesto en una subcarpeta de mi public llamada proyectoPHPcomp y tengo los "originales" en una subcarpeta proyectoPHP. Y listo! bueno, obviamente falta colocar nuestros archivos en el proyecto recientemente creado. Para hacer la prueba crearemos un index.php y una clase Persona. Lo haré así porque considero que lo que más uno quiere proteger es el diseño técnico de la aplicación más que el diseño gráfico para darle la posibilidad al cliente de modificar algunas cosas de diseño gráfico de su web. Pero la algoritmia y programación de los procesos los colocaremos en clases compiladas.

Tenemos una clase Persona de ejemplo en el archivo Persona.php


<?php
class Persona {
public $id;
public $nombre;

public function Persona($nombre = NULL) {
$this->nombre = $nombre;
}

}

?>

Con su respectivo constructor, una clase muy sencilla pero que puede almacenar todo nuestro algoritmo y valioso trabajo.

Y este es nuestro archivo index.php que no compilaremos para permitir al cliente manejar el diseño de su web. Total, la lógica del negocio está en la clase Persona sólo hay que saber qué se puede hacer con esta clase. Para el ejemplo sólo da el nombre de una persona.

<?php
include_once "classes/Persona.php";
$persona = new Persona("Justo Debarbieri");
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link href="styles.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="scripts.js"></script>
<title>Creación de una Persona - PHP Compilado</title>
</head>
<body>
<h1>Creación de una Persona - PHP Compilado</h1>
<table>
<tr>
   <td>Nombre:</td>
   <td><?= $persona->nombre?></td>
    </tr>
</table>
</body>
</html>

Agregamos estos archivos en nuestro proyecto en la siguiente ventana del wizard. Mis originales los tengo en la subcarpeta proyectoPHP:


Dejamos los default del wizard y terminamos. Y queda así nuestro explorador de proyectos:


Al lado derecho vemos muchas opciones donde se puede indicar la fecha de caducidad de los scripts, si quieres ofuscar los nombres de las variables, funciones y clases, manejo de licencias, etc. Se puede modificar la cabecera que se mostrará en caso no se tenga instalado el Zend Optimizer de lado del servidor. Ahora hay que especificar que no queremos que el archivo index.php sea compilado. Simplemente le damos clic derecho y seleccionamos "Exclude Resource" lo que permite copiar el archivo en el output sin ser compilado.

Ahora hacemos clic derecho sobre el proyecto y seleccionamos "Encode Project".

El archivo index.php queda igual pero el archivo Persona.php con caracteres extraños que ni siquiera puedo copiar acá. Pero sigue manteniendo la extensión .php eso quiere decir que los debemos seguir incluyendo como si fueran archivos PHP normales.

Suerte con sus proyectos!

7 comentarios:

  1. Buena info.

    Un apunte, si me lo permites: según tengo entendido, "encriptar" es lo que hace (por ejemplo) sha1, y no se puede "desencriptar"; por otra parte, se puede "codificar", para luego "decodificar".

    Por tanto (según mi entender), base64 es una función de codificación (ya que se puede decodificar).

    Un saludo!

    ResponderEliminar
    Respuestas
    1. en ese orden de ideas la palabra desencriptar no existiría en el diccionario..... sin embargo tienes razon en que base64 es un encoder

      Eliminar
  2. Que Buen Post, tambien queremos compartirles 2 sitios que nosotros usamos para encriptar paginas, con demostracion gratuita

    para encriptar codigo html :

    www.protegerhtml.info

    y para encirptar codigo php:

    www.protegerphp.info

    saludos

    ResponderEliminar
  3. www.protegercodigo.info simplemente usa un encode_base64 muy fácil de decodificar ... solo coloquemos en un decodificador este código DQoNCiRhPTE7DQoNCiRiPTI7DQoNCiRjPSRhKyRiOw0KDQplY2hvICJFbCBwcmltZXIgbnVtZXJvIGVzOiAiLiRhOw0KDQplY2hvICI8YnI+IjsNCg0KZWNobyAiRWwgc2VndW5kbyBudW1lcm8gZXM6ICIuJGI7DQoNCmVjaG8gIjxicj4iOw0KDQplY2hvICJMYSBzdW1hIGRlIGFtYm9zIG51bWVyb3MgZXM6ICAiLiRjOw0KDQpleGl0Ow0KDQo/Pg==

    y obtendremos el ejemplo Todoelsecreto stá en esta función, function pregg_match($matchwordx) {
    $matchwordx=substr($matchwordx,50,strlen($matchwordx));
    $matchwordx=strrev($matchwordx);
    $matchwordx=substr($matchwordx,50,strlen($matchwordx));
    $matchwordx=base64_decode($matchwordx);
    return $matchwordx;
    }

    ResponderEliminar
  4. Si queremos algo que sea medianamente válido tendremos que optar por Zend Guard o Iioncube, y sin garantía total ...

    ResponderEliminar
  5. Esta extremamente cara, mejor buscar otras opciones o cambiar de lenguaje, aunque también hay aplicaciones para ver el código de dll de c# la cual era mi otra opción :/

    ResponderEliminar