ASP.NET Identity : Generate random password

If you are using .NET Framework and System.Web.Security.Membership is available to you:

Check here:

 string password = Membership.GeneratePassword(12, 1);

Note that this class is not available in .NET Standard or .NET Core.


Although I'm a bit late to the party, I would like to share the helper method I put together to handle these kind of scenarios in an ASP.NET Core compatible way.

The function below ensures a decent char distribution, adding the required character types randomly within the string and not altering the required length (unless edge-case scenarios with lots of required unique chars, which was meant by design). It also features the support for the RequiredUniqueChars rule, which is one of the strength requirements available for the ASP.NET Core Identity framework.

    /// <summary>
    /// Generates a Random Password
    /// respecting the given strength requirements.
    /// </summary>
    /// <param name="opts">A valid PasswordOptions object
    /// containing the password strength requirements.</param>
    /// <returns>A random password</returns>
    public static string GenerateRandomPassword(PasswordOptions opts = null)
    {
        if (opts == null) opts = new PasswordOptions()
        {
            RequiredLength = 8,
            RequiredUniqueChars = 4,
            RequireDigit = true,
            RequireLowercase = true,
            RequireNonAlphanumeric = true,
            RequireUppercase = true
        };

        string[] randomChars = new[] {
            "ABCDEFGHJKLMNOPQRSTUVWXYZ",    // uppercase 
            "abcdefghijkmnopqrstuvwxyz",    // lowercase
            "0123456789",                   // digits
            "!@$?_-"                        // non-alphanumeric
        };

        Random rand = new Random(Environment.TickCount);
        List<char> chars = new List<char>();

        if (opts.RequireUppercase)
            chars.Insert(rand.Next(0, chars.Count), 
                randomChars[0][rand.Next(0, randomChars[0].Length)]);

        if (opts.RequireLowercase)
            chars.Insert(rand.Next(0, chars.Count), 
                randomChars[1][rand.Next(0, randomChars[1].Length)]);

        if (opts.RequireDigit)
            chars.Insert(rand.Next(0, chars.Count), 
                randomChars[2][rand.Next(0, randomChars[2].Length)]);

        if (opts.RequireNonAlphanumeric)
            chars.Insert(rand.Next(0, chars.Count), 
                randomChars[3][rand.Next(0, randomChars[3].Length)]);

        for (int i = chars.Count; i < opts.RequiredLength
            || chars.Distinct().Count() < opts.RequiredUniqueChars; i++)
        {
            string rcs = randomChars[rand.Next(0, randomChars.Length)];
            chars.Insert(rand.Next(0, chars.Count), 
                rcs[rand.Next(0, rcs.Length)]);
        }

        return new string(chars.ToArray());
    }

The function takes a PasswordOptions object as parameter, which is shipped by the Microsoft.AspNetCore.Identity assembly, but you can easily replace it with a two int / four bool parameter group (or POCO class) if you don't have that package installed.

In the likely case you have it in your ASP.NET Core project, you can use the exact same object used in the ConfigureService method of the Startup class when defining the password requirements:

[...]

// Add ASP.NET Identity support
services.AddIdentity<ApplicationUser, IdentityRole>(
    opts =>
    {
        opts.Password.RequireDigit = true;
        opts.Password.RequireLowercase = true;
        opts.Password.RequireUppercase = true;
        opts.Password.RequireNonAlphanumeric = false;
        opts.Password.RequiredLength = 7;
    })
    .AddEntityFrameworkStores<ApplicationDbContext>();

[...]

For additional details regarding this helper function you can also read this post on my blog.


ASP.NET Identity does not have a generate password method.

I'm not sure of your exact use case, but I believe the preferred approach would be to send the user a reset password link that allows the user to enter their own password. This is generally considered more secure than sending out a generated password in plain text.

See the Reset Password section in this tutorial: http://www.asp.net/identity/overview/features-api/account-confirmation-and-password-recovery-with-aspnet-identity