Desenvolvimento - Visual Basic .NET

Evitando robôs na Internet através do uso de Verificação de Palavra

Para evitar o problema de robôs na Internet, por exemplo, Spams, muitos desenvolvedores estão implementando o uso de “Verificação de Palavra” onde o usuário é obrigado a informar uma palavra. Veja como implementar.

por David Pomarico



Para evitar o problema de robôs na Internet, por exemplo, Spams, muitos desenvolvedores estão implementando o uso de "Verificação de Palavra" onde o usuário é obrigado a informar uma palavra.

O que é técnica de verificação de palavra?

Locais populares tais como o Yahoo e o Hotmail utilizam a tecnologia de verificação de palavra para reduzir Spams.

Este método consiste em exibir uma imagem que contém algum texto inserido. Os usuários decifram o texto e entram com a palavra decifrada em um TextBox, por exemplo.

Este método serve para diferenciar seres humanos das máquinas, visto que para que uma máquina decifre o texto que será exibido é uma tarefa difícil ou impossível.

Como funciona a técnica?

Em um determinado ponto do software deve-se incluir a lógica, onde a aplicação compara as letras extraídas em uma imagem com o texto digitado. Se os caracteres informados combinarem, o usuário é realmente uma pessoa e não uma máquina tentando acessar algum recurso.

O Hash seria um valor ou uma chave gerada a partir de uma String. O hashing é muito mais rápido do que o encryption porque tem sentido único; você não pode recuperar o valor original de uma String "Hashed". Há um número de algoritmos de hashing disponíveis. O algoritmo SHA1 produz valores tais que o hashing de uma String dada produz sempre o mesmo, e é extremamente difícil que outra String gere o mesmo valor. Conseqüentemente, se você tiver os valores do Hash para duas Strings, você pode comparar se os valores das Strings são idênticas. Você pode ler mais sobre o algoritmo Hash SHA1 neste link: http://www.w3.org/TR/1998/REC-DSig-label/SHA1-1_0

Neste caso, você pode dar o hash nos caracteres no Server e depois enviar para o cliente salvando em um Cookie. Depois que o cliente enviou o post do texto digitado, o server faz o Hash e compara as duas Strings. Se os dois valores das Strings combinarem, você terá certeza de que não é uma máquina tentando acessar os recursos.

Você precisa decidir exatamente como e onde armazenar o valor do Hash quando você for criar a página.

Embora seja possível criar um Web Form que retorne 2 imagens geradas, você não pode retorná-las ambas ao mesmo tempo. Para retornar uma imagem JPEG-formatada, por o exemplo, deve-se ajustar o Response.ContentType para "image/jpeg" e para que retorne HTML, o Response.ContentType é "text/html". Conseqüentemente a maneira mais simples de resolver o problema é usar duas páginas: Uma para retornar o texto, e outra para criar e retornar a imagem.

Bom, tudo isso parece um pouco complicado, mas vamos ver como ficará nosso código. Este é um exemplo que poderá ser adaptado ao seu gosto.

Abra o Visual Studio .Net e inicie um projeto WEB (no artigo foi usado o VB.NET).

- Renomeie o WebForm1.aspx para frmPrincipal.aspx;
- Adicione um WebForm frmRandomImage.aspx;

No WebForm frmPrincipal.aspx, insira os seguintes controles:

- Image (ID: imgImagem; ImageUrl: frmRandomImage.aspx)
- TextBox (ID: txtPalavra)
- Button (ID: cmdVerificar; Text: Verificar)
- Label (ID: lblResultado;Text: deixe vazio)

Veja como ficará o WebForm:

O WebForm frmRandomImage servirá para gerar nossas imagens. Adicione o seguinte código neste WebForm:

Imports

Imports System.Text
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Drawing.Text
Imports System.Drawing.Drawing2D
Imports System.Configuration.ConfigurationSettings
Imports System.Security.Cryptography
Imports System.IO

PageLoad

    Dim b As GeraString
    Dim s As String
    s = b.GenerateRandomString(5)

    Dim hMACIString As String = b. Hash (s)

    "Guarda o resultado em um cookie.
    Dim c As HttpCookie = New HttpCookie("hMACIString")
    c.Value = hMACIString
    Dim dtNow As DateTime = DateTime.Now
    Dim tsYear As New TimeSpan(365, 0, 0, 0)
    c.Expires = dtNow.Add(tsYear)
    Response.Cookies.Add(c)

    Call DrawStringImage(s)

Sub StringImage

