Secure Password Generator [Re-vamped] [Updated 12/29/2016] - Malum™ - Dec 20, 2016
I've had this project laying around awhile I made for a friend to further understand something (I don't recall anymore). Feel free to use this for account creators, login systems, etc. Ask any questions! I'm sorry I do not really comment my code.
GUI
![[Image: adef7d6d87.png]](https://puu.sh/sVrgG/adef7d6d87.png)
Password Generator Class
Code class PasswordGenerator
{
private SecureRandom RND = new SecureRandom();
public bool Special { get; set; }
public bool Numbers { get; set; }
public bool UpperCase { get; set; }
public bool LowerCase { get; set; }
private const string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
private const string SpecialChars = "~`!@#$%^&*()-_+";
public PasswordGenerator() { }
public string Generate(int Length)
{
if (!Special && !Numbers && !UpperCase && !LowerCase)
throw new ArgumentException("At least one option must be set.");
StringBuilder sBuilder = new StringBuilder(Length);
for (int i = 0; i < Length; i++)
sBuilder.Append(RandomChoice());
return sBuilder.ToString();
}
private string RandomChoice()
{
string response = "";
switch (RND.Next(0, 4))
{
case 0:
if (!UpperCase)
return "";
response = Alphabet[RND.Next(Alphabet.Length)].ToString();
break;
case 1:
if (!LowerCase)
return "";
response = Alphabet[RND.Next(Alphabet.Length)].ToString().ToLower();
break;
case 2:
if (!Numbers)
return "";
response = RND.Next(0, 9).ToString();
break;
case 3:
if (!Special)
return "";
response = SpecialChars[RND.Next(SpecialChars.Length)].ToString();
break;
default: break;
}
return response;
}
}
Secure Random Class
Code class SecureRandom : RandomNumberGenerator
{
private RandomNumberGenerator RNG = new RNGCryptoServiceProvider();
private byte[] data = new byte[sizeof(uint)];
public SecureRandom() { }
public int Next()
{
RNG.GetBytes(data);
return BitConverter.ToInt32(data, 0) & (int.MaxValue - 1);
}
public int Next(int maxValue)
{
return Next(0, maxValue);
}
public int Next(int minValue, int maxValue)
{
if (minValue > maxValue)
throw new ArgumentOutOfRangeException();
return (int)((minValue + ((double)maxValue - minValue) * NextDouble()));
}
public double NextDouble()
{
RNG.GetBytes(data);
var randUint = BitConverter.ToUInt32(data, 0);
return randUint / (uint.MaxValue + 1.0);
}
public double NextDouble(double min, double max)
{
if (min > max)
throw new ArgumentOutOfRangeException();
return NextDouble() * (max - min) + min;
}
public override void GetBytes(byte[] data)
{
RNG.GetBytes(data);
}
public override void GetNonZeroBytes(byte[] data)
{
RNG.GetNonZeroBytes(data);
}
Usage
Code PasswordGenerator pGenerator = new PasswordGenerator() { UpperCase = true, LowerCase = true, Special = True };
string password = pGenerator.Generate(12) //12 being the length
Project Source Download
Changed (12/29/2016)- Changed While Loop to For Loop.
- Used StringBuilder.
- Removed Math.Floor.
- Removed issue with byte buffer being created every time.
- Updated download link to new project source.
* - Chickendipper - Dec 20, 2016
Your code is very nice, however I do have one gripe with it.
You use a while loop to select characters randomly based off of your RNG. This is a lot more hassle and uses more resources, and is a messier solution.
Instead, what you could do is:
Code StringBuilder charPoolBuilder = new StringBuilder();
if (UpperCase) charPoolBuilder.Append("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
// ... etc
StringBuilder myPassword = new StringBuilder();
for (int i = 0; i < passwordLength; i++) myPassword.Append(charPoolBuilder[RND.Next(charPoolBuilder.Length)]);
return myPassword.ToString();
This way, instead of doing twice the selection & having a messy case selection, you have a "one size fits all" solution. Now, if you wanted to add European characters (eg éíúóá), you could do so by doing
Code if (European) charPoolBuilder.Append("éíúóá");
rather than having an extra case statement. Otherwise, your code is great and a great learning point to others about CSPRNGs.
* - Zilog80 - Dec 20, 2016
Pull Request for PasswordGenerator class
PHP Code
<?php while (password.Length < 12)
Should be:
PHP Code
<?php while (password.Length < Length)
If you change this you can do this:
PHP Code
<?php string password = pGenerator.Generate(12) //12 being the length string password2 = pGenerator.Generate(15) //15 being the length string password3 = pGenerator.Generate(25) //25 being the length
* - Mr Whiskey - Dec 20, 2016
I'm confused, you have a box to choose the length but it's hard-coded to 12?
* - Kaspah - Dec 20, 2016
I mean, nice contribution but what's the point when I can use a web-based generator?
* - Chickendipper - Dec 20, 2016
(Dec 20, 2016 01:12 PM)Kaspah Wrote: I mean, nice contribution but what's the point when I can use a web-based generator?
Are you retarded? He's making a contribution so that others can learn from it.
* - Mr Whiskey - Dec 20, 2016
(Dec 20, 2016 01:12 PM)Kaspah Wrote: I mean, nice contribution but what's the point when I can use a web-based generator?
I think he gave a pretty good example in the OP. "Feel free to use this for account creators"
* - Malum™ - Dec 21, 2016
(Dec 20, 2016 01:06 PM)Zilog80 Wrote: Pull Request for PasswordGenerator class
PHP Code
<?php while (password.Length < 12)
Should be:
PHP Code
<?php while (password.Length < Length)
If you change this you can do this:
PHP Code
<?php string password = pGenerator.Generate(12) //12 being the length string password2 = pGenerator.Generate(15) //15 being the length string password3 = pGenerator.Generate(25) //25 being the length
Oh shit! My bad. I forgot to remove that. I was testing and forgot to remove that part. I'll fix it now.
* - passwords - Dec 22, 2016
Very nice, this "Friend" of yours must have been something really special.
Anyways, Good contribution to the community!
* - Malum™ - Dec 23, 2016
(Dec 22, 2016 12:40 PM)DOT1 Wrote: Very nice, this "Friend" of yours must have been something really special.
Anyways, Good contribution to the community!
Why the hostility? It was someone on Skype wanting to learn about ListView/ListBox and Random String generation. So I threw this project together and added a little more to it to post on here.
EDIT: God damn it. DOT1 was the friend I made it for. Lmfao. You dick. Haha.
* - BahNahNah - Dec 23, 2016
Just some things to think about:
- Empty constructors can be omitted.
![[Image: S2RtdrA.png]](https://i.imgur.com/S2RtdrA.png)
- Decimal/float/double to int cast will drop the decimals, so no need for the extra Math.Floor.
![[Image: W1Tm943.png]](https://i.imgur.com/W1Tm943.png)
![[Image: rDNFH0x.png]](https://i.imgur.com/rDNFH0x.png)
* - Malum™ - Dec 23, 2016
- Empty constructors can be omitted. - This seems extraordinarily picky..more like one of your pet-peeves.
- Yea, that was my bad. I was having issues (brain fart) when using StringBuilder and resorted to concatenations. Never bothered to revert back.
- Decimal/float/double to int cast will drop the decimals, so no need for the extra Math.Floor. - Didn't know that. Thank you!
- - I appreciate that information. I didn't take that into consideration.
![[Image: W1Tm943.png]](https://i.imgur.com/W1Tm943.png)
![[Image: rDNFH0x.png]](https://i.imgur.com/rDNFH0x.png)
I would love and greatly appreciate whatever you use to benchmark. It would come in handy for future projects.
* - sinfulshotx - Jan 14, 2017
I just made one of these myself using very similar methods, great work. All improvements are done with practice and time.
|