【问题标题】:Alternative to System.Web.Security.Membership.GeneratePassword in aspnetcore (netcoreapp1.0)在 aspnetcore (netcoreapp1.0) 中替代 System.Web.Security.Membership.GeneratePassword
【发布时间】:2016-12-24 00:54:01
【问题描述】:

AspNetCore (netcoreapp1.0) 中的System.Web.Security.Membership.GeneratePassword 有什么替代品吗?

最简单的方法是只使用Guid.NewGuid().ToString("n"),它的长度足以配得上密码,但它不是完全随机的。

【问题讨论】:

  • System.Web.Security.Membership.GeneratePassword 做了什么你不想要的?
  • 该方法所做的只是generate a random password,自己做起来超级容易。

标签: asp.net asp.net-mvc asp.net-core asp.net-core-1.0 .net-standard-1.5


【解决方案1】:

这是一个基于 Membership.GeneratePassword 的源代码的类/方法,适用于 .NET Core:

public static class Password
{
    private static readonly char[] Punctuations = "!@#$%^&*()_-+=[{]};:>|./?".ToCharArray();

    public static string Generate(int length, int numberOfNonAlphanumericCharacters)
    {
        if (length < 1 || length > 128)
        {
            throw new ArgumentException(nameof(length));
        }

        if (numberOfNonAlphanumericCharacters > length || numberOfNonAlphanumericCharacters < 0)
        {
            throw new ArgumentException(nameof(numberOfNonAlphanumericCharacters));
        }

        using (var rng = RandomNumberGenerator.Create())
        {
            var byteBuffer = new byte[length];

            rng.GetBytes(byteBuffer);

            var count = 0;
            var characterBuffer = new char[length];

            for (var iter = 0; iter < length; iter++)
            {
                var i = byteBuffer[iter] % 87;

                if (i < 10)
                {
                    characterBuffer[iter] = (char)('0' + i);
                }
                else if (i < 36)
                {
                    characterBuffer[iter] = (char)('A' + i - 10);
                }
                else if (i < 62)
                {
                    characterBuffer[iter] = (char)('a' + i - 36);
                }
                else
                {
                    characterBuffer[iter] = Punctuations[i - 62];
                    count++;
                }
            }

            if (count >= numberOfNonAlphanumericCharacters)
            {
                return new string(characterBuffer);
            }

            int j;
            var rand = new Random();

            for (j = 0; j < numberOfNonAlphanumericCharacters - count; j++)
            {
                int k;
                do
                {
                    k = rand.Next(0, length);
                }
                while (!char.IsLetterOrDigit(characterBuffer[k]));

                characterBuffer[k] = Punctuations[rand.Next(0, Punctuations.Length)];
            }

            return new string(characterBuffer);
        }
    }
}

我在CrossSiteScriptingValidation.IsDangerousString 上省略了do...while 循环。如果需要,您可以自行添加。

你可以这样使用它:

var password = Password.Generate(32, 12);

另外,请确保您引用 System.Security.Cryptography.Algorithms

【讨论】:

  • 这很有帮助。谢谢。
  • 这很有帮助。有没有一些巧妙的方法来添加其余的非字母数字字符,[因为你省略了一些;)]?创建 StringRaw 类什么的?
  • 此方法(作为框架中的方法)由于在byte % 87 中使用了模数而存在偏差。对于大多数用例来说可能不是问题,但要记住一些事情。如果在 Punctuations 数组中添加或删除字符,则偏差会发生变化。
  • 感谢您制作即用型课程! - 是的,我很懒 ;-)
  • 如果i == 86,这将抛出这个长度的标点符号列表,因为你会得到一个超出索引的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多