Friday, September 28, 2012

Password Generator

Today I want to present a "Password Generator" written in C#. Maybe the name is a bit wrong, it is about creating all possible passwords of a given length, so that they can for example be used for brute-force attacks.

The generator is capsuled in a class, when creating an instance of it a new thread is started, which generates the passwords and writes them to a queue. This can then be checked from the outside, so that the creating and asking of possible passwords can be done in parallel.
The creation of passwords happens in the function FillQueue(). Here an iteration counts from the given minimal length to the maximal length of a password and by recursion for every of these characters the function SetLetter() is called.
It goes over all possible characters (in the program can be set, that the characters A-Z, a-z and 0-9 are used), sets the current position to the current character and calls the function with the next position. If the last position is reached, the current password is written to the queue.
With the public function Dequeue() the lowest element of the queue is taken out and returned, that way the created passwords can be collected.

The code:
public class PasswordGenerator
    {
        Queue<string> Results; // queue with created passwords

        bool UpperAZ; // true if capital letters should be used
        bool LowerAZ; // true if lower case letters should be used
        bool Numbers; // true if numbers should be used

        int Min; // min. length of the password
        int Max; // max. length of the password

        const int MaxQueueSize = 30000000; // maximal number of passwords, which can be in the queue simultaneously (protection of memory overflow)

        public PasswordGenerator(bool upperAZ, bool lowerAZ, bool numbers, int min, int max)
        {
            UpperAZ = upperAZ;
            LowerAZ = lowerAZ;
            Numbers = numbers;

            Min = min;
            Max = max;
            Results = new Queue<string>();

            // create new thread for password generation
            Thread Creator = new Thread(new ThreadStart(FillQueue));
            Creator.Start();
        }

        private void FillQueue()
        {
            // fill queue
            for (int i = Min; i <= Max; i++)
            {
                SetLetter(i, 0, "");
            }
        }

        private void SetLetter(int length, int pos, string temp)
        {
            // fill current position with all possible characters
            if (UpperAZ)
            {
                for (int i = 65; i <= 90; i++)
                {
                    NextStep(length, pos, temp + (char)i);
                }
            }
            if (LowerAZ)
            {
                for (int i = 97; i <= 122; i++)
                {
                    NextStep(length, pos, temp + (char)i);
                }
            }
            if (Numbers)
            {
                for (int i = 0; i <= 9; i++)
                {
                    NextStep(length, pos, temp + i.ToString());
                }
            }
        }

        private void NextStep(int length, int pos, string temp)
        {
           // function to finalize a step

           // if the queue is "full", the step is paused
           while (Results.Count > MaxQueueSize)
               Thread.Sleep(500);

            // if not yet the last position is reached, call function with next position
            if (pos < length - 1)
                SetLetter(length, pos + 1, temp);
            else
                // otherwise add complete password to the queue
                Results.Enqueue(temp);
        }

        public string Dequeue()
        {
            // returns the lowest element of the queue
            if (Results.Count > 0)
                return Results.Dequeue();
            else
                return "";
        }
    }

The initialization of the generator then can be done e.g. via
PasswordGenerator Generator = new PasswordGenerator(true, true, true, 1, 4);
The asking for passwords via
Generator.Dequeue();

No comments:

Post a Comment