【问题标题】:Get random seed for generating unique password获取随机种子以生成唯一密码
【发布时间】:2014-09-13 05:28:29
【问题描述】:

我编写了一个简单的模块来生成满足我复杂性要求的密码。

Module PasswordGenerator
   Private ReadOnly _alphaChars As Char() = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".ToArray()
   Private ReadOnly _digitChars As Char() = "0123456789".ToArray()
   Private ReadOnly _nonAlphaNumChars As Char() = "_-.,:;!$%&/()[]=+#".ToArray()
   Private ReadOnly _allPswChars As Char() = _alphaChars.Concat(_digitChars).Concat(_nonAlphaNumChars).ToArray()

   Public Function GeneratePassword(length As Integer, minNonAlphaNum As Integer, minDigits As Integer) As String
      Return GeneratePassword(length, minNonAlphaNum, minDigits, New Random(GetSeed()))
   End Function

   Public Function GeneratePassword(length As Integer, minNonAlphaNum As Integer, minDigits As Integer, rnd As Random) As String
      Dim selectedChars As List(Of Char),
          psw As String,
          rndSelectedChar As Integer
      If length < (minNonAlphaNum + minDigits) Then Throw New ArgumentException
      selectedChars = New List(Of Char)(length)
      selectedChars.AddRange(GetRandomChars(_nonAlphaNumChars, minNonAlphaNum, rnd))
      selectedChars.AddRange(GetRandomChars(_digitChars, minDigits, rnd))
      selectedChars.AddRange(GetRandomChars(_allPswChars, (length - minNonAlphaNum - minDigits), rnd))
      psw = ""
      For i As Integer = 1 To selectedChars.Count
         rndSelectedChar = rnd.Next(0, selectedChars.Count)
         psw &= selectedChars(rndSelectedChar)
         selectedChars.RemoveAt(rndSelectedChar)
      Next
      Return psw
   End Function

   Private Function GetSeed() As Integer
      Dim guidString As String
      guidString = Guid.NewGuid().ToString("N").Substring(0, 5)
      Return Int32.Parse(guidString, Globalization.NumberStyles.HexNumber)
   End Function

   Private Function GetRandomChars(charRange As Char(), count As Integer, rnd As Random) As List(Of Char)
      Dim retVal As New List(Of Char),
          selectedPos As Integer

      If count < 1 Then Return retVal
      For i As Integer = 1 To count
         selectedPos = rnd.Next(0, charRange.Length)
         retVal.Add(charRange(selectedPos))
      Next

      Return retVal
   End Function
End Module

如果我在没有GetSeed() 函数的情况下使用此代码,如果我在循环中生成密码,我将多次获得相同的密码。通过使用 guid 作为随机种子,我可以确保不会获得相同的密码,因为 NewGuid 函数确保不会生成相同的 guid。系统提供的生成 guid 的功能可确保不会获得相同的 guid,但不是用于在加密环境中生成随机值,因为它是某种可预测的(或比其他功能更可预测 - 不可预测是不可能的)。

  • 您是否建议以任何方式更改我的代码?
  • 有没有更好的方法来解决我的问题?
  • 单例随机对象会不会比使用 guid 作为种子更难预测(我相信这也可以确保不会获得相同的密码)?

【问题讨论】:

    标签: .net vb.net random passwords cryptography


    【解决方案1】:

    不要将Random 用于像这样敏感的事情。请改用RNGCryptoServiceProvider,它提供了相当安全的播种。

    使用 API 不像 Random 那样简单——你基本上只是获取字节,可能保证不为零——但它是一个更合适的 API。

    【讨论】:

    • 但是,在 IIS 服务器上运行此程序时,有人可能猜到生成的密码是否存在现实风险?获得有关我的服务器的足够知识以真正预测生成的字符串不是几乎不可能吗?
    • @user1200847:我不知道 - 你想防止什么攻击媒介?您要保护哪些资源?对于您需要的保护级别,这可能还可以,但我们不知道那是什么。在生成密码时,我倾向于谨慎行事。
    • 也许我可以比这更简单地解决我的问题,但我现在无法尝试:如果我设置了PasswordStrengthRegularExpression 然后调用MembershipUser.ResetPassword() 会发生什么?跨度>
    • @user1200847:恐怕我对这些一无所知。
    • 谢谢你,我相信我会实施你基于RNGCryptoServiceProvider 的建议。
    猜你喜欢
    • 2011-08-19
    • 2011-04-18
    • 2023-02-14
    • 2010-09-08
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    相关资源
    最近更新 更多