Click here to Skip to main content
13,901,142 members
Click here to Skip to main content
Add your own
alternative version


56 bookmarked
Posted 1 Nov 2005
Licenced CPOL

Cryptographically Strong Random Password Generation

, 1 Nov 2005
Rate this:
Please Sign up or sign in to vote.
An article on creating a simple, but robust cryptographically strong password generator.

Sample Image - CryptoPasswordGenerator.gif


This article is another simple but robust password generator based on similar concepts presented in Kevin Stewart's C# Password Generator.


My purpose for creating this example stemmed from evaluating various third party password generation tools and wanting to know what it would really take to implement my own password generator. In my research I came across Kevin Stewart's article and noticed his use of the RNGCryptoServiceProvider and became curious why this class from the Cryptography namespace was used instead of the Random class.

Further research on the RNGCryptoServiceProvider class led me to find it makes use of Windows modules that have completed FIPS-140 (Federal Information Processing Standard) US government standard which provide a benchmark for implementing cryptographic software. See the Microsoft FIPS - 140 Evaluation article for more information.


The types of characters included in the passwords needed to be configurable. The length of the password needed to have a variant length that was chosen randomly. Finally I wanted to randomly determine which character type to append (number, uppercase, lowercase or symbol).


Below I've outlined the purpose for each of the methods included in the process of creating the passwords.

RandomNumber.Next(int max)

This method provides a wrapper around the RNGCryptoServiceProvider class allowing for easy creation of a random number. See below...

public static int Next(int max)
    if(max <= 0)
        throw new ArgumentOutOfRangeException("max");
    int value = BitConverter.ToInt32(bytes, 0) % max;
    if(value < 0)
        value = -value;
    return value;

The _Random field being used by this method is a static instance of the RNGCryptoServiceProvider class.

Character Types

The char arrays below define the character types that are available for use during password generation.

private static readonly char[] _Letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
private static readonly char[] _Numbers = "1234567890".ToCharArray();
private static readonly char[] _Symbols = "!@#$%^&*.?".ToCharArray();


The Create method does four different functions. It initializes the available character types, determines the length of the password to create, creates and finally returns the generated password.

public string Create()
    _CharacterTypes = getCharacterTypes();
    StringBuilder password = new StringBuilder(_MaximumLength);

    //Get a random length for the password.
    int currentPasswordLength = RandomNumber.Next(_MaximumLength);
    //Only allow for passwords greater than or equal to the minimum length.
    if(currentPasswordLength < _MinimumLength)
        currentPasswordLength = _MinimumLength;
    //Generate the password
    for(int i = 0; i < currentPasswordLength; i++)
    return password.ToString();


I used an enum to to indicate which character types were available to create the passwords. In this method I iterate through the character types and determine if a particular character type is available for use based on a value set to a corresponding property that indicates whether or not to include a given character type.

private string[] getCharacterTypes()
    ArrayList characterTypes = new ArrayList();
    foreach(string characterType in Enum.GetNames(typeof(CharacterType)))
        CharacterType currentType = 
          characterType, false);
        bool addType = false;
            case CharacterType.Lowercase:
                addType = IncludeLower;
            case CharacterType.Number:
                addType = IncludeNumber;
            case CharacterType.Special:
                addType = IncludeSpecial;
            case CharacterType.Uppercase:
                addType = IncludeUpper;
    return (string[])characterTypes.ToArray(typeof(string));


This method randomly determines which type of character to get from the character types, then randomly determines which character from that subset and returns the value.

private string getCharacter()
    string characterType = 
    CharacterType typeToGet = 
      (CharacterType)Enum.Parse(typeof(CharacterType), characterType, false);
        case CharacterType.Lowercase:
            return _Letters[RandomNumber.Next(_Letters.Length)].ToString().ToLower();
        case CharacterType.Uppercase:
            return _Letters[RandomNumber.Next(_Letters.Length)].ToString().ToUpper();
        case CharacterType.Number:
            return _Numbers[RandomNumber.Next(_Numbers.Length)].ToString();
        case CharacterType.Special:
            return _Symbols[RandomNumber.Next(_Symbols.Length)].ToString();
    return null;


The example is easy to use and very configurable.

Accept the defaults

If you'd just like to accept the default pre-initialized lengths and to include all of the character types, it's as easy as the following two lines of code:

Password password = new Password();

Configure the types of characters to include

There are properties in the Password class allowing you to indicate whether or not you'd like to IncludeUpper (uppercase), IncludeLower (lowercase), IncludeSymbols (!@#$) and IncludeNumbers (12345*). These properties can be set after a password object has already been created or they can be set during the creation of the object via parameters in the constructor.

Password password = new Password(false, false, true, false);

Create fixed length passwords

One recent suggestion by Gabe Wishnie was to make it so you could explicitly set the password length without having the length chosen at random. A quick test showed this functionality was already built in if used in the following manner.

Password password = new Password();
password.MinimumLength = 8;
password.MaximumLength = 8;


The value in this project can be seen as it could be applied to various concepts. The random number method supplied in this article or Kevin Stewart's could also be used to randomly select words from a string array read from a text file. Combine this with a Captcha control and you'll have a decent validation control. Hope all of you find my implementation of use!


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Wil Peck
Software Developer (Senior)
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

GeneralMy vote of 3 Pin
ImageProcessingExpert26-Jul-16 23:02
memberImageProcessingExpert26-Jul-16 23:02 
BugIf no character type is included ... Pin
ImageProcessingExpert26-Jul-16 21:50
memberImageProcessingExpert26-Jul-16 21:50 
SuggestionHow to enforce that each required character type will be present Pin
ImageProcessingExpert26-Jul-16 21:44
memberImageProcessingExpert26-Jul-16 21:44 
SuggestionReturn value of GetCharacterTypes() Pin
ImageProcessingExpert26-Jul-16 21:38
memberImageProcessingExpert26-Jul-16 21:38 
Questionlicense/usage terms Pin
cjfrancione11-Apr-14 10:44
membercjfrancione11-Apr-14 10:44 
GeneralRandomNumber.Next() method is slightly biased toward the low range Pin
Jordan Rieger6-Jan-09 11:42
memberJordan Rieger6-Jan-09 11:42 
GeneralGood article! A small suggestion though... Pin
Freddy Soderlund5-Jan-08 11:06
memberFreddy Soderlund5-Jan-08 11:06 
GeneralRe: Good article! A small suggestion though... Pin
Wil Peck6-Jan-08 10:21
memberWil Peck6-Jan-08 10:21 
GeneralRe: Good article! A small suggestion though... Pin
ImageProcessingExpert26-Jul-16 21:46
memberImageProcessingExpert26-Jul-16 21:46 
Generalstrong password constraints [modified] Pin
Mr Brown Shoes9-Aug-06 15:57
memberMr Brown Shoes9-Aug-06 15:57 
GeneralRe: strong password constraints Pin
Wil Peck14-Aug-06 1:00
memberWil Peck14-Aug-06 1:00 
GeneralFor those who want &quot;exclusions&quot; support Pin
yrleu5-Dec-05 1:02
memberyrleu5-Dec-05 1:02 
GeneralRe: For those who want &amp;quot;exclusions&amp;quot; support Pin
Wil Peck6-Dec-05 3:21
memberWil Peck6-Dec-05 3:21 
Generalgood idea but... Pin
ncage9-Nov-05 3:26
memberncage9-Nov-05 3:26 
GeneralRe: good idea but... Pin
Wil Peck10-Nov-05 11:21
memberWil Peck10-Nov-05 11:21 
QuestionWhy not use PasswordDeriveBytes? Pin
ediazc2-Nov-05 11:06
memberediazc2-Nov-05 11:06 
AnswerRe: Why not use PasswordDeriveBytes? Pin
Wil Peck2-Nov-05 11:50
memberWil Peck2-Nov-05 11:50 
GeneralRe: Why not use PasswordDeriveBytes? Pin
ediazc2-Nov-05 15:00
memberediazc2-Nov-05 15:00 
GeneralRe: Why not use PasswordDeriveBytes? Pin
Wil Peck2-Nov-05 15:18
memberWil Peck2-Nov-05 15:18 
GeneralInteresting Pin
bigals2-Nov-05 9:45
memberbigals2-Nov-05 9:45 
GeneralRe: Interesting Pin
Wil Peck2-Nov-05 14:06
memberWil Peck2-Nov-05 14:06 
GeneralRe: Interesting Pin
bigals2-Nov-05 15:42
memberbigals2-Nov-05 15:42 
GeneralRe: Interesting Pin
Wil Peck2-Nov-05 16:47
memberWil Peck2-Nov-05 16:47 

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

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

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web06 | 2.8.190306.1 | Last Updated 1 Nov 2005
Article Copyright 2005 by Wil Peck
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid