【发布时间】: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