Reputation: 4876
I needed 3 unique passwords for 3 database connection strings, so I hacked together the following as part of a winforms application:
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
void CharCount_TextChanged(object sender, System.EventArgs e)
{
int noChars;
if (int.TryParse(CharCount.Text, out noChars))
{
byte[] random = new Byte[noChars-1];
rng.GetBytes(random);
OutputTxt.Text = Convert.ToBase64String(random);
}
}
however, if I enter 8 for the number of characters, I get something like "igTJEQptvQ==", which is 12 characters, and every string seems to end in "=="
can someone please explain both why the number of characters is greater than the size of the byte array, and also why the strings seem to regularly end in ==.
Forgive how amateur this question is, and thank you for your explanations.
Upvotes: 0
Views: 91
Reputation: 322
If you're after a text password of exactly 8 (or whatever characters) how about using something like this method I wrote once for generating fairly random user passwords:
string GeneratePassword(int numUpper, int numLower, int numNum, int numSym)
{
char[] genPassword = new char[numUpper+numLower+numNum+numSym]; //array to store our password
int gPidx=0; // holds the index of where we are in the genPassword char array
Random rng = new Random(); // You could use your CryptoRNG here if you want
char[] upperChars = {'A','B','C','D','E','F','G',
'H','I','J','K','L','M','N','P','Q',
'R','S','T','U','V','W','X','Y','Z'}; // No 'O' as it is easily confused with '0' (but does slightly reduce the keyspace)
char[] lowerChars = {'a','b','c','d','e','f','g',
'h','i','j','k','m','n','o','p','q',
'r','s','t','y','v','w','x','y','z'}; // No 'l' as it is easily confused with '1' (but does slightly reduce the keyspace)
char[] numberChars = {'2','3','4','5','6','7','8','9'}; // No '1' or '0' as they are easily confused
char[] symbolChars = {'!','£','$','%','^','&',
'*','+','=','-','@','#','?'}; // Just the easy ones for a luser to find
//get uppers & put into the password array
for(int i=0; i<numUpper; i++) {
genPassword[gPidx] = upperChars[rng.Next(0,upperChars.Length)];
gPidx++;
}
//get lowers & put into the password array
for(int i=0; i<numLower; i++) {
genPassword[gPidx] = lowerChars[rng.Next(0,lowerChars.Length)];
gPidx++;
}
//get numbers & put into the password array
for(int i=0; i<numNum; i++) {
genPassword[gPidx] = numberChars[rng.Next(0,numberChars.Length)];
gPidx++;
}
//get symbols & put into the password array
for(int i=0; i<numSym; i++) {
genPassword[gPidx] = symbolChars[rng.Next(0,symbolChars.Length)];
gPidx++;
}
// Shuffle the letters (leave the numbers and symbols)
// I like passwords to start with a letter as some
// sites don't like non-alpha first chars
int endOfAlpha = genPassword.Length-numNum-numSym;
for(int i=0; i<endOfAlpha;i++) {
// For each character in our password
// pick a number between 0 and the end of the password
// swap the characters
char tempChar;
int random = rng.Next(0,endOfAlpha); //don't alter the first letter
tempChar = genPassword[i]; //store the current Value
genPassword[i] = genPassword[random];
genPassword[random]=tempChar;
}
// Re-Shuffle leaving the first character intact
for(int i=1; i<genPassword.Length;i++) {
// For each character in our password
// pick a number between 0 and the end of the password
// swap the characters
char tempChar;
int random = rng.Next(1,genPassword.Length); //don't alter the first letter
tempChar = genPassword[i]; //store the current Value
genPassword[i] = genPassword[random];
genPassword[random]=tempChar;
}
return new string(genPassword);
}
Upvotes: 0
Reputation: 3724
1) byte arrays are accessed 0 based but sized 1 based, ie you are making a 7 byte array not an 8 byte one
2) Base64String was designed for (things like) sending binary data in strings in emails. It only uses a 'safe' subset of characters to represent the data (64 chars = 2 ^ 6). To represent 7 bytes (2^ (7*8) = 2^56 bits) it needs 56/6 = 10 chars, its actually padded out to a multiple of 4 chars (ie 12, 16 etc) by trailing ===s
see http://en.wikipedia.org/wiki/Base64 padding section for example
Upvotes: 2