Click here to Skip to main content
Click here to Skip to main content

Creating CAPTCHA-Like Functionality in ASP.NET

, 8 Dec 2006
Rate this:
Please Sign up or sign in to vote.
How to create CAPTCHA-like functionality in ASP.NET.

Introduction

According to Wikipedia, CAPTCHA ("Completely Automated Public Turing test to tell Computers and Humans Apart") is a challenge response test which is used to check if the user is human or not. CAPTCHA is used exclusively in applications where user input is required. These applications include blogs, forums, and portals. In this article, I will demonstrate how to create a simple webpage that uses the CAPTCHA functionality.

The CreateImage Method

The first task is to create an image and put it on the screen. For that, I have created an ASP.NET page named CaptchaControl.aspx. The CaptchaControl.aspx page will be responsible for displaying the image to the user. Let’s take a look at the following code which generates the image:

private void CreateImage()
{

    string code = GetRandomText();
    Bitmap bitmap = new Bitmap(200,150,
           System.Drawing.Imaging.PixelFormat.Format32bppArgb);
    Graphics g = Graphics.FromImage(bitmap);
    Pen pen = new Pen(Color.Yellow);
    Rectangle rect = new Rectangle(0,0,200,150);
    SolidBrush b = new SolidBrush(Color.DarkKhaki);
    SolidBrush blue = new SolidBrush(Color.Blue);
    int counter = 0;
    g.DrawRectangle(pen, rect);
    g.FillRectangle(b, rect);

    for (int i = 0; i < code.Length; i++)
    {
        g.DrawString(code[i].ToString(), 
           new Font("Verdena", 10 + rand.Next(14, 18)), 
           blue, new PointF(10 + counter, 10));
        counter += 20;
    }

    DrawRandomLines(g);
    Response.ContentType = "image/gif";
    bitmap.Save(Response.OutputStream,ImageFormat.Gif);
    g.Dispose();
    bitmap.Dispose();

}

There is a bunch of stuff going on inside the CreateImage method. The GetRandomText method generates the random text and returns to the caller. If you are unfamiliar with creating random strings, then I would suggest that you check out my article: Creating Random Passwords. After I create the Rectangle where the text would appear, I resize the text to give it a strange look. Finally, I call the DrawRandomLines method which protects the image from OCR software.

The GetRandomText Method

The purpose of the GetRandomText method is to generate a random text every time a user gets the old text wrong. Take a look at the simple method which returns the random text.

private string GetRandomText()
{

    StringBuilder randomText = new StringBuilder();

    if (Session["Code"] == null)
    {

        string alphabets = "abcdefghijklmnopqrstuvwxyz";
        Random r = new Random();

        for (int j = 0; j <= 5; j++)
        {
            randomText.Append(alphabets[r.Next(alphabets.Length)]);
        }
        Session["Code"] = randomText.ToString();
    }
    return Session["Code"] as String;
}

The DrawRandomLines Method

The DrawRandomLines method puts the lines on the text which is displayed on an image. The purpose of these lines is to make it difficult for the bots to read the text. This way the text can only be read by humans.

private void DrawRandomLines(Graphics g)
{
    SolidBrush green = new SolidBrush(Color.Green);

    for (int i = 0; i < 20; i++)
    {
        g.DrawLines(new Pen(green, 2), GetRandomPoints());
    }

}

private Point[] GetRandomPoints()
{

    Point[] points = { new Point(rand.Next(10, 150), 
                       rand.Next(10, 150)), 
                       new Point(rand.Next(10, 100), 
                       rand.Next(10, 100)) };
    return points;
}

Using the CAPTCHA Page

We have created the CAPTCHA feature, but the question is how do we use it. In order to use the CAPTCHA feature, you will need to create a page which consumes the CaptchaControl.aspx page. I have created the Default.aspx page which uses the CaptchaControl.aspx as the ImageUrl to the ASP.NET Image control. Check out the complete HTML code of the Default.aspx page.

<form id="form1" runat="server">
<div>
<asp:Image ID="myImage" runat="server" 
     ImageUrl="~/CaptchaControl.aspx" />
<br />
<br />
Enter code: <asp:TextBox ID="TextBox1" runat="server">
            </asp:TextBox>
<asp:Button ID="Button1" runat="server" 
     Text="Validate" OnClick="Button1_Click" />
<br />
<br />
<asp:Label ID="lblError" runat="server" Font-Bold="True" 
     Font-Size="X-Large" ForeColor="Red"></asp:Label></div>
</form>

The important thing to note is the ASP.NET Image control which requests the CaptchaControl.aspx page and generates the image. The code for the validation of the user text against the CAPTCHA text is pretty simple, and you can view it in the downloaded files.

Below is an image of how the application looks like:

Conclusion

In this article, I demonstrated how easy it is to create a CAPTCHA feature. This feature can play a very important role in the security of a web application.

I hope you liked the article, happy programming!

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

azamsharp
Web Developer
United States United States
I am the founder of knowledge base website, HighOnCoding, GridViewGuy, RefactorCode.com and ScreencastADay.com.
 
HighOnCoding is a website which will get you high legally with useful information. There are tons of articles, videos and podcasts hosted on HighOnCoding.
 
HighOnCoding.com www.HighOnCoding.com
 

My Blog:

Blog

 

Buy my iPhone app ABC Pop

Comments and Discussions

 
Questionsimple captcha Pinmembershanid36014-Jun-12 19:34 
GeneralHello Sir PinmemberSaurabh Chandak20-Aug-10 0:23 
QuestionIs there a ASP.NET VB version floating around? Pinmemberprojecthiphop27-Jun-07 13:33 
GeneralThank you Pinmembercykophysh3925-Feb-07 3:59 
GeneralEnhancement Pinmemberjcvest26-Dec-06 8:06 
In addition to the comments above, some more suggestions:
 
First, it is critical (for usability) that certain letters/digits be EXCLUDED from valid captcha strings. Also, the input MUST NOT be case-sensitive.
 
Because a good captcha algorithm will skew and scale each character individually, proportion is lost meaning that users cannot necessarily distinguish lowercase/uppercase. So the input check algorithm must not be case-sensitive.
 
The letters Q, T, I, O, D, G, L, B should never be used.
The lowercase e, c, g, q, a, m, h, l, i, j, r, should likewise be avoided.
And the digits 1, 4, 6, 9, 0 should not be used.
While this reduces the available set of characters, the remaining set is still large enough to adequately provide security. In captchas which use common words instead of random strings, most of these letters can still be used because context allows the user to determine the appropriate character even when it is not clearly distinguishable on its own.
 
Instead of wasting server resources on Session or Cache, the implementor would do better to store a value in Viewstate or a hidden field. Simply store a secure hash of the actual (decoded) string in the page itself, then when the page is submitted, you hash the user's input (after normalizing to remove spaces and to convert all to upper or lower-case), and compare that to the stored hash. A match indicates a successful entry, while still prohibiting bot abuse and without wasting resources on the server.
 
Finally, captcha implementors would do well to pay close attention to the business case that necessitates the captcha ...
For resources which are extremely attractive to bots, such as free email accounts, very tight captcha authentication (i.e. very difficult "OCR-proof" captchas) is called for. But most cases do not require this. For example, if the purpose is simply to reduce bandwidth expenditures by limiting scraper bots from pulling sports scores from your site, you would do well to implement easier captchas which are much friendlier to your users.
The captchas of myspace and yahoo, for example, are quite successful at thwarting OCR-enabled bots, but they are very painful for humans. Even with good eyesight and literacy, it's not uncommon for a human to fail two or three times at their captcha's before succeeding.
 
If you business case for anti-bot security is not so critical, you would be advised not to abuse your human users with such painful captchas, and instead go with clearer images and use common words instead of random strings ... these steps will be greatly appreciated by your users while still blocking all but the most determined botters. (And you would do good to remember that even myspace, yahoo, etc., with all of their painful anti-bot measures, are still swarming with bots. I can tell you firsthand, if a real coder is determined, their measures are inconveniences not stoppers!).
 
Hope that helps those who choose to implement this.
 
Joe

GeneralRe: Enhancement Pinmembercykophysh3925-Feb-07 3:53 
GeneralA good start for a captiva, but as coded can easily be broken Pinmemberrweil12-Dec-06 12:33 
GeneralRe: A good start for a captiva, but as coded can easily be broken Pinmemberazamsharp12-Dec-06 12:37 
GeneralRe: A good start for a captiva, but as coded can easily be broken Pinmembercykophysh3925-Feb-07 3:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.141022.2 | Last Updated 8 Dec 2006
Article Copyright 2006 by azamsharp
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid