El trastero de José Juan Valid XHTML 1.1 Valid CSS! Estilo de página alternativo
Artículo creado en 2009.
Valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración sobre 66 comentarios.

Captcha PHP

¿Porqué protegernos de un robot?

Desde edades muy tempranas de Internet se ha utilizado el HTTP no sólo para compartir información con los demás. También se ha utilizado profusamente para pedir datos al usuario, bien para almacenarlos, bien para realizar alguna acción con ellos y devolver el resultado al usuario.

Imaginemos los siguientes escenarios:

En todos los casos, queremos ofrecer un servicio a los usuarios (por diferentes motivos: de forma altruista, por hacernos populares, por dar a conocer nuestra empresa o productos, etc...). Sin embargo, es posible que otros sistemas nos perjudiquen o se aprovechen de nuestro trabajo (como ocurre con frecuencia). Así, algunas amenazas para los ejemplos anteriores serían:

Como se ve, existen potenciales riesgos al dejar al público una serie de servicios.

¿Captcha?

Uno de los mecanismos más populares para que un servidor HTTP pueda identificar si la petición a un determinado servicio ha sido realizada por un humano o un autómata, son los CAPTCHA que consisten en una imágen con algunos caracteres que debe reescribir la persona que quiere acceder. Un ejemplo típico, sería el siguiente:

Ejemplo de CAPTCHA hecho en PHP  introduzca las dos letras que aparecen en la imagen.

¿Porqué un Captcha es difícil para un ordenador?

No es fácil responder la pregunta sin entrar en aspectos técnicos, puesto que la dificultad que tiene un ordenador en resolver este tipo de problemas proviene de cómo éste procesa la información. A grandes rasgos, podríamos resumirlo en lo siguiente:

Ejemplos de letras deformadas
Ejemplos de letras deformadas.

¿Se puede romper (hackear) un captcha?

Romper un captcha significa encontrar un procedimiento (algoritmo) que permita a un ordenador automatizar el reconocimiento de la secuencia que contiene la imagen (y que es la que debe suministrarse para acceder al servicio). Parece ser que la mejor forma de romper los captcha es utilizar redes neuronales, sin embargo, para generadores de captcha suficientemente buenos, la cosa se complica lo suficiente como para que el esfuerzo a realizar (para entrenar la red) sea muy grande. Una de las cosas más difíciles es saber separar los diferentes símbolos dentro de una imagen (los cuales, se suelen superponer parcialmente).

Desde mi punto de vista, la lucha entre el generador de captchas y el hacker sería como la fórmula 1, en la que no obstante, el generador tiene todas las de ganar, puesto que la explosión combinacional que se logra añadiendo pequeñas variaciones complican enormemente el trabajo al hacker (por ejemplo, teniendo que reprogramar toda una nueva red neuronal).

¿Qué tipos de captcha hay?

Los más populares son aquellos con unos 5 números o letras, otros contienen palabras e incluso algunos, unas simples operaciones matemáticas (por ejemplo 5 + 2 * 4). No he visto ninguno, pero otros captchas muy fuertes podrían hacer preguntas muy sencillas que variaran de forma automática la forma de la frase ("¿de qué color es el cielo?", "¿cuantas patas tiene un gato?") y aunque tendría algunas desventajas, sería realmente fuerte.

Es seguro que podrían (como en el ejemplo anterior) buscarse variantes o estrategias más o menos parecidas de captcha, sin embargo, el captcha "estandar" es realmente sencillo de implementar.

Muchas variantes complican mucho más el reconocimiento automatizado de captchas como: situar las letras aleatoriamente en la imagen (y no alineadas), superponer parcialmente unas letras con otras, dibujar diferentes letras de diferentes tamaños, aplicar filtros no lineales que deformen la imagen o cada letra, etc...

¿Cómo hacer un captcha en PHP?

Una forma muy sencilla (y creo que elegante) de hacer un captcha en PHP es la siguiente:

Esquema de validación del captcha
Esquema de validación del captcha.

La única desventaja es que en la misma sesión sólo puede haber un captcha simultáneamente, pero ésto debería ser lo normal. La ventaja es que es completamente seguro (a no ser que rompan nuestro generador de captchas, claro) y muy sencillo, pues sólo requiere una variable de sesión.

