This chapter introduces you to a password generator PWG8 developed by the author and a password-protected programme that uses passwords from the password generator PWG8. The special feature is that you can encrypt plaintext passwords and decrypt pwg8-encrypted passwords.
The presented PWG8 password generator uses its own class with two methods EncodePW(sInput As String) and DecodePW(sInput As String). The strength of the entered password (plain text) is checked.
Figure 28.2.4.1.1: Password generator PWG8
Here is a selection of encrypted passwords for the plaintext password '+gamBas3' :
If the plaintext password is not a strong password, then the criteria for a strong password are displayed:
Figure 28.2.4.1.2: Hints for a strong password
Figure 28.2.4.1.3: Decryption of an encrypted password
You can also use the password generator to decrypt a strong pwg8-encrypted password and display the plaintext.
The source code for the custom class PWG8 is shown in full, while from the main program only the procedure is given which carries the main load in the password generator.
Contents of the file PWG8.class:
' Gambas class file ' This class PWG8 provides 2 public methods that are needed to encode ' and decoding a password. It also provides a globalValid ' variable of type Boolean is provided for checking purposes. The class can be ' controlled from a user interface via its public interface. ' *** Private constants *** ' That's 4 sets of characters for the encrypted password. ' The only important thing is that they are disjunctive sets. ' This means that a character may only occur once in the 4 subsets. ' Character set: Private Const sCharactersetGB As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ' 26 Characters Private Const sCharactersetKB As String = "abcdefghijklmnopqrstuvwxyz" ' 26 Characters Private Const sCharactersetN As String = "0123456789" ' 10 Characters Private Const sCharactersetS As String = "@#+*!?" ' 6 Characters ' *** Public variables *** Public password As String ' *** Constructor *** Public Sub _new() Password = "" End ' _new() ' *** Public method *** Public Function EncodePW(sInput As String) As String ' <--- Encrypt Dim iCount, iPosition, kCount As Integer Dim longInteger As Long Dim sCharacter, sBitSequence8, sBitSequence2, sPasswordE As String Randomize ' <--- Initialisation with timestamp sPasswordE = "" For iCount = 1 To Len(sInput) sCharacter = Mid(sInput, iCount, 1) longInteger = Asc(sCharacter) sBitSequence8 = Bin(longInteger, 8) iPosition = 1 For kCount = 1 To 4 sBitSequence2 = Mid(sBitSequence8, iPosition, 2) Select Case sBitSequence2 Case "00" sPasswordE = sPasswordE & Mid(sCharactersetGB, Int(Rnd(1, Len(sCharactersetGB) + 1)), 1) Case "01" sPasswordE = sPasswordE & Mid(sCharactersetKB, Int(Rnd(1, Len(sCharactersetKB) + 1)), 1) Case "10" sPasswordE = sPasswordE & Mid(sCharactersetN, Int(Rnd(1, Len(sCharactersetN) + 1)), 1) Case "11" sPasswordE = sPasswordE & Mid(sCharactersetS, Int(Rnd(1, Len(sCharactersetS) + 1)), 1) End Select iPosition = iPosition + 2 sBitSequence2 = "" Next ' kCount Next ' iCount Return sPasswordE End ' EncodePW <--- Encrypt Public Function DecodePW(sInput As String) As String ' <--- Decrypt Dim iCount As Integer Dim sCharacter, sBitSequence8, sPasswordD As String sPasswordD = "" sBitSequence8 = "" For iCount = 1 To Len(sInput) sCharacter = Mid(sInput, iCount, 1) If InStr(sCharatersetGB, sCharater) > 0 Then sBitSequence8 = sBitSequence8 & "00" If InStr(sCharatersetKB, sCharater) > 0 Then sBitSequence8 = sBitSequence8 & "01" If InStr(sCharatersetN, sCharater) > 0 Then sBitSequence8 = sBitSequence8 & "10" If InStr(sCharatersetS, sCharater) > 0 Then sBitSequence8 = sBitSequence8 & "11" If iCount Mod 4 = 0 Then sPasswordD = sPasswordD & Chr(BitSequenceToDecimal(sBitSequence8)) sBitSequence8 = "" Endif ' iCount MOD 4 = 0 ? Next ' iCount Return sPasswordD End ' DecodePW <--- Decrypt Property Read Valid As Integer ' A check is made to see if a strong password has been entered. ' *** Private method *** Private Function Valid_Read() As Integer Dim iCount, iKB, IGB, iNUM, iSZ As Integer Dim sInput, sCharater, sCharaterset As String If Not Me.Password Then Return -1 Else sInput = Me.Password Endif ' Not Me.Password ? For iCount = 1 To Len(sInput) sCharater = Mid(sInput, iCount, 1) sCharaterset = sCharatersetGB & sCharatersetKB & sCharatersetN & sCharatersetS If InStr(sCharaterset, sCharater) = 0 Then Return -2 Endif ' Password with at least 1 illegal character ? Next ' iCount For iCount = 1 To Len(sInput) sCharater = Mid(sInput, iCount, 1) If InStr(sCharatersetKB, sCharater) <> 0 Then iKB = 1 Endif ' Password with at least 1 lower case letter ? Next ' iCount For iCount = 1 To Len(sInput) sCharater = Mid(sInput, iCount, 1) If InStr(sCharatersetGB, sCharater) <> 0 Then iGB = 1 Endif ' Password with at least 1 capital letter ? Next ' iCount For iCount = 1 To Len(sInput) sCharater = Mid(sInput, iCount, 1) If InStr(sCharactersetN, sCharacter) <> 0 Then iNUM = 1 Endif ' Password with at least 1 digit ? Next ' iCount For iCount = 1 To Len(sInput) sCharacter = Mid(sInput, iCount, 1) If InStr(sCharactersetS, sCharacter) <> 0 Then iSZ = 1 Endif ' Password with at least 1 special character ? Next ' iCount If iKB + iGB + iNUM + iSZ < 4 Then Return -3 If Len(Me.Password) < 8 Then Return -4 Return 0 End ' Valid_Read() Private Function BitSequenceToDecimal(sInput As String) As Integer Dim iCount, iDecimal As Integer Dim sLocation As String For iCount = 0 To Len(sInput) - 1 sLocation = Mid(sInput, Len(sInput) - iCount, 1) iDecimal = iDecimal + CInt(sLocation) * 2 ^ iCount Next ' iCount Return iDecimal End ' BitSequenceToDecimal This is the content of the file FMain.class: Public Sub btnEncodeDecode_Click() MyPWG8.Password = txtPasswordInput.Text Select Case MyPWG8.Valid Case -1 Message.Error("The input field is empty!") txtPasswordInput.SetFocus Return Case -2 Message.Error("At least one character in the password is not allowed!") txtPasswordInput.SetFocus Return Case -3 Message.Error("The password is NOT a strong password!") txtPasswordInput.SetFocus Return Case -4 Message.Error("The password is too short!") txtPasswordInput.SetFocus Return Case Else ' 0 → Without error If chkPasswordDisplay.Value = True Then txtPasswordOutput.Password = False Else txtPasswordOutput.Password = True Endif ' chkPasswordDisplay.Value = True ? If optEncode.Value = True Then txtPasswordOutput.Text = MyPWG8.EncodePW(MyPWG8.Password) Else txtPasswordOutput.Text = MyPWG8.DecodePW(MyPWG8.Password) Endif ' optEncode.Value = True ? End Select ' MyPWG8.Valid End ' btnDecodeEncode_Click()
Comment:
The complete project and an application of the PWG8 password generator can be found in the download area.