我编写了一个简单的模块,可以生成满足我复杂性要求的密码。
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,但不能用于在加密环境中生成随机值,因为它是某种可预测的(或者比其他函数更可预测 - 不可预测)。
答案 0 :(得分:3)
根本不要使用Random
这样敏感的东西。请改用RNGCryptoServiceProvider
,这样可以提供合理安全的播种。
使用Random
并不是一个简单的API - 你基本上只是获取字节,可能保证不为零 - 但它是一个更合适的API。