Si no disponemos de sesión o el objeto de sesión no es compartida entre peticiones de página (algo raro pero que podría darse si el servidor que ofrece el servicio es diferente al servidor que lo da) una solución es aportar junto con la imagen que genera el captcha el código ¡pero encriptado claro!. Aunque ésto es algo más feo y engorroso.

Pero, ¿cómo hacer la imagen del captcha en PHP?

Bueno, yo creo que con el código directamente del script PHP que genera mi captcha es suficiente, lo he comentado bastante así que, no deberías tener problemas.

<?php

/*
	JJBM,   26/03/2009, captcha.php

	Genera una imágen CAPTCHA y almacena en la sesión el código establecido.

	(Obviamente sólo puede usarse una imagen CAPTCHA por sesión a la vez).

*/

// Configuración:
$N = 2;		// Nivel de emborronado { 2, 3, 4, ... }
$J = 100;	// Calidad JPEG { 0, 1, 2, 3, ..., 100 }
$M = 5;		// Margen.
$L = 2;		// Número de letras.
$C = FALSE;	// Case sensitive.

// Acceso a los objetos de sesión:
session_start();

// Indicamos que vamos a generar una imagen ¡no una página HTML!
header("Content-type: image/jpeg");

// Inicializamos cualquier posible valor previo de captcha:
$_SESSION['CAPTCHA'] = '';
// Metemos tantos caraceteres aleatorios como sean precisos:
for( $n = 0; $n < $L; $n++ )
	$_SESSION['CAPTCHA'] .= C();

// Si no es case sensitive lo ponemos todo en minúsculas:
if( ! $C )
	$_SESSION['CAPTCHA'] = strtolower( $_SESSION['CAPTCHA'] );

// Dimensiones del captcha:
$w = 2 * $M + $L * imagefontwidth ( 5 );
$h = 2 * $M +      imagefontheight( 5 );

// Creamos una  imagen:
$i = imagecreatetruecolor( $w, $h );

// La rellenamos de blanco:
imagefill( $i, 0, 0, imagecolorallocate( $i, 255, 255, 255 ) );

// Elegimos aleatoriamente un ángulo de emborronado:
$A = ( rand() % 180 ) / 3.14;

// Realizamos iteraciones de emborronado:
for( $n = 0; $n < $N; $n++ ) {

	// Factor de interpolación, va de 1.0 a 0.0
	$t = 1.0 - $n / ( $N - 1.0 );

	// El radio se va centrando a medida que se hace nítido:
	$r = $M * $t;

	// El color va siendo cada vez más oscuro:
	$c = 255 * $t;
	$c = imagecolorallocate( $i, $c, $c, $c );

	// Trazamos dos líneas aleatorias para dificultar más las cosas:
	imageline( $i, $M, rand( $M, $h - $M ), $w - $M, rand( $M, $h - $M ), $c );
	imageline( $i, rand( $M, $w - $M ), $M, rand( $M, $w - $M ), $h - $M, $c );

	// Pasamos un filtro gaussiano:
	imagefilter( $i, IMG_FILTER_GAUSSIAN_BLUR );

	// Dibujamos el texto en el sentido del ángulo y radio de desplazamiento:
	imagestring( $i, 5, $M + $r * cos( $A ), $M + $r * sin( $A ), $_SESSION['CAPTCHA'], $c );

	// Pasamos otro filtro gaussiano:
	imagefilter( $i, IMG_FILTER_GAUSSIAN_BLUR );
}

// Escribimos la imagen como un JPEG en el buffer de salida:
imagejpeg( $i, NULL, $J );

// Liberamos la imagen:
imagedestroy( $i );

// Devuelve un caracter aleatorio:
function C() {
	$W = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
	return substr( $W, rand() % strlen( $W ), 1 );
}

?>