Private Sub DrawStringImage(ByVal ds As String)
    Dim rRandom As New Random(System.DateTime.Now.Millisecond) 
    Dim dirBKGIMG As Directory
    Dim afBKGIMG As String()
    Dim fBKGIMG As String
    "Aqui eu configuro o fundo da imagem.
    afBKGIMG = dirBKGIMG.GetFiles(Server.MapPath("BKGIMG"))
    fBKGIMG = afBKGIMG(rRandom.Next(0, afBKGIMG.GetLength(0)))

    Dim bmap As Bitmap = New Bitmap(fBKGIMG)
    Dim g As Graphics = Graphics.FromImage(bmap)
    Dim drawFont As New Font("Arial", 9, FontStyle.Bold + FontStyle.Italic, GraphicsUnit.Millimeter)
    Dim drawBrush As New SolidBrush(Color.Red)
    Dim xPos As Integer = 0
    Dim yPos As Integer = 0
    g.DrawString(ds, drawFont, drawBrush, xPos, yPos)

    Dim pen As Pen = New Pen(Color.Blue, 1.5)
    Dim points As PointF() = {New PointF(rRandom.Next(0, bmap.Width), rRandom.Next(0, bmap.Height)), _
    New PointF(rRandom.Next(0, bmap.Width), rRandom.Next(0, bmap.Height)), _
    New PointF(rRandom.Next(0, bmap.Width), rRandom.Next(0, bmap.Height))}
    g.DrawLines(pen, points)

    Response.ContentType = "image/jpeg"
    bmap.Save(Response.OutputStream, Imaging.ImageFormat.Jpeg)
    g.Dispose()
    bmap.Dispose()
  End Sub

Criando a Classe GeraString

Agora insira uma Classe chamada GeraString.vb. Esta classe servirá para que possamos gerar uma String randômica e também para fazer o Hash da string.

Aqui está o código da classe:

Imports System.Text
Imports System.Security.Cryptography
Imports System.Configuration.ConfigurationSettings

Public Class GeraString
    Public Shared Function GenerateRandomString(ByVal iLength As Integer) As String

        Dim iStartBC, iEndBC, iStartSC, iEndSC, iCount, iTmpC As Integer
        Dim sRandomString As String

        Dim rRandom As New Random(System.DateTime.Now.Millisecond)
        iStartSC = Asc("a")
        iEndSC = Asc("z")
        iStartBC = Asc("A")
        iEndBC = Asc("Z")

        While (iCount < iLength)

            iTmpC = rRandom.Next(iStartBC, iEndSC)
            If (((iTmpC >= iStartSC) And (iTmpC <= iEndSC) _
            Or (iTmpC >= iStartBC) And (iTmpC <= iEndBC))) Then
                sRandomString = sRandomString + Chr(iTmpC)
                iCount = iCount + 1
            End If

        End While
        Return sRandomString
    End Function

    Public Shared Function Hash(ByVal s As String) As String
        Dim b As Byte
        Dim HashValue() As Byte
        Dim retString As String

        "Cria uma nova instancia UnicodeEncoding para converter a string.
        Dim UE As New UnicodeEncoding

        "Converte a string para bytes.
        Dim MessageBytes As Byte() = UE.GetBytes(s & AppSettings("MACKey"))

        "Cria uma nova instancia da classe SHA1Managed
        Dim SHhash As New SHA1Managed

        "Cria o valor Hash do Array de bytes.
        HashValue = SHhash.ComputeHash(MessageBytes)

        "Retorna a representação hexadecimal da String.
        For Each b In HashValue
            retString += b.ToString("X2")
        Next

        Return retString
    End Function
End Class

Agora no Click do botão cmdVerificar em frmPrincipal.aspx, coloque o seguinte código:

        Dim StringImagem As String

        Try
            Dim c As HttpCookie = Request.Cookies("hMACIString")
            StringImagem = c.Value
        Catch ex As Exception
            lblResultado.Text = ex.Message
        End Try

        Dim b As GeraString

        If (StringImagem = b.Hash(txtPalavra.Text)) Then
            lblResultado.Text = "É uma pessoa!!!"
        Else
            lblResultado.Text = "É uma máquina!!!"
        End If

Execute (F5) e veja o resultado:

Observações:

Deve-se digitar as mesmas letras que estão na imagem no TextBox respeitando Caixa Alta e Caixa Baixa. (Upper Case e Lower Case).

Na página acima as letras contém uma imagem de fundo. Essas imagens você poderá montar a seu gosto. Porém par ao projeto funcionar, elas precisam estar em uma pasta chamada de BKGIMG dentro de seu projeto como a imagem abaixo:

Para baixar o projeto completo, clique aqui.

Se você tem interesse em aprender .net ou discutir .net entre no grupo de usuários Codificando.net - São Paulo.

Abraço,
David Pomarico
dcpomarico@uol.com.br
Co-Líder Codificando.NET SP
http://br.thespoke.net/MyBlog/dpomarico/MyBlog.aspx

David Pomarico

David Pomarico - Analista de Sistemas, MCP (Micrososft Certified Professional) em ASP.NET e WindowsForms, atualmente trabalhando em uma multinacional, graduado em Tecnologia em Desenvolvimento de Softwares na Faculdade Informática e Administração Paulista (FIAP), Co-Líder do Grupo de Usuários Codificando.Net SP (www.codificando.net), experiência de 2 anos em .NET, conhecimentos e práticas em Framework .NET, ASP.NET, WinForms, Pocket PC, VB.NET, C#, Crystal Reports.NET, Active Reports for .NET, MS SQL 2000, Oracle 9i, UML, XML.
Visite o meu The spoke: http://br.thespoke.net/MyBlog/dpomarico/MyBlog.aspx