当我们网站上的用户丢失密码并转到丢失密码页面时,我们需要给他一个新的临时密码。我并不介意这有多随机,或者它是否符合所有“所需的”强密码规则,我想做的只是给他们一个他们以后可以更改的密码。
该应用程序是用c#编写的Web应用程序。所以我想刻薄一点,走一条简单的路线,用Guid的一部分。即。
Guid.NewGuid().ToString("d").Substring(1,8)
Suggesstions吗?想法吗?
当我们网站上的用户丢失密码并转到丢失密码页面时,我们需要给他一个新的临时密码。我并不介意这有多随机,或者它是否符合所有“所需的”强密码规则,我想做的只是给他们一个他们以后可以更改的密码。
该应用程序是用c#编写的Web应用程序。所以我想刻薄一点,走一条简单的路线,用Guid的一部分。即。
Guid.NewGuid().ToString("d").Substring(1,8)
Suggesstions吗?想法吗?
当前回答
在接受的答案中添加了一些补充代码。它改进了仅使用随机的答案,并允许一些密码选项。我也喜欢KeePass回答中的一些选项,但不想在我的解决方案中包含可执行文件。
private string RandomPassword(int length, bool includeCharacters, bool includeNumbers, bool includeUppercase, bool includeNonAlphaNumericCharacters, bool includeLookAlikes)
{
if (length < 8 || length > 128) throw new ArgumentOutOfRangeException("length");
if (!includeCharacters && !includeNumbers && !includeNonAlphaNumericCharacters) throw new ArgumentException("RandomPassword-Key arguments all false, no values would be returned");
string pw = "";
do
{
pw += System.Web.Security.Membership.GeneratePassword(128, 25);
pw = RemoveCharacters(pw, includeCharacters, includeNumbers, includeUppercase, includeNonAlphaNumericCharacters, includeLookAlikes);
} while (pw.Length < length);
return pw.Substring(0, length);
}
private string RemoveCharacters(string passwordString, bool includeCharacters, bool includeNumbers, bool includeUppercase, bool includeNonAlphaNumericCharacters, bool includeLookAlikes)
{
if (!includeCharacters)
{
var remove = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z" };
foreach (string r in remove)
{
passwordString = passwordString.Replace(r, string.Empty);
passwordString = passwordString.Replace(r.ToUpper(), string.Empty);
}
}
if (!includeNumbers)
{
var remove = new string[] { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
foreach (string r in remove)
passwordString = passwordString.Replace(r, string.Empty);
}
if (!includeUppercase)
passwordString = passwordString.ToLower();
if (!includeNonAlphaNumericCharacters)
{
var remove = new string[] { "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "-", "_", "+", "=", "{", "}", "[", "]", "|", "\\", ":", ";", "<", ">", "/", "?", "." };
foreach (string r in remove)
passwordString = passwordString.Replace(r, string.Empty);
}
if (!includeLookAlikes)
{
var remove = new string[] { "(", ")", "0", "O", "o", "1", "i", "I", "l", "|", "!", ":", ";" };
foreach (string r in remove)
passwordString = passwordString.Replace(r, string.Empty);
}
return passwordString;
}
这是我搜索生成随机密码时的第一个链接,以下内容超出了当前问题的范围,但可能很重要,需要考虑。
假设System.Web.Security.Membership.GeneratePassword是加密安全的,至少有20%的字符是非字母数字。 不确定在这种情况下删除字符和追加字符串是否被认为是良好的实践,并提供足够的熵。 可能需要考虑以某种方式使用SecureString实现内存中的安全密码存储。
其他回答
我知道这是一个旧线程,但我有什么可能是一个相当简单的解决方案供某人使用。易于实现、易于理解、易于验证。
考虑以下要求:
我需要一个随机密码生成,其中至少有2个小写字母,2个大写字母和2个数字。密码长度至少为8个字符。
下面的正则表达式可以验证这种情况:
^(?=\b\w*[a-z].*[a-z]\w*\b)(?=\b\w*[A-Z].*[A-Z]\w*\b)(?=\b\w*[0-9].*[0-9]\w*\b)[a-zA-Z0-9]{8,}$
这超出了这个问题的范围——但是正则表达式是基于前向/后向和前后向的。
下面的代码将创建一个匹配这个要求的随机字符集:
public static string GeneratePassword(int lowercase, int uppercase, int numerics) {
string lowers = "abcdefghijklmnopqrstuvwxyz";
string uppers = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string number = "0123456789";
Random random = new Random();
string generated = "!";
for (int i = 1; i <= lowercase; i++)
generated = generated.Insert(
random.Next(generated.Length),
lowers[random.Next(lowers.Length - 1)].ToString()
);
for (int i = 1; i <= uppercase; i++)
generated = generated.Insert(
random.Next(generated.Length),
uppers[random.Next(uppers.Length - 1)].ToString()
);
for (int i = 1; i <= numerics; i++)
generated = generated.Insert(
random.Next(generated.Length),
number[random.Next(number.Length - 1)].ToString()
);
return generated.Replace("!", string.Empty);
}
要满足上述要求,只需调用以下命令:
String randomPassword = GeneratePassword(3, 3, 3);
代码以一个无效字符(“!”)开始——这样字符串就有一个长度,可以向其中注入新字符。
然后,它从1循环到所需的小写字符#,在每次迭代中,从小写列表中抓取一个随机项,并将其注入字符串中的随机位置。
然后对大写字母和数字重复循环。
这将返回长度=小写字母+大写字母+数字的字符串,其中您想要的计数的小写字母、大写字母和数字字符已按随机顺序放置。
如果你想使用System.Web.Security.Membership.GeneratePassword使用的加密安全随机数生成,但又想将字符集限制为字母数字字符,你可以使用regex过滤结果:
static string GeneratePassword(int characterCount)
{
string password = String.Empty;
while(password.Length < characterCount)
password += Regex.Replace(System.Web.Security.Membership.GeneratePassword(128, 0), "[^a-zA-Z0-9]", string.Empty);
return password.Substring(0, characterCount);
}
使用Random和linq-to-objects来要求每个组都有一个很简单的方法。
随机分组 从第一组中选择随机金额 从以下组中选择剩余的随机金额
Random rand = new Random();
int min = 8;
int max = 16;
int totalLen = rand.Next(min, max);
int remainingGroups = 4;
string[] allowedLowerChars = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z".Split(',');
string [] allowedUpperChars = "A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z".Split(',');
string [] allowedNumbers = "1,2,3,4,5,6,7,8,9,0".Split(',');
string [] allowedSpecialChars = "!,@,#,$,%,&,?".Split(',');
var password = allowedLowerChars.OrderBy(c => rand.Next()).Take(rand.Next(1, totalLen-remainingGroups--)).ToList();
password.AddRange(allowedUpperChars.OrderBy(c => rand.Next()).Take(rand.Next(1, totalLen-password.Count-remainingGroups--)).ToList());
password.AddRange(allowedNumbers.OrderBy(c => rand.Next()).Take(rand.Next(1, totalLen-password.Count-remainingGroups--)).ToList());
password.AddRange(allowedSpecialChars.OrderBy(c => rand.Next()).Take(totalLen-password.Count).ToList());
password = password.OrderBy(c => rand.Next()).ToList(); // randomize groups
由于Random是不安全的,RNGCryptoServiceProvider是过时的,我最终这样做:
// possible characters that password can have
private const string passChars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"abcdefghijklmnopqrstuvwxyz" +
"0123456789" +
"!@#$%.-_"
;
public static string GetRandomPassword(int length)
{
char[] p = new char[length];
for (int i = 0; i < length; i++)
p[i] = passChars[RandomNumberGenerator.GetInt32(0, passChars.Length)];
return new string(p);
}
对于这种类型的密码,我倾向于使用可能生成更容易“使用”的密码的系统。短的,通常由发音片段和一些数字组成,并且没有字符间的歧义(这是0还是O?是1还是I?)类似的
string[] words = { 'bur', 'ler', 'meh', 'ree' };
string word = "";
Random rnd = new Random();
for (i = 0; i < 3; i++)
word += words[rnd.Next(words.length)]
int numbCount = rnd.Next(4);
for (i = 0; i < numbCount; i++)
word += (2 + rnd.Next(7)).ToString();
return word;
(直接在浏览器中输入,因此仅作为参考。同时,要多加单词)。