Opinado el 07/05/09 11:51, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 24/07/09 13:27, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Me parece genial, he visitado al menos 10 páginas mas y en ninguna estaba tan claro, sencillo y bien explicado, sin necesidad de ejecutar nuevos scripts o darse de alta en ningún servicio. Espero que no te importe que use tu código, gracias. paratodo88@yahoo.es
Opinado el 25/08/10 22:39, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 09/10/10 19:37, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 20/10/10 16:30, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Wuau!!!!, gracias
Opinado el 13/12/10 22:54, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Por fin alguien que lo explica bien... saludos..
Opinado el 09/01/11 12:57, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Thanks For This Post, was added to my bookmarks.
Opinado el 22/02/11 12:27, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Great Post. I add this Blog to my bookmarks.
Opinado el 23/02/11 15:30, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 02/08/11 05:28, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    very good
Opinado el 06/09/11 21:35, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 21/10/11 01:22, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 21/10/11 03:05, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 31/10/11 07:12, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Mas o menos me parece bastante ambigua la explicac
Opinado el 08/11/11 16:27, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Donde encuentro un Catpcha Orientado a Objeto?
Opinado el 17/11/11 13:06, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 24/11/11 01:52, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 24/11/11 15:38, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    si, esta mas o menos la expli.. jubaez@hotmail.com
Opinado el 18/01/12 00:22, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Excelente
Opinado el 19/01/12 13:43, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    muy bueno. gracias
Opinado el 19/01/12 21:07, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Bien
Opinado el 15/02/12 20:27, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 10/04/12 21:37, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    victor_fer_554@hotmail.com
Opinado el 17/04/12 04:07, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    como puedo leer un captcha
Opinado el 23/04/12 20:04, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    muchas gracias lo estaba buscando
Opinado el 03/05/12 04:25, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    bacan
Opinado el 11/05/12 03:01, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    mas ayuda porfa juancarlosrobayopaez@gmail.com
Opinado el 13/07/12 18:51, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 30/07/12 23:46, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 22/10/12 13:50, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Excelente
Opinado el 27/11/12 03:14, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    4werwe
Opinado el 28/12/12 18:56, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    excelente men
Opinado el 21/03/13 21:46, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Excelente! Jamás havia usado la variable $_SESSION
Opinado el 25/04/13 20:08, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    dfhjlñ{}{ñlmnbvcvbm,-ljhgdtyuhpojsknbfeikvfpoqewjf
Opinado el 09/06/13 13:44, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Muy bueno ¡¡gracias!!
Opinado el 10/06/13 20:14, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    TEST1
Opinado el 05/07/13 21:59, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    interesantete
Opinado el 15/07/13 15:18, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 05/08/13 06:21, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Excelente aporte. Gracias!
Opinado el 09/08/13 22:29, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    excelente!!!!
Opinado el 28/08/13 16:52, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    no tene lo que quiero :3
Opinado el 30/08/13 14:38, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    bueno
Opinado el 04/09/13 19:06, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    muy bueno
Opinado el 27/09/13 12:11, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 02/10/13 01:20, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 27/10/13 18:45, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    muy bien AnunciosEro.com
Opinado el 03/11/13 00:13, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Excelente Aporte!
Opinado el 11/11/13 19:27, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Muy bueno. Gracias.
Opinado el 29/11/13 08:52, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    muy clarito
Opinado el 27/12/13 13:50, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 28/01/14 18:33, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Muy bueno
Opinado el 04/02/14 07:25, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Muy bueno
Opinado el 04/02/14 23:05, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Buen post, algo que estaba buscando
Opinado el 03/03/14 15:18, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    bueniximo
Opinado el 20/03/14 20:17, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    hola probe el codigo pero no funciono xq?
Opinado el 22/03/14 04:13, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    esta bueno tu aporte y sigue asi.gracias adelante
Opinado el 11/04/14 16:43, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 04/06/14 20:34, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    GENIAL
Opinado el 11/06/14 17:56, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    gf
Opinado el 07/09/14 19:04, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    <script>alert("Hola Mundo!!!!");</script>
Opinado el 06/04/15 10:59, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    ssjjskkjsks
Opinado el 25/04/15 09:45, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    Http://AlterBot.AlterVista.Org Captcha Service Fre
Opinado el 18/08/15 11:54, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 25/08/15 23:21, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    
Opinado el 02/11/15 21:18, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    http://alterbot.altervista.org/contact/ my captcha
Opinado el 11/12/15 20:08, valoración ValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoraciónValoración
    ooo
¿Te ha gustado? ¡aporta tu opinión!
Valoración:
 0    1    2    3    4    5    6    7    8    9    10

Comentario:
NOTA: si es una petición... ¡pon el e-mail al que responderte o no sabré a dónde escribir!

Código de verificación captcha