basically it takes some secret passphrases, and md5 hashes them with the hardware id of the user. this becomes the license key. then in the installer we check that the same hash matches the key given. the key (hash) looks like its 32 chars long from md5. maybe you can trim that if you want, but i dont know if you will have collisions. the machine fingerprint is primitive as well and is trimmed to 16
this is not very secure because your secret passphrases must be stored within your 'installer' application so that the installer itself can perform the same hash to verify the license key. if someone hacks your installer and gets your passphrases and knows to use md5, then they can build a keygen
Code:
secret_passphrase1 := "dave_is_the_man_123"
secret_passphrase2 := "456_blah_789"
Gui, Add, Text,, USE THIS TO GENERATE
Gui, Add, Text, section, Users Hardware ID:
Gui, Add, Button, gGenerateButton, Generate
Gui, Add, Text,, Users Key:
Gui, Add, Edit, ys w240 vHw_Id_To_Generate_For,
Gui, Add, Text
Gui, Add, Edit, w240 vGenerated_Key
Gui, Add, Text, xs
Gui, Add, Text,, TEST CLIENT SIDE ACCESS
Gui, Add, Text, section, Your Hardware ID is:
Gui, Add, Text,, Enter the Key given to you:
Gui, Add, Button, gCheckButton, Check License Key
Gui, Add, Edit, ys w240 vHw_Id_To_Check, % MachineFingerprint()
Gui, Add, Edit, w240 vKey_To_Check,
Gui, Show
return
GuiClose:
ExitApp
return
GenerateButton:
Gui, Submit, NoHide
concatenated := secret_passphrase1 . Hw_Id_To_Generate_For . secret_passphrase2
hash := AuthHash(concatenated, StrLen(concatenated), 3)
GuiControl,, Generated_Key, %hash%
return
CheckButton:
Gui, Submit, NoHide
concatenated := secret_passphrase1 . Hw_Id_To_Check . secret_passphrase2
hash := AuthHash(concatenated, StrLen(concatenated), 3)
if (hash = Key_To_Check)
MsgBox, key good! proceed with install
else
MsgBox, key bad
return
AuthHash(ByRef sData, nLen, SID = 4) { ; SID: 3 for MD5, 4 for SHA
DllCall("advapi32\CryptAcquireContextA", "UintP", hProv, "Uint", 0, "Uint", 0, "Uint", 1, "Uint", 0xF0000000)
DllCall("advapi32\CryptCreateHash", "Uint", hProv, "Uint", 0x8000|0|SID , "Uint", 0, "Uint", 0, "UintP", hHash)
DllCall("advapi32\CryptHashData", "Uint", hHash, "Uint", &sData, "Uint", nLen, "Uint", 0)
DllCall("advapi32\CryptGetHashParam", "Uint", hHash, "Uint", 2, "Uint", 0, "UintP", nSize, "Uint", 0)
VarSetCapacity(HashVal, nSize, 0)
DllCall("advapi32\CryptGetHashParam", "Uint", hHash, "Uint", 2, "Uint", &HashVal, "UintP", nSize, "Uint", 0)
DllCall("advapi32\CryptDestroyHash", "Uint", hHash)
DllCall("advapi32\CryptReleaseContext", "Uint", hProv, "Uint", 0)
format = %A_FormatInteger% ; save original integer format
SetFormat, Integer, H
Loop, %nSize% {
nValue := *(&HashVal + A_Index - 1)
StringReplace, nValue, nValue, 0x, % (nValue < 16 ? 0 :)
sHash .= nValue
}
SetFormat Integer, %format% ; restore original format
Return sHash
}
MachineFingerprint() {
EnvGet, COMPUTERNAME, COMPUTERNAME
EnvGet, PROCESSOR_ARCHITECTURE, PROCESSOR_ARCHITECTURE
EnvGet, PROCESSOR_REVISION, PROCESSOR_REVISION
DriveGet, DRIVESERIAL, Serial, C:\
PCdata := A_OSType . A_OSVersion . COMPUTERNAME
PCdata .= PROCESSOR_ARCHITECTURE . PROCESSOR_REVISION . DRIVESERIAL
fingerprint := AuthHash(PCdata, StrLen(PCdata))
fingerprint := SubStr(fingerprint, 1, 16)
return fingerprint
}