Timothy
  • Timothy
  • 100% (Exalted)
  • Flock Leader Topic Starter
2009-01-23T12:10:19Z
I've been emailed a few times about how XS BAP generates its random passwords, so I am going to post the code below. It's not well commented, but basically it first checks to see what settings you specified and then generates a random password of a random length between the min and max. After that, it verifies complexity and if it fails complexity, it changes a character into a missing character type. After this, it randomly changes the order of all the characters so that any "forced complexity" characters do not always end up at the end of the string. It currently uses the Random class in .Net, but I have plans to see if I can change it over to a more cryptographically secure random number generator in the future. The generated passwords, if of a sufficient length, should provide adequette protection against any password cracker that doesn't "cheat" (eg, use rainbow tables and/or have some other sort of access to the box that negates the effectiveness of any password complexity and policy). Code is below!


  Public Shared Function RandomPW() As String
    Const lowerChars As String = "abcdefghijklmnopqrstuvwxyz"
    Const upperChars As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    Const numbers As String = "0123456789"
    Dim symbols As String = My.Settings.RandomPasswordSymbolSet

    Dim hasLower As Boolean = False
    Dim hasUpper As Boolean = False
    Dim hasNumbers As Boolean = False
    Dim hasSymbols As Boolean = False

    Dim complexity As Integer = 0

    Dim s As String = ""
    Dim l As Integer = 0
    Dim type As Integer = 0
    Dim n As Integer = 0
    Dim r As New Random(randSeed.Next)

    l = r.Next(My.Settings.RandomPasswordMinimumLength, My.Settings.RandomPasswordMaximumLength + 1)

    For i As Integer = 1 To l
      type = r.Next(0, IIf(My.Settings.RandomPasswordUseLettersMoreThanOthers, 9, 8))

      Select Case type
        Case 0, 1
          n = r.Next(0, lowerChars.Length)
          s &= lowerChars.Chars(n)
        Case 2, 3
          n = r.Next(0, upperChars.Length)
          s &= upperChars.Chars(n)
        Case 4
          n = r.Next(0, numbers.Length)
          s &= numbers.Chars(n)
        Case 5
          n = r.Next(0, symbols.Length)
          s &= symbols.Chars(n)
        Case 6
          If My.Settings.RandomPasswordUseLettersMoreThanOthers Then
            n = r.Next(0, lowerChars.Length)
            s &= lowerChars.Chars(n)
          Else
            n = r.Next(0, numbers.Length)
            s &= numbers.Chars(n)
          End If
        Case 7
          If My.Settings.RandomPasswordUseLettersMoreThanOthers Then
            n = r.Next(0, upperChars.Length)
            s &= upperChars.Chars(n)
          Else
            n = r.Next(0, symbols.Length)
            s &= symbols.Chars(n)
          End If
        Case Else ' 8
          If r.Next(0, 2) = 0 Then
            n = r.Next(0, numbers.Length)
            s &= numbers.Chars(n)
          Else
            n = r.Next(0, symbols.Length)
            s &= symbols.Chars(n)
          End If
      End Select
    Next


    ' Make sure we have the appropriate level of complexity, if required
    If My.Settings.RandomPasswordMustBeComplex Then
      If GetComplexityValue(s) < My.Settings.ComplexPasswordMinimumCharacterTypes Then
        s = s.Substring(0, s.Length - 1) & symbols.Chars(r.Next(0, symbols.Length))
        If GetComplexityValue(s) < My.Settings.ComplexPasswordMinimumCharacterTypes Then
          s = s.Substring(0, s.Length - 2) & numbers.Chars(r.Next(0, numbers.Length)) & symbols.Chars(r.Next(0, symbols.Length))
          If GetComplexityValue(s) < My.Settings.ComplexPasswordMinimumCharacterTypes Then
            s = s.Substring(0, s.Length - 3) & upperChars.Chars(r.Next(0, upperChars.Length)) & numbers.Chars(r.Next(0, numbers.Length)) & symbols.Chars(r.Next(0, symbols.Length))
            If GetComplexityValue(s) < My.Settings.ComplexPasswordMinimumCharacterTypes Then
              s = s.Substring(0, s.Length - 4) & lowerChars.Chars(r.Next(0, lowerChars.Length)) & upperChars.Chars(r.Next(0, upperChars.Length)) & numbers.Chars(r.Next(0, numbers.Length)) & symbols.Chars(r.Next(0, symbols.Length))
            End If
          End If
        End If
      End If
    End If

    ' now jumble all the characters around, in case we had to use the "forced complexity" up above.
    For i As Integer = 0 To (s.Length / 2) - 1
      Dim n1 As Integer = r.Next(0, s.Length)
      Dim n2 As Integer = r.Next(0, s.Length)
      Dim c1 As Char = s.Chars(n1)
      Dim c2 As Char = s.Chars(n2)
      Dim a() As Char = s.ToCharArray
      a(n1) = c2
      a(n2) = c1
      s = New String(a)
    Next

    Return s
  End Function
Users browsing this topic
full film