Archive for July, 2011

Captcha

I needed a captcha for a Java Web Project, I tried SimpleCaptha and ReCaptha….both worked fine. And then out of curiosity I checked wikipedia what a captcha is and this is what I got.

 It is an acronym based on the word “capture” and standing for “Completely Automated PublicTuring test to tell Computers and Humans Apart”

So basically, we want to be able to tell computers (or bots) trying to use our service from humans. So I thought to myself, is it really necessary to use all these mangled, difficult to read, sometimes very funny images? We can just ask the user a simple question we think only a human can know, make this question random enough that guessing(which is what most brute force attacks rely on) will be difficult.

For example, I am yet to see someone who says he/she has successfully guessed a recharge voucher pin. Even if there are maybe one or two. And this pin is just numbers, sometimes as few as 10 digits. Your ATM Pin is most times 4 Digits.

I remember seeing on a website a very simple captcha, they ask you a mathematical question, (+, -, *) and you give an answer. That simple. No mangled image, no mangled audio, nothing fancy.

So I started writing down ideas for what we can really call SimpleCaptcha.

  1. Present five random characters and ask the user what is the n-th character, of course the n-th character is also random
  2. Present the user a simple arithmetic expression, and ask for the answer. The two operands and the operator are random.
  3. Ask Date based questions like today is thursday, two days before today is ?, yesterday was Friday, 9 days from now is, etc
I actually set out to implement the three above, but the project I am working on is also pressing, so I decided to pick the most basic one. No 2. Just as a proof of concept.

Now these captcha ideas MAY or MAY NOT have very very serious security holes. I am not an expert in web security and captcha, I am just a guy who likes simple things.

Below is some part of the Single File Java Class that does No. 2.

    public String getQuestion() {
        Random r = new Random(System.currentTimeMillis());

        int operationRandInt = r.nextInt(3);
        String operationString = operations[operationRandInt];

        int q1Rand = r.nextInt(100) + 10;
        int q2Rand = r.nextInt(100) + 10;

        //we don't want answers to have -negative results
        if (operationString.equals("-")) {
            while (q2Rand >= q1Rand) {
                q2Rand = r.nextInt(100) + 10;
            }
        }

        /*
            if you want to implement for division, be my guest.
            A few thoughts though.
         * 1. It will be easier if there are no reminders in answers. i.e q1/q2 = Whole Number
         * 2. It will be safer if q1 != q2.
         */

        q1 = q1Rand;
        q2 = q2Rand;
        operation = operationString;

        return q1 + " " + operation + " " + q2;
    }
    public boolean solve(int answer) {
        if (operation.equals("+")) {
            return q1 + q2 == answer;
        } else if (operation.equals("-")) {
            return q1 - q2 == answer;
        } else if (operation.equals("*")) {
            return q1 * q2 == answer;
        }
        return false;
    }

The full source is here Captcha.java

Advertisements

Comments (12)