I have a project in the works, and I'll need to associate a passcode with an item.
The password should be completely non sequential or easily guessable, yet simple to remember.I thought about doing someth开发者_运维技巧ing like this.
string rand = System.Guid.NewGuid().ToString();
rand.Substring(0,3);
Return the first 4 digits of a GUID.
I was wondering if anyone else had something similar they worked on, and potentially a better solution than this.
Security is important as we don't want people to be able to guess the digits, however this isn't dealing with money or personal data so it doesn't have to be NSA capable :)
Thanks guys!
People remember words better than they remember codes...
So a simple way is to generate a passphrase rather than a gibberish word or code.
The easiest way to do this is to have a list of a few thousand words in a database or dictionary and then randomly select 3 or 4 of them.
The more words you use the harder it will be for hackers to guess - 3 from 3,000 words will pretty unguessable, while 4 from 20,000 words will have 1,600,00,000,000,000,000 combinations.
If you're thinking of a PIN-style code, I'd suggest using all digits (or possibly all letters) rather than the first four characters of a GUID. Many people are familiar with all-digit PINs; I suspect having a letter mixed in there might make it less easy for them to remember. But I have no evidence to back this up!
If a PIN is sufficient, you could just call Random.Next(0, 9) four times and concatenate the results. Be sure to eliminate "not random enough" results like when all four digits are the same! As unknown says, you can get statistically more random results from the crypto classes, but over four digits that's unlikely to matter.
If you want something that will provide your users with something that is relatively easy to remember, you can always use my PronouncablePasswords
class.
I originally wrote this as an experiment in generating random passwords that were pronounceable by the end-user, rather than being complete gobbledygook. Of course, this reduces the security of the password, but for your purposes it sounds like this would be sufficient.
The function simply alternates between a vowel and a consonant (with some rudimentary exception rules), with "weighting" on the letters chosen based upon their occurrence in the English language. Note that this is by no means perfect, but it does do "what is says on the tin"!
Code:
using System;
using System.Collections.Generic;
using System.Text;
namespace PronouncablePasswords
{
class PasswordGenerator
{
//string vowels = "aeiou";
//string consonants = "bcdfghjklmnprstvwxyz";
/*
The reason for the duplicate letters is to add "weighting" to certain letters to allow them more chance
of being randomly selected. This is due to the fact that certain letters in the English language are more
frequently used than others.
The breakdown of usage is as follows (from most frequent to least frequent):
1. E (7)
2. T (6)
3. A, O, N, R, I, S (5)
4. H (4)
5. D, L, F, C, M, U (3)
6. G, Y, P, W, B (2)
7. V, K, X, J, Q, Z (1)
*/
string vowels = "aaaaaeeeeeeeiiiiiooooouuu";
string consonants = "bbcccdddfffgghhhhjklllmmmnnnnnpprrrrrsssssttttttvwwxyyz";
string[] vowelafter = {"th", "ch", "sh", "qu"};
string[] consonantafter = { "oo", "ee" };
Random rnd = new Random();
public string GeneratePassword(int length)
{
string pass = "";
bool isvowel = false;
for (int i = 0; i < length; i++)
{
if (isvowel)
{
if (rnd.Next(0, 5) == 0 && i<(length-1))
{
pass += consonantafter[rnd.Next(0, consonantafter.Length)];
}
else
{
pass += vowels.Substring(rnd.Next(0, vowels.Length), 1);
}
}
else
{
if (rnd.Next(0, 5) == 0 && i<(length-1))
{
pass += vowelafter[rnd.Next(0, vowelafter.Length)];
}
else
{
pass += consonants.Substring(rnd.Next(0, consonants.Length), 1);
}
}
isvowel = !isvowel;
}
return pass;
}
}
}
ASP .Net Membership provider has a method that generate passwords that could be helpful. http://msdn.microsoft.com/en-us/library/system.web.security.membership.generatepassword.aspx also you can look at the source code of the providers to see what they do internally http://weblogs.asp.net/scottgu/archive/2006/04/13/442772.aspx
What characteristics must your password have? If your primary criterion is memorability, then I would suggest something like this:
Go find a large corpus of English text and get all unique words of five or less letters out of it. Now, for any particular new password, randomly select three or four of these words. Then, at the end, add a random two-digit number.
How many passwords? Well, one hundred for the two-digit number, times (number of distinct words) to the power of (number of random words in a password). So if you take the base-two log of that, you'll get the entropy that you could have in these passwords -- if your random number generator is good enough.
In practice, if you lock accounts after a few bad password tries, then you'll foil attackers effectively as long as there are at least a few thousand possible passwords.
I would suggest using the RandomNumberGenerator class, it will give you better results than GUID generation.
http://msdn.microsoft.com/en-us/library/system.security.cryptography.randomnumbergenerator(VS.71).aspx
I think it's very difficult to achieve it.
精彩评论