当我们网站上的用户丢失密码并转到丢失密码页面时,我们需要给他一个新的临时密码。我并不介意这有多随机,或者它是否符合所有“所需的”强密码规则,我想做的只是给他们一个他们以后可以更改的密码。

该应用程序是用c#编写的Web应用程序。所以我想刻薄一点,走一条简单的路线,用Guid的一部分。即。

Guid.NewGuid().ToString("d").Substring(1,8)

Suggesstions吗?想法吗?


当前回答

public static string GeneratePassword(int passLength) {
        var chars = "abcdefghijklmnopqrstuvwxyz@#$&ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        var random = new Random();
        var result = new string(
            Enumerable.Repeat(chars, passLength)
                      .Select(s => s[random.Next(s.Length)])
                      .ToArray());
        return result;
    }

其他回答

我喜欢生成密码,就像生成软件密钥一样。您应该从遵循良好实践的字符数组中进行选择。采用@Radu094回答的内容并修改它以遵循良好的实践。不要把每个字母都放在字符数组中。有些信在电话里更难读懂。

您还应该考虑对生成的密码使用校验和,以确保它是由您生成的。实现这一点的一个好方法是使用LUHN算法。

我知道这是一个旧线程,但我有什么可能是一个相当简单的解决方案供某人使用。易于实现、易于理解、易于验证。

考虑以下要求:

我需要一个随机密码生成,其中至少有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循环到所需的小写字符#,在每次迭代中,从小写列表中抓取一个随机项,并将其注入字符串中的随机位置。

然后对大写字母和数字重复循环。

这将返回长度=小写字母+大写字母+数字的字符串,其中您想要的计数的小写字母、大写字母和数字字符已按随机顺序放置。

这个包允许你生成一个随机密码,同时流利地指出它应该包含哪些字符(如果需要):

https://github.com/prjseal/PasswordGenerator/

例子:

var pwd = new Password().IncludeLowercase().IncludeUppercase().IncludeSpecial();
var password = pwd.Next();

我的代码的主要目标是:

弦的分布几乎是均匀的(不关心微小的偏差,只要它们很小) 它为每个参数集输出超过几十亿个字符串。如果您的PRNG只生成20亿(31位熵)不同的值,那么生成8个字符的字符串(约47位熵)是没有意义的。 它是安全的,因为我希望人们使用它作为密码或其他安全令牌。

第一个属性是通过对字母大小取一个64位值的模来实现的。对于小字母(例如问题中的62个字符),这导致了可以忽略不计的偏差。第二个和第三个属性是通过使用RNGCryptoServiceProvider而不是System.Random来实现的。

using System;
using System.Security.Cryptography;

public static string GetRandomAlphanumericString(int length)
{
    const string alphanumericCharacters =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
        "abcdefghijklmnopqrstuvwxyz" +
        "0123456789";
    return GetRandomString(length, alphanumericCharacters);
}

public static string GetRandomString(int length, IEnumerable<char> characterSet)
{
    if (length < 0)
        throw new ArgumentException("length must not be negative", "length");
    if (length > int.MaxValue / 8) // 250 million chars ought to be enough for anybody
        throw new ArgumentException("length is too big", "length");
    if (characterSet == null)
        throw new ArgumentNullException("characterSet");
    var characterArray = characterSet.Distinct().ToArray();
    if (characterArray.Length == 0)
        throw new ArgumentException("characterSet must not be empty", "characterSet");

    var bytes = new byte[length * 8];
    new RNGCryptoServiceProvider().GetBytes(bytes);
    var result = new char[length];
    for (int i = 0; i < length; i++)
    {
        ulong value = BitConverter.ToUInt64(bytes, i * 8);
        result[i] = characterArray[value % (uint)characterArray.Length];
    }
    return new string(result);
}

(这是我对如何在c#中生成随机8个字符,字母数字字符串的回答的副本?)

public string GenerateToken(int length)
{
    using (RNGCryptoServiceProvider cryptRNG = new RNGCryptoServiceProvider())
    {
        byte[] tokenBuffer = new byte[length];
        cryptRNG.GetBytes(tokenBuffer);
        return Convert.ToBase64String(tokenBuffer);
    }
}

(你也可以让这个方法所在的类实现IDisposable,持有对RNGCryptoServiceProvider的引用,并正确地处理它,以避免重复实例化它。)

It's been noted that as this returns a base-64 string, the output length is always a multiple of 4, with the extra space using = as a padding character. The length parameter specifies the length of the byte buffer, not the output string (and is therefore perhaps not the best name for that parameter, now I think about it). This controls how many bytes of entropy the password will have. However, because base-64 uses a 4-character block to encode each 3 bytes of input, if you ask for a length that's not a multiple of 3, there will be some extra "space", and it'll use = to fill the extra.

If you don't like using base-64 strings for any reason, you can replace the Convert.ToBase64String() call with either a conversion to regular string, or with any of the Encoding methods; eg. Encoding.UTF8.GetString(tokenBuffer) - just make sure you pick a character set that can represent the full range of values coming out of the RNG, and that produces characters that are compatible with wherever you're sending or storing this. Using Unicode, for example, tends to give a lot of Chinese characters. Using base-64 guarantees a widely-compatible set of characters, and the characteristics of such a string shouldn't make it any less secure as long as you use a decent hashing algorithm.