ternal Posted April 26, 2019 Share Posted April 26, 2019 (edited) hi, As a side project for a main I am trying to write a (hopefully reuseable) script. This is the first time I am using encryption so I might have done something wrong and create a security issue, the goal of the script is so it could be used by other scripts as a login handler/saver. So if anyone feels like checking wether or not I used encryption/hashing correctly be my guest. Any input is appriciated!!! I feel fairly confident for most(of my) purposes this script will be secure enough. I have done some testing and I have added a few options. If anyone would like to use this, there are examples in the script Feel free to alter it in any way expandcollapse popup##Version 01/05/2019 #include-once #Region ##Headers #include <Array.au3> #include <Crypt.au3> #include <File.au3> #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> #EndRegion ##Headers Opt ("GUIOnEventMode", 1) Opt ("GUIEventOptions", 1) #Region ##Examples ;Local $aencryption = "4fxRuvY" ;~ _Login_CreateUser(@ScriptDir & "\test.cdt", "testuser", "testpw2", $aencryption, True) ;~ _Login_AskForList(@ScriptDir & "\test.cdt", $aencryption, True) ;~ _Login_DeleteUser(@ScriptDir & "\test.cdt", "testuser", $aencryption) ;~ _Login_CheckUserCredentials(@ScriptDir & "\test.cdt", "testuser", "testpw2", $aencryption) ;~ _Login_ChangePW(@ScriptDir & "\test.cdt", "testuser2", "test", "testpw2", $aencryption) ;~ ;~ Notes: ;~ You still need to handle the button functions of the form yourself. ;~ Different apps need different functions after all. ;~ The encryption of the userlist/hash list is purely to protect privacy of the userlist. ;~ This can be easly cracked but even then are the passwords hashed out. Beware!!! #EndRegion ;###################### Example script () ####################### ; this is an example of the script automatically generating an user and then asking for a login ; This is how you could use my script as a login module for your script ;~ #include <Login.au3> ;~ Global $aLoginVars; declare a global array to hold the form variables. This is global for ease of acces of the form elements. ;~ Global $sCurrentUser; declare global string to set what user logged in. ;~ _Login_CreateUser(@ScriptDir & "\test.cdt", "Username", "Password", "4fxRuvY", True); generate a user with username "username" and password "Password" ;~ If @error Then MsgBox(0, "creating error", @error & " " & @extended) ;~ _Quiz_Login(); do the login ;~ While 1 ;~ Sleep(100) ;~ WEnd ;~ Func _Quiz_Login () ;~ $aLoginVars = _Login_Form_AskLogin() ; create login window ;~ GUISetOnEvent($GUI_EVENT_CLOSE, "Quit", $aLoginVars[0][0]); exitbutton(X) on the form menu bar was clicked ;~ GUICtrlSetOnEvent($aLoginVars[1][0], "_Quiz_Login_Check"); button OK was pressed ;~ GUICtrlSetOnEvent($aLoginVars[2][0], "Quit"); button Cancel was pressed ;~ GUISetState(@SW_SHOW, $aLoginVars[0][0]); Display the generated GUI ;~ EndFunc ;~ Func _Quiz_Login_Check() ;~ Local $sUsername = GUICtrlRead($aLoginVars[4][0]); get username ;~ Local $sPassword = GUICtrlRead($aLoginVars[3][0]); get password ;~ Local $aCheckResult = _Login_CheckUserCredentials(@ScriptDir & "\test.cdt", $sUsername, $sPassword, "4fxRuvY") ; check both ;~ If @error Then MsgBox(0,"@error", @error & " extended:" & @extended) ; check for errors ;~ If $aCheckResult[0] = True Then; user is correct ;~ If $aCheckResult[1] = True Then ;~ $sCurrentUser = $sUsername; PW is correct ;~ EndIf ;~ EndIf ;~ EndFunc ;~ Func Quit () ;~ Exit ;~ EndFunc ;########################### End of examplescript ################ #Region ##Functions ; _Login_CreateUser ==================================================================================================================== ; Description ...: Creates and writes a new user to the file. If the file does not exist it will try to make a new one. ; You have to provide the encryption array. ; For more info please check comments section/ the actual script comments :-) ; Syntax ........: _Login_CreateUser ($sUsername, $sPassword, $sEncryptionPW, $sFileLocation,[$bCreateNew = False]) ; Parameters ....: $sFileLocation - a string containing the FULL path to the file.(make sure permissions are sufficient to write there). ; $sUsername - a string containing the username.(Clear txt.) ; $sPassword - a string containing the password.(Clear txt.) ; $sEncryptionPW - a string containing the encryption PW(Clear txt) ; Return values .: 1 if succes , 0 and sets @error if there is an error ; Author ........: Ternal ; ;@error 1: - Path does not exist($sFileLocation) -@extended 1 : Bool to make a new path was set to false and path does not exist. ; -@extended 2 : Could not open file.(In use or permissions?) ; ;@error 2: Encryption PW incorrect -@extended 1 :It less then 6 chars or there is a space in it. ; -@extended 2 : Function failed to decrypt file, PW incorrect or file corrupted. ; ;@error 3 :User already exists ; ;@error4 :Failed to create user -@extended 1 : In a new file. ; -@extended 2 :In an existing file. ; ; =============================================================================================================================== Func _Login_CreateUser($sFileLocation, $sUsername, $sPassword, $sEncryptionPW, $bCreateNew = Default) If $bCreateNew = Default Then $bCreateNew = False ; parameter setting Local $hFile ; declare the var for the filehandle If Not (FileExists($sFileLocation)) Then ;check if path exists If $bCreateNew = False Then Return SetError(1, 1, 0) ; if the Bool to create a new path is not set and the path does not exist return and set error $hFile = FileOpen($sFileLocation, 9) ; create new path if it did not exist If $hFile = -1 Then Return SetError(1, 2, 0) ; selfexplaining I guess? FileClose($hFile) ; close da file to reopen it elsewhere, they told me I should do this asap always. EndIf ; end of the things to do when the path does not exist Local $sInputCombined = $sUsername & $sPassword ; to avoid checking each string seperatly If (Not (IsString($sUsername) And IsString($sPassword))) Or StringInStr($sInputCombined, " ") Or StringInStr($sInputCombined, ";") Or StringInStr($sInputCombined, "/") Or StringInStr($sInputCombined, "\") Then Return SetError(2, 0, 0) ; inputchecking If StringInStr($sEncryptionPW, " ") Then Return SetError(2, 1, 0) ; inputchecking If StringLen($sEncryptionPW) < 6 Then Return SetError(2, 1, 0) ; inputchecking Local $aUserlist = _Login_AskForList($sFileLocation, $sEncryptionPW, True) If _ArraySearch($aUserlist, $sUsername) > -1 Then Return SetError(3, 0, 0) ; checks if username already exists ;If we are still in function by now this means there are no errors given by our inputchecking Local $aPWHash = _HashPW($sUsername, $sPassword) $hFile = FileOpen($sFileLocation, 17) ; open the file in binary write mode FileSetPos($hFile, 0, 0) ; set pos back to 0( because it was opened in mode 17) Local $sEncryptedContent = FileRead($hFile) ; read the file Local $iFileSize = BinaryLen($sEncryptedContent) If $iFileSize < 4 Then ; file was empty, so we create the first entry. LogWrite("_Login_CreateUser", "New Credential file started @ " & $sFileLocation) Local $sFirstString = __StringEncrypt(True, $sUsername & ";/;" & $aPWHash[0] & ";/;" & $aPWHash[1] & ";/\;", $sEncryptionPW) ; encrypt the credentials with delimeters FileSetPos($hFile, 0, 0) ; set cursor at the start of the file FileWrite($hFile, $sFirstString) ; write to the file FileFlush($hFile) ; save to disk FileSetPos($hFile, 0, 0) ; set cursor at start of file Local $sEncryptedContentTest = FileRead($hFile) ; read the data back from file to string. this is to ensure that the Function will not run further if it was saved incorrectly. FileClose($hFile) ; close the file for now If Not StringInStr(__StringEncrypt(False, $sEncryptedContentTest, $sEncryptionPW), $sUsername & ";/;" & $aPWHash[0] & ";/;" & $aPWHash[1] & ";/\;") Then ; decrypt the file and check if the new credentials are added to it LogWrite("_Login_CreateUser", "Failure to write correctly to a new file") ; it came out wrong Return SetError(4, 1, 0) Else Return 1 ; the first credential is in the file... YAAAAY EndIf Else FileClose($hFile) ; close the file to reopen it in overwrite mode.(to make sure everything works correctly, I had some issues with not getting the right cursor pos so I used this out of lazyness) EndIf FileCopy($sFileLocation, $sFileLocation & ".bak", 9) Local $aCredentialList = __String2Array(__StringEncrypt(False, $sEncryptedContent, $sEncryptionPW)) ; convert the encrypted string to arrayformat for easier handling.(array is the standard format to be used). Local $iOldSize = UBound($aCredentialList, 1) ; get the current size of the array If $iFileSize > 6 And $iOldSize = 0 Then Return SetError(2, 2, 0) EndIf ReDim $aCredentialList[$iOldSize + 1][3] ; resize the array so it can hold one element more.By adding a new row the value of $iOldSize becomes the index of the new row (0 based array) $aCredentialList[$iOldSize][0] = $sUsername ; username in the first column $aCredentialList[$iOldSize][1] = $aPWHash[0] ; passwordhash in the second column $aCredentialList[$iOldSize][2] = $aPWHash[1] ; salt in the third column $sEncryptedContent = __StringEncrypt(True, __Array2String($aCredentialList), $sEncryptionPW) ; encrypt the new array $aCredentialList = "" ; get rid of the credentials in plaintext in the memory, it is no longer needed. $hFile = FileOpen($sFileLocation, 18) ; open in binary overwritemode FileWrite($hFile, $sEncryptedContent) ; write to the file FileFlush($hFile) ; write to disk FileSetPos($hFile, 0, 0) ; set cursor at start of file Local $sEncryptedContent = FileRead($hFile) ; read the file FileClose($hFile) ; we are finished If Not StringInStr(__StringEncrypt(False, $sEncryptedContent, $sEncryptionPW), $sUsername & ";/;" & $aPWHash[0] & ";/;" & $aPWHash[1] & ";/\;") Then ; decrypt the file and check if the new credentials are added to it LogWrite("_Login_CreateUser", "Failure to write correctly to file, or file has been corrupted") ; put :"it came out wrong" in da log FileCopy($sFileLocation & ".bak", $sFileLocation, 1) FileDelete($sFileLocation & ".bak") Return SetError(4, 2, 0) Else FileDelete($sFileLocation & ".bak") Return 1 ; the new user is in the function so I guess its bye bye EndIf EndFunc ;==>_Login_CreateUser ; _Login_AskForUserList ==================================================================================================================== ; Description ...: Retrieves an Userlist from a previous made credential file ; Syntax ........: _Login_Query_UserList ($sFileLocation, $sEncryptionPW,[$bUser = True]) ; Parameters ....: $sFileLocation - a string containing the location of the file ; $sEncryptionPW - a string containing the encryption PW(Clear txt) ; $bUser - if true then return userlist, if false return passwordlist, default is userlist ; Return values .: an array of usernames if succes, empty array or 0 at no succes ; Author ........: Ternal ; ;@error 1: - Path does not exist($sFileLocation) -@extended 1 : Bool to make a new path was set to false and path does not exist. ; -@extended 2 : Could not open file.(In use or permissions?) ; =============================================================================================================================== Func _Login_AskForList($sFileLocation, $sEncryptionPW, $bUser = Default) If Not (FileExists($sFileLocation)) Then Return SetError(1, 1, 0) ; inputchecking If $bUser = Default Then $bUser = True Local $aReturn[1] ; declare the return array If $bUser = True Then $bUser = 0 ; get the userlist Else $bUser = 1 ; get the passwordlist EndIf Local $hFile = FileOpen($sFileLocation, 16) ; open file in binary mode If $hFile = -1 Then Return SetError(1, 2, 0) ; inputchecking FileSetPos($hFile, 0, 0) ; set cursor at start of file Local $sEncryptedContent = FileRead($hFile) ; read the binary file Local $aTemp = __String2Array(__StringEncrypt(False, $sEncryptedContent, $sEncryptionPW)) ; put everything decrypted in an array If $bUser = 0 Then ReDim $aReturn[UBound($aTemp, 1)] ; correct the array size to 1D for usernames For $i = 0 To UBound($aTemp, 1) - 1 $aReturn[$i] = $aTemp[$i][$bUser] ; copy the usernames to the returnarray Next Else ReDim $aReturn[UBound($aTemp, 1)][2] ; correct the array to 2D for pw and salt For $i = 0 To UBound($aTemp, 1) - 1 $aReturn[$i][0] = $aTemp[$i][$bUser] ; copy the password hashes to the returnarray $aReturn[$i][1] = $aTemp[$i][$bUser + 1] ; copy the salt to the returnarray Next EndIf Return $aReturn EndFunc ;==>_Login_AskForList ; _Login_CheckUserCredentials ==================================================================================================================== ; Description ...: Checks wether the given username and password are correct. Please do note this might malfunction when there are duplicate users so beware when creating users please. ; Syntax ........: _Login_CheckUserCredentials ($sFileLocation, $sUsername, $sPassword, $sEncryptionPW) ; Parameters ....: $sFileLocation - a string containing the filelocation ; $sUsername - a string containing the username to check ; $sPassword - a string containing the password to check ; $sEncryptionPW - a string containing the encryption PW(Clear txt) ; Return values .: An Array with at index 0 usercheck (true is correct , false is incorrect) and index 1 holds the password bool.If the encryption PW is wrong you will get 2x False as well ; Author ........: Ternal, Additional credits go to jchd for correcting me !!! ; ;@error 1: - Path does not exist($sFileLocation) -@extended 1 : Bool to make a new path was set to false and path does not exist. ; -@extended 2 : Could not open file.(In use or permissions?) ; =============================================================================================================================== Func _Login_CheckUserCredentials($sFileLocation, $sUsername, $sPassword, $sEncryptionPW) Local $aReturn[2] = [False, False] ; create return array and set it false Local $aUserlist = _Login_AskForList($sFileLocation, $sEncryptionPW, True) ; ask for a list of users If @error Then Local $error = @error Local $extended = @extended Return SetError($error, @extended, $aReturn) EndIf Local $iLocationUsername = _ArraySearch($aUserlist, $sUsername, 0, 0, 0, 0, 1, 0) ; search the first column(usernames) non-case sensitive. If @error Then Return $aReturn If $iLocationUsername > -1 Then ; function returns an integer thats 0 or above so it has found something. $aReturn[0] = True ; set username to be true(found it) Else ; better luck next time for a correct user :( Return $aReturn ; end of the function for this path EndIf Local $aPWList = _Login_AskForList($sFileLocation, $sEncryptionPW, False) ;still running so we are asking for the passwordhashlist... Local $sNewHash = _HashPW($sUsername, $sPassword, $aPWList[$iLocationUsername][1]) If Not ($aPWList[$iLocationUsername][0] == $sNewHash[0]) Then ; check if the passwordhash at the location where we found the username is the same as the hash generated Return $aReturn ; not the same Else $aReturn[1] = True Return $aReturn EndIf EndFunc ;==>_Login_CheckUserCredentials ; _Login_DeleteUser ==================================================================================================================== ; Description ...: Deletes an user from the file ; Syntax ........: _Login_DeleteUser($sFileLocation, $sUsername, $sEncryptionPW) ; Parameters ....: $sFileLocation - a string containing the filepath ; $sUsername - a string containing the user to delete ; $sEncryptionPW - a string containing the encryption PW(Clear txt) ; Return values .: 1 if succes, 0 on error, 404 if the user is not found. ; Author ........: Ternal ; ;@error 1: - Path does not exist($sFileLocation) -@extended 1 : Bool to make a new path was set to false and path does not exist. ; -@extended 2 : Could not open file.(In use or permissions?) ; ;@error2: -Failed to get userlist, encryption PW might be wrong or file might be corrupted ; ;@error3 / return 404 : -User to delete from userlist was NOT in the userlist. ; =============================================================================================================================== Func _Login_DeleteUser($sFileLocation, $sUsername, $sEncryptionPW) Local $aUserlist = _Login_AskForList($sFileLocation, $sEncryptionPW, True) ; ask for a list of users If @error Then Local $error = @error Local $extended = @extended Return SetError($error, @extended, 0) EndIf Local $iSearch = _ArraySearch($aUserlist, $sUsername, 0, 0, 0, 0, 1, 0) If @error = 3 Then Return SetError(2, 0, 0) If $iSearch > -1 Then Local $hFile = FileOpen($sFileLocation, 16) Local $sEncryptedContent = FileRead($sFileLocation) FileClose($hFile) Local $aCredentialList = __String2Array(__StringEncrypt(False, $sEncryptedContent, $sEncryptionPW)) ; convert the encrypted string to arrayformat for easier handling.(array is the standard format to be used). _ArrayDelete($aCredentialList, $iSearch) $hFile = FileOpen($sFileLocation, 18) FileWrite($hFile, __StringEncrypt(True, __Array2String($aCredentialList), $sEncryptionPW)) FileClose($hFile) Else Return SetError(3, 0, 404) EndIf Return 1 EndFunc ;==>_Login_DeleteUser ; _Login_ChangePW ==================================================================================================================== ; Name ..........: _Login_ChangePW ; Description ...: Changes the PW for a user, in reality it checks the old credentials, if correct it deletes the old user and recreates a new user with the new password (CALL ME LAZY , Proud of it). ; Syntax ........: _Login_ChangePW($sFileLocation, $sUsername, $NewPW, $OldPW, $sEncryptionPW) ; Parameters ....: $sFileLocation - a string containing the filepath ; $sUsername - a string containing the user to change pw of ; $NewPW - a string containing the new pw in plaintext ; $OldPW - a string containing the old pw in plaintext ; $sEncryptionPW - a string containing the encryption PW(Clear txt) ; Return values .: 1 if succes, 0 if no succes ; Author ........: Ternal ; =============================================================================================================================== Func _Login_ChangePW($sFileLocation, $sUsername, $NewPW, $OldPW, $sEncryptionPW) Local $aCheck = _Login_CheckUserCredentials($sFileLocation, $sUsername, $OldPW, $sEncryptionPW) If $aCheck[0] = False Then Return 0 If $aCheck[1] = False Then Return 0 _Login_DeleteUser($sFileLocation, $sUsername, $sEncryptionPW) _Login_CreateUser($sFileLocation, $sUsername, $NewPW, $sEncryptionPW) Return 1 EndFunc ;==>_Login_ChangePW ; _Login_Form_AskLogin ==================================================================================================================== ; Name ..........: _Login_Form_AskLogin ; Description ...: Creates a loginform and returns the handles and description in a 2D array. ; Syntax ........: _Login_Form_AskLogin([$sLanguage = Default]) ; Parameters ....: $sLanguage - [optional] What language to use. Default is English. ; Possible options are "English", "French","Dutch",Default.. All other input will result in the function returning 0 and @error set to 1 ; Return values .: If language is correct = array with formvariables, otherwise 0 and set @error to 1 ; Author ........: Ternal ; return array layout: ;[Handle1, Name of the handle] : FormHandle ;[Handle2, Name of the handle] : Button OK ;[Handle3, Name of the handle] : Button Cancel ;[Handle4, Name of the handle] : Inputbox PW ;[Handle5, Name of the handle] : Inputbox User ;[Handle6, Name of the handle] : label pw ;[Handle7, Name of the handle] : Label user ; =============================================================================================================================== Func _Login_Form_AskLogin($sLanguage = Default) If $sLanguage = Default Then $sLanguage = "English" Local $TXT_UserInput, $TXT_LabelPW, $TXT_LabelUser, $TXT_FormTitle, $TXT_BtnOk, $TXT_BtnCncl Select Case $sLanguage = "English" $TXT_FormTitle = "Login" $TXT_LabelPW = "Password" $TXT_LabelUser = "Username" $TXT_BtnOk = "Login" $TXT_BtnCncl = "Cancel" Case $sLanguage = "Dutch" $TXT_FormTitle = "Login" $TXT_LabelPW = "Wachtwoord" $TXT_LabelUser = "Gebruikersnaam" $TXT_BtnOk = "Login" $TXT_BtnCncl = "Annuleren" Case $sLanguage = "French" $TXT_FormTitle = "Login" $TXT_LabelPW = "mot de passe" $TXT_LabelUser = "Nom d'utilisateur" $TXT_BtnOk = "s'Identifier" $TXT_BtnCncl = "Annuler" Case Else Return SetError(1, 0, 0) EndSelect Local $aFormVars[7][2] $aFormVars[0][0] = GUICreate($TXT_FormTitle, 275, 154, -1, -1) $aFormVars[0][1] = "LoginForm" $aFormVars[4][0] = GUICtrlCreateInput("", 14, 28, 233, 21, $GUI_SS_DEFAULT_INPUT) $aFormVars[4][1] = "UserInput" $aFormVars[3][0] = GUICtrlCreateInput("", 14, 72, 233, 21, BitOR($GUI_SS_DEFAULT_INPUT,$ES_PASSWORD)) $aFormVars[3][1] = "PWInput" $aFormVars[1][0] = GUICtrlCreateButton($TXT_BtnOk, 92, 108, 75, 25, $BS_NOTIFY) $aFormVars[1][1] = "BTNOk" $aFormVars[2][0] = GUICtrlCreateButton($TXT_BtnCncl, 173, 108, 75, 25, $BS_NOTIFY) $aFormVars[2][1] = "BTNCancel" $aFormVars[5][0] = GUICtrlCreateLabel($TXT_LabelPW, 14, 52, 90, 17, 0) $aFormVars[5][1] = "LabelPW" $aFormVars[6][0] = GUICtrlCreateLabel($TXT_LabelUser, 14, 8, 90, 17, 0) $aFormVars[6][1] = "LabelUser" Return $aFormVars EndFunc ; LogWrite ==================================================================================================================== ; Name ..........: LogWrite ; Description ...: Well , in case you were wondering it writes a log file.... ; Syntax ........: LogWrite($sFunction, $sTxt) ; Parameters ....: $sFunction - a string containing the function who called the logwrite ; $sTxt - a string containing whatever you deem logworthy ; Author ........: Ternal ; =============================================================================================================================== Func LogWrite($sFunction, $sTxt) Local $sFullString = @MDAY & "/" & @MON & "/" & @YEAR & " " & @HOUR & ":" & @MIN & ":" & @SEC & " " & "function " & $sFunction & " reports: " & $sTxt ; create a string with a timestamp ConsoleWrite($sFullString & @CRLF) ; write it to console(because I am still to lazy to go to the actual map an read the txt file.. Local $errorFile = @WorkingDir & "\" & @ScriptName & ".log" ; make a logfilepath string Local $hFileOpen = FileOpen($errorFile, 9) ; create path/ append to end of file params FileWriteLine($hFileOpen, $sFullString & @CRLF) ; write the line FileClose($hFileOpen) ; lets close it EndFunc ;==>LogWrite ; #INTERNAL_USE_ONLY# ==================================================================================================================== ; Description ...: hashes a PW with salt( almost seems like this is cooking rather then programming ain't it?) ; Syntax ........: _HashPW($sUsername, $sPlainTextPW[, $sSalt = Default]) ; Parameters ....: $sUsername - a string containing the user ; $sPlainTextPW - a string containing the pw ; $sSalt - [optional] a string that contains the salt of the pw to has, Default is a new random salt of 20 chars. ; Return values .: 0 on error, array with hash and salt on succes ; Author ........: Ternal ; =============================================================================================================================== Func _HashPW($sUsername, $sPlainTextPW, $sSalt = Default) If $sSalt = Default Then $sSalt = __Randomstring(20) If Not IsString($sPlainTextPW) Then Return SetError(1, 0, 0) If StringLen($sPlainTextPW) < 3 Then Return SetError(2, 0, 0) Local $sUserSalt = StringLower($sUsername); to avoid having case sensitive usernames. _Crypt_Startup() Local $sHash = _Crypt_HashData($sUserSalt & $sSalt & $sPlainTextPW, $CALG_SHA_512) _Crypt_Shutdown() Local $aReturn[2] = [$sHash, $sSalt] Return $aReturn EndFunc ;==>_HashPW ; #INTERNAL_USE_ONLY# ==================================================================================================================== ; Description ...: generates a random string of $length ; Syntax ........: __Randomstring($length) ; Parameters ....: $length - integer containing the length of the string to generate ; Return values .: a random string ; Author ........: PhilRip ; Modified ......: 29/03/2009 ; =============================================================================================================================== Func __Randomstring($length) Local $chars = StringSplit("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", "") Local $String = "" Local $i = 0 Do If $length <= 0 Then ExitLoop $String &= $chars[Random(1, $chars[0])] $i += 1 Until $i = $length Return $String EndFunc ;==>__Randomstring ; #INTERNAL_USE_ONLY# ==================================================================================================================== ; Name ..........: __String2Array ; Description ...: Converts a decrypted string to array ; Syntax ........: __String2Array($sDecryptedString) ; Parameters ....: $sDecryptedString - a string containing the decrypted file ; Return values .: an array of the string ; Author ........: Ternal ; =============================================================================================================================== Func __String2Array($sDecryptedString) Local $aColums ; declare an array to hold each column value for each row Local $aRows = StringSplit($sDecryptedString, ";/\;", 1) ; ;/\; is the delimiter for rows, this splits up the rows in decrypted file string Local $aArray[$aRows[0]][3] ; declare an array big enough to hold all array vars. For $i = 1 To $aRows[0] $aColums = StringSplit($aRows[$i], ";/;", 1) ; ;/; is the delimiter for cells this splits up the colums per row For $j = 1 To $aColums[0] $aArray[$i - 1][$j - 1] = $aColums[$j] ; copy the array info, notice the - 1 , this moves the 1based array to a 0 based array Next Next ReDim $aArray[$aRows[0] - 1][3] ; resize to get rid of the 1-based array from stringsplit, this will now be at the end Return $aArray EndFunc ;==>__String2Array ; #INTERNAL_USE_ONLY# ==================================================================================================================== ; Name ..........: __Array2String ; Description ...: preps an array to be put into encryption as a string. ; Syntax ........: __Array2String($aArray) ; Parameters ....: $aArray - an array of credentials ; Return values .: a string of credentials ; Author ........: Ternal ; =============================================================================================================================== Func __Array2String($aArray) Local $sReturn ; declare return string For $i = 0 To UBound($aArray, 1) - 1 For $j = 0 To UBound($aArray, 2) - 1 $sReturn = $sReturn & $aArray[$i][$j] & ";/;" ; add column delimiters Next $sReturn = StringTrimRight($sReturn, 3) ; delete the last delimiter $sReturn &= ";/\;" ; place a new row delimiter Next Return $sReturn EndFunc ;==>__Array2String ; #INTERNAL_USE_ONLY# ==================================================================================================================== ; Name ..........: __StringEncrypt ; Description ...: function found on autoitForum ; Syntax ........: __StringEncrypt($bEncrypt, $sData, $sPassword) ; Parameters ....: $bEncrypt - a boolean value. ; $sData - a string value. ; $sPassword - a string value. ; Return values .: None ; Author ........: perfaram ?? I forgot the user who made this function, AWFULLY SORRY :/ The person who wrote this deserves all the credits!! ; =============================================================================================================================== Func __StringEncrypt($bEncrypt, $sData, $sPassword) _Crypt_Startup() ; Start the Crypt library. Local $vReturn = '' Local $hKey = _Crypt_DeriveKey(StringToBinary($sPassword), $CALG_AES_256) If $bEncrypt Then ; If the flag is set to True then encrypt, otherwise decrypt. $vReturn = _Crypt_EncryptData($sData, $hKey, $CALG_USERKEY) ; encrypt data Else $vReturn = BinaryToString(_Crypt_DecryptData($sData, $hKey, $CALG_USERKEY)) ; decrypt data EndIf _Crypt_DestroyKey($hKey) _Crypt_Shutdown() ; Shutdown the Crypt library. Return $vReturn EndFunc ;==>__StringEncrypt #EndRegion ##Functions Edited May 1, 2019 by ternal update on script Link to comment Share on other sites More sharing options...
jchd Posted April 27, 2019 Share Posted April 27, 2019 You should never ever store passphrases! Just store the user name and the hash made from login name, passphrase and preferably some salt. Validating input then means collecting login name and pass then checking the resulting hash is correct. ternal 1 This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
ternal Posted April 27, 2019 Author Share Posted April 27, 2019 (edited) First thanks for taking the time to check my script!! So I will alter my script to take a hash of a combination of user and pass and some salt.. And then encrypt the plaintxt user and the hash all together in a file? If I need to check credentials then I would decrypt to memory, check hash from input , compare it to decrypted hash of a certain user, right? Any other remarks? Thanks a lot!! Edited April 27, 2019 by ternal Link to comment Share on other sites More sharing options...
jchd Posted April 27, 2019 Share Posted April 27, 2019 (edited) Yes, correct. Encryption of the file isn't mandatory, unless you insist on keeping names hidden in case some malvolent gets access to the file (users and logins may be distinct or not, depending on your use case). In allmost all cases, this simple scheme is safe enough since you can't be held responsible for passphrase leaking, even if the AutoIt executable is somehow reverse-engineered and the file is copied. Even home-jacking you and your kids isn't an effective way to recover working access: all you can give is file decryption key and salt value, not enough to impersonate any user. Obviously if the context requires very high robustness (keeping the number and identities/logins a secret) then extra measures can be taken, but then it's a completely different story. Yet you can do something to protect names and logins: encrypt them wih the user password just supplied. Your file then just contains a 2D table of meaningless binary data: hash(login & passphrase & salt), crypt(name), crypt(login). This way makes users protect their credentials by their own login/password. That said, a powerful opponent will probably find it easier to compromise physical access to you PC (trojan, hardware) or intercept the network flow at some point in your organization. Edited April 27, 2019 by jchd ternal 1 This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
ternal Posted April 27, 2019 Author Share Posted April 27, 2019 (edited) Hi again, If anyone would like to check my script for security issues( no obligation to anyone!!) feel free. I think this is secure enough for most applications that do not deal with finances. edit = for the script see first post !! Edited May 1, 2019 by ternal Link to comment Share on other sites More sharing options...
jchd Posted April 27, 2019 Share Posted April 27, 2019 I have very little time for reviewing your code and I trust you to be careful. I think you're indeed on the right track, even more as it sin't a highly sensitive military top secret context and no life is threatened! This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe hereRegExp tutorial: enough to get startedPCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta. SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt) Link to comment Share on other sites More sharing options...
ternal Posted May 1, 2019 Author Share Posted May 1, 2019 So a little Bump. I feel fairly confident that the script now is secure enough for offline purposes. I updated the script with some examples how you could use it as an Include.(as a library/header?) First post contains the script, if there are any questions, errors or anything like it please let me know. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now