我需要3个数据库连接字符串的3个唯一密码,因此我将以下内容作为winforms应用程序的一部分进行了攻击:
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);
}
}
但是,如果我输入8作为字符数,我会得到类似“igTJEQptvQ ==”的内容,这是12个字符,每个字符串似乎以“==”结尾
有人可以解释为什么字符数大于字节数组的大小,以及字符串似乎经常以==结尾的原因。
原谅这个问题的业余爱好者,谢谢你的解释。
答案 0 :(得分:2)
1)字节数组基于0访问,但大小为1,即你正在制作7字节数组而不是8字节数字
2) Base64String专为(在某些事情中)在电子邮件中的字符串中发送二进制数据而设计。它仅使用“安全”字符子集来表示数据(64个字符= 2 ^ 6)。要表示7个字节(2 ^(7 * 8)= 2 ^ 56位),它需要56/6 = 10个字符,它实际上通过尾随=== s填充到4个字符的倍数(即12,16等)
请参阅http://en.wikipedia.org/wiki/Base64填充部分,例如
答案 1 :(得分:0)
如果您正在使用8个(或任何字符)的文本密码,那么使用类似这种方法的方法我写了一次用于生成相当随机的用户密码:
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);
}