I finally found a good use for the background manipulation that VB performs on strings. Normally, a password would be saved in the registry as an encrypted or hashed value in Binary format. The available registry commands in VB only support string values, so saving binary values involves using API calls. Since the VB commands are much simpler, I decided to do a little experimentation. When a byte array is passed to the "SaveSetting" command, it stores the array as if it was a Unicode string. For example, the string "01234" is "00 30 00 31 00 32 00 33 00 34" in memory. When the byte array for this value is stored in the registry with VB, it displays as "??4". This does not take the place of encryption or hashing, as it is easy enough to decode the recovered string, but it does hide the existence of the password store. I have used rather obvious key names in the following, so to hide them you would use less obvious names.
In the past, if the stored password was empty or non-existent, I would ask the user to enter the password as if they were setting up the program for the first time. If the user forgot the password, he/she could go into the registry, delete the stored password, and enter a new one in the program. This was convenient for the user, but it also made it easy for an unauthorized individual to gain access. What I do now is store a default password. Then when the program is activated, it detects the default password and asks the user to enter a new password. The unreadable storage provided by the above makes duplicating the default password difficult.
J.A. Coutts
Note: I have not tested these routines with real Unicode characters.
Code:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Sub cmdDecode_Click()
Dim sKey As String
Dim bBuffer() As Byte
Dim M%, N%
sKey = GetSetting("TEST", "Passwords", "Program1")
ReDim bBuffer(LenB(sKey) - 1)
CopyMemory bBuffer(0), ByVal StrPtr(sKey), LenB(sKey)
sKey = String$(UBound(bBuffer) + 1, " ")
M% = 1
For N% = 0 To UBound(bBuffer)
If bBuffer(N%) > 0 Then
Mid$(sKey, M%, 1) = Chr$(bBuffer(N%))
End If
M% = M% + 1
Next N%
txtPW.Text = sKey
End Sub
Private Sub cmdGet_Click()
Dim sKey As String
Dim bBuffer() As Byte
Dim M%, N%
sKey = GetSetting("TEST", "Passwords", "Program1")
txtPW.Text = sKey
End Sub
Private Sub cmdSave_Click()
Dim sPW As String
Dim bTmp() As Byte
Dim N%
sPW = txtPW.Text
ReDim bTmp(Len(sPW) - 1)
For N% = 1 To Len(sPW)
bTmp(N% - 1) = Asc(Mid$(sPW, N%, 1))
Next N%
SaveSetting "TEST", "Passwords", "Program1", bTmp
End Sub
J.A. Coutts
Note: I have not tested these routines with real Unicode characters.