ASP .NET - Gerando Imagens Captcha (C#)


 Neste artigo vou mostrar como gerar imagens Captcha em uma aplicação ASP .NET usando a linguagem C#.

Vamos iniciar com o conceito de Captcha encontrado na Wikipédia - http://pt.wikipedia.org/wiki/CAPTCHA

CAPTCHA é um acrônimo de -  Completely Automated Public Turing test to tell Computers and Humans Apart -  e envolve um computador (um servidor) que pede que um usuário termine um teste. Como os computadores são incapazes de resolver o CAPTCHA, todo usuário que incorpora uma solução correta é presumidamente humano. O termo foi inventado em 2000 por Luis von Ahn, Manuel Blum , Nicholas J. Hopper e por John Langford.

Um tipo comum de CAPTCHA requer que o usuário identifique as letras de uma imagem distorcida, às vezes com a adição de uma seqüência obscurecida das letras ou dos dígitos que apareça na tela. Como o teste é administrado por um computador, em contraste ao teste padrão de Turing que é administrado por um ser humano, é descrito às vezes como um "teste reverso de Turing".

O CAPTCHA é usado para evitar ataques de robôs ou bots (o termo bots vem de robots, robôs em inglês), programinhas maliciosos que automatizam operações repetitivas. Sem os captchas, esses bots seriam capazes de simular um humano digitando informações aleatórias de modo a criar centenas ou até milhares de  requisições em poucas horas.

Após esta introdução vou mostrar uma forma de implementar a validação por imagens em páginas ASP .NET usando a linguagem C# e um exemplo bem simples.

Recursos usados

Objetivos

Criando o WebSite no VS Express 2013 for web

Abra o VS Express 2013 for web e clique em New WebSite;

A seguir selecione Visual C# -> ASP .NET Empty Web Site;

Informe o local e nome GeraCaptcha e clique no botão OK;

A seguir a partir do menu WEBSITE -> Add New Item;

Selecione o template Web Form e inclua o nome Default.aspx e clique em Add;

Repita  a operação anterior incluindo a página GeraCaptcha.aspx no web site.

Abra o arquivo Default.aspx e defina os seguintes namespaces:

using System;
using
System.Text;

Ainda no arquivo Default.aspx, no modo Design inclua a partir da ToolBox os seguintes controles na página:

Disponha os controles conforme o leiaute da figura abaixo:

Agora no arquivo Default.aspx.cs, no code-behind, inclua o código abaixo no evento Load da página:

  protected void Page_Load(object sender, EventArgs e)
  {
        if (!IsPostBack)
        {
            PreencheCodigoCaptcha();
        }
  }

O código do método PreencheCodigoCaptcha() é visto a seguir:

protected void PreencheCodigoCaptcha()
    {
        try
        {
            Random objAleatorio = new Random();
            string combinacao = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
            StringBuilder codigoCaptcha = new StringBuilder(); 
            for (int i = 0; i < 5; i++)
            {
                codigoCaptcha.Append(combinacao[objAleatorio.Next(combinacao.Length)]);
            }

           Session["codigoCaptcha"] = codigoCaptcha.ToString();
           imgCodigoCaptcha.ImageUrl = "GerarCaptcha.aspx?" + DateTime.Now.Ticks.ToString();
        }
        catch(Exception ex)
        {
            Response.Write(ex.Message);
            lblMsg.Text = ex.Message;
        }
  } 

Este código gera combinação aleatório para gerar a imagem do captcha.

No evento Click do botão - Atualizar Código - inclua o seguinte código:

  protected void btnAtualizaCodigo_Click(object sender, EventArgs e)
  {
        PreencheCodigoCaptcha();
  }

E no evento Click do botão OK insira o código abaixo:

    protected void btnOk_Click(object sender, EventArgs e)
    {
        if (Session["codigoCaptcha"].ToString() != txtCodigoCaptcha.Text)
        {
            Response.Write("Código Inválido, tente novamente");
            lblMsg.Text = "Código Inválido, tente novamente";
        }
        else
        {
            Response.Write("Código Válido !!!");
            lblMsg.Text = "Código Válido";
        }
        txtCodigoCaptcha.Text = string.Empty;
        PreencheCodigoCaptcha();
  }

Este código verifica se o valor informado pelo usuário confere com o captcha gerado.

Para concluir abra o arquivo GerarCaptcha.aspx.cs, e , no code-behind, inclua o seguinte código :

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
public partial class GerarCaptcha : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        try
        {
            Response.Clear();
            int height = 65;
            int width = 150;
            Bitmap objBmp = new Bitmap(width, height);
            RectangleF rectf = new RectangleF(10, 5, 0, 0);
            Graphics objGraphics = Graphics.FromImage(objBmp);
            objGraphics.Clear(Color.White);
            objGraphics.SmoothingMode = SmoothingMode.AntiAlias;
            objGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
            objGraphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
            objGraphics.DrawString(Session["codigoCaptcha"].ToString(), new Font("Chiller", 38, 
FontStyle.Italic), Brushes.Blue, rectf);
            objGraphics.DrawRectangle(new Pen(Color.Green), 1, 1, width - 2, height - 2);
            objGraphics.Flush();
            Response.ContentType = "image/jpeg";
            objBmp.Save(Response.OutputStream, ImageFormat.Jpeg);
            objGraphics.Dispose();
            objBmp.Dispose();
        }
        catch
        {
            throw;
        }
    }
}

Neste código estamos gerando a imagem do captcha, renderizando-a na página e salvando o valor na sessão. (O que pode ser um problema de segurança, não é mesmo ???)

Executando o projeto iremos obter o seguinte resultado:

Este artigo teve o objetivo de introduzir o assunto apresentando uma forma de implementar a validação por imagens em páginas ASP .NET e não deve ser tomado como referência exclusiva.

Se você pretende implementar a técnica em um site de produção deverá usar um código mais robusto e pesquisar melhores opções existentes.

Lembrando que usar CAPTCHA por si só não evita um ataque, visto que já existem robôs que quebram o CAPTCHA  usando algoritmos complexos e técnicas de reaproveitamento da "session-ID" de um captcha conhecido.

Veja este texto publicado no  GLOBO - Informática  por Carlos Alberto Teixeira :

Hoje em dia, encontrar um captcha não é nada difícil. Só que já tem uma rapaziada derrotando captcha. Acredite, tem sim. São brilhantes esses caras. Eles estão construindo bots que capturam um captcha original em um site X, apresentam-no a um humano num site diferente Y, em outro contexto, registram a resposta da criatura e submetem-na de volta ao campo digitado no site X de onde capturaram a figura, transpondo a barreira de segurança e ganhando acesso a seja lá o que for que estão querendo acessar.

Em geral, esses gênios usam como site Y páginas de pornografia, que os tarados virtuais acessam em busca de material para seus devaneios. Assim, fingindo que é uma barreira real, o bot apresenta ao ávido internauta o captcha capturado no site X. O camarada vai lá e digita sua interpretação da figura. O bot pega os caracteres digitados no site pornô Y, que está sob seu controle, e "digita" os mesmos caracteres no site X. E pronto, mais uma vitória da inteligência a serviço do mal.

E veja esse outro artigo que fala sobre assunto - http://exame.abril.com.br/tecnologia/noticias/software-consegue-decifrar-90-dos-captchas-rapidamente

Como exemplo temos  um roteiro que pode ser usado para quebrar o captcha, como mostrou Thiago Galbiatti Vespa em seu artigo :  Quebrando CAPTCHAs

Então todo o cuidado é pouco...

Pegue o projeto completo aqui:  GeraCaptcha.zip

Aquele que diz: Eu conheço-o (Jesus), e não guarda os seus mandamentos, é mentiroso, e nele não está a verdade.
1 João 2:4

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

Referências:


José Carlos Macoratti