The QAES_smart_universal_coder is so small that I have added it above the file crypter addon-module
Code: Select all
DeclareModule QAES_smart_universal_coder
Declare QAES_smart_universal_coder(mode, *buffer_in.word, *buffer_out.word, bytes.q, key$, counter_key.q=0, counter_aes.q=0)
UseSHA3Fingerprint()
EndDeclareModule
Module QAES_smart_universal_coder
EnableExplicit
; QAES AES256 OFB mode one or two stage special coder for all things - binarys - strings - text files
; This coder can handle automatic string termination for PB strings in compiler mode ASCII and UNICODE
; The coder works with all data lengths
; With mode ASCII you can encrypt mixed data, string and binary - This ignore the encryption from zero bytes
; The coder go ever forward, a extra decoder is unnecessary !
; You cipher a file blockwise, set ever the current block number (consecutive) with a counter - Important !
; Author Werner Albus - www.nachtoptik.de - www.quick-aes-256.de
; No warranty whatsoever - Use at your own risk
; counter_key.q : You cipher a file blockwise, set ever the current block number with this counter (consecutive numbering)
; counter_aes.q : This counter chance same the counter_key the encryption absolutely
; : The counter_aes you can use as sample for setting a randomized startpoint for using with the file coder addon protection function
; : With used counters and salt you can personalize the coder, nobody can brute force a password from a unknown personalized coder
; : You can set the counter as quad, positive and negative
; key$ : You can use any strings as key
; *buffer_in : Set the adress to the source data
; *buffer_out : Set the adress to the destination data - Hint : It can also are the same place as the plain data
; mode : Set mode=0 for binary files - Set mode=1 for ASCII strings - Set mode=2 for UNICODE strings
Procedure QAES_smart_universal_coder(mode, *buffer_in.word, *buffer_out.word, bytes.q, key$, counter_key.q=0, counter_aes.q=0)
If Not bytes.q Or key$="" : ProcedureReturn 0 : EndIf
#Salt$="t8690352cj2p1ch7fgw34u&=)?=)/%&§/&)=?(otmq09745$%()=)&%" ; Salt, you can change
Protected.q i, swap_, rounds.q=bytes>>4
Protected ii, iii, bytes_minus_x, stepp=SizeOf(character)<<1
Protected *register_asc.ascii, *register.word, *buffer_in_quad.quad, *buffer_out_quad.quad
Protected rest=bytes%16, bytes_minus_1=bytes-1
Protected *buffer_in_asc.ascii, *buffer_out_asc.ascii
Protected hash$=#Salt$+key$+Str(counter_key)+ReverseString(#Salt$)
Static fixed_key_string${64}
Static Dim register.q(3)
fixed_key_string$=Fingerprint(@hash$, StringByteLength(hash$), #PB_Cipher_SHA3, 256) ; Create a key
For ii = 0 To 31 : PokeA(@register(0)+ii, Val("$"+PeekS(@fixed_key_string$+iii, 2))) : iii+stepp : Next
register(1)+counter_aes
Macro go_1 ; One stage
register(0)+1
If Not AESEncoder(@register(0), @register(0), 32, @register(0), 256, 0, #PB_Cipher_ECB) : ProcedureReturn 0 : EndIf
swap_=register(0) : register(0)=register(3) : register(3)=swap_ ; Never use here
swap_=register(1) : register(1)=register(2) : register(2)=swap_ ; the PB swap function !
; register(2)+1 ; Activate for two stage crypting
; If Not AESEncoder(@register(0), @register(0), 32, @register(0), 256, 0, #PB_Cipher_ECB) : ProcedureReturn 0 : EndIf
EndMacro
If Not mode ; Binary mode
*buffer_in_quad.quad=*buffer_in.word : *buffer_out_quad.quad=*buffer_out.word
If bytes<16 ; Less 16 bytes
*buffer_out_asc=*buffer_out_quad : *buffer_in_asc=*buffer_in_quad : *register_asc=@register(0)
go_1
For ii=0 To bytes_minus_1
*buffer_out_asc\a=*buffer_in_asc\a ! *register_asc\a : *buffer_in_asc+1 : *buffer_out_asc+1 : *register_asc+1
Next
ProcedureReturn 1
EndIf
While i<rounds ; =>16 bytes
go_1
*buffer_out_quad\q=*buffer_in_quad\q ! register(0) : *buffer_in_quad+8 : *buffer_out_quad+8
*buffer_out_quad\q=*buffer_in_quad\q ! register(1) : *buffer_in_quad+8 : *buffer_out_quad+8 : i+1
Wend
If rest
*buffer_out_asc=*buffer_out_quad : *buffer_in_asc=*buffer_in_quad : *register_asc=@register(0)
go_1
For ii=0 To rest-1
*buffer_out_asc\a=*buffer_in_asc\a ! *register_asc\a : *buffer_in_asc+1 : *buffer_out_asc+1 : *register_asc+1
Next
EndIf
ElseIf mode=1
bytes_minus_x=bytes-2
*buffer_in_asc=*buffer_in : *buffer_out_asc=*buffer_out
Repeat
go_1 : *register_asc=@register(0)
For ii=0 To 15
If *buffer_in_asc\a And *buffer_in_asc\a ! *register_asc\a
*buffer_out_asc\a=*buffer_in_asc\a ! *register_asc\a
Else
*buffer_out_asc\a=*buffer_in_asc\a
EndIf
If i>bytes_minus_x : Break 2 : EndIf
*buffer_in_asc+1 : *buffer_out_asc+1 : *register_asc+1 : i+1
Next ii
ForEver
Else ; mode=2
bytes_minus_x=bytes-3
Repeat
go_1 : *register.word=@register(0)
For ii=0 To 15 Step 2
If *buffer_in\w And *buffer_in\w ! *register\w
*buffer_out\w=*buffer_in\w ! *register\w
Else
*buffer_out\w=*buffer_in\w
EndIf
If i>bytes_minus_x : Break 2 : EndIf
*buffer_in+2 : *buffer_out+2 : *register+2 : i+2
Next ii
ForEver
EndIf
ProcedureReturn 1
EndProcedure
EndModule
UseModule QAES_smart_universal_coder
; ===== File coder addon for the universal AES256 based QAES_smart_universal_coder =====
DeclareModule QAES_smart_file_coder
UseModule QAES_smart_universal_coder
Declare.s QAES_smart_file_coder(mode, window_ID, progressbar_ID, path_1$, key_1$, file_extender$="", set_counter_protection_mode.q=0)
Declare QAES_get_cryptextender_length()
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Declare FixWriteData(file, *adress, length) ; Workaround for Linux PB 560
CompilerEndIf
EndDeclareModule
Module QAES_smart_file_coder
; Smart file crypting addon or the QAES_smart_universal_coder
; Its nice you set a hint in your software for using QAES contents
; This addon can protect or encrypt and decrypt files using the QAES_smart_universal_coder module
; The encrypted files do not have visible headers or extenders
; Works with all file lengths
; No separate decrypter necessary
; With integrated full automatic working crypt randomized counter
; With full automatic file integrity check
; Can full automatic check whether a file is encrypted
; Various files with the same content are encrypted ever completely differently
; Author Werner Albus - www.nachtoptik.de - www.quick-aes-256.de
; No warranty whatsoever - Use at your own risk
EnableExplicit
Global cryptextender_length
Procedure QAES_get_cryptextender_length()
ProcedureReturn cryptextender_length
EndProcedure
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
Procedure FixWriteData(file, *adress, length) ; Workaround for Linux PB560
Protected write_data_pointer=Loc(file)
Protected writen_data=WriteData(file, *adress, length)
FileSeek(file, write_data_pointer+writen_data)
ProcedureReturn writen_data
EndProcedure
Macro WriteData(File, Buffer, Size)
FixWriteData(File, Buffer, Size)
EndMacro
CompilerEndIf
Procedure.s QAES_smart_file_coder(mode, window_ID, progressbar_ID, path_1$, key_1$, file_extender$="", set_counter_protection_mode.q=0)
; mode=0 - Full automatic mode with file selectors
; mode=1 - Encrypt or add a file protection
; mode=2 - Decrypt or remove a file protection
; mode=3 - Check the file integrity
; mode=4 - Check if a file is already encrypted or protected
; set_counter_protection_mode <> 0 - activate the file protection mode
; This protect a file, but dont encrypt the file
; Mostly files you can normaly use protected
; Set on this variable your defined counter_aes from the universal crypter
; If not window_ID or not progressbar_ID, you become not a progressbar
; A empty key (Password) open automatically a string selector
; CompilerIf #PB_Compiler_Debugger : MessageRequester("Debugger", "Please deactivate firstly the debugger !") : ProcedureReturn "" : CompilerEndIf
#HashLength=256 ; (224, 256, 384, 512) You can use all available hash lengths divisible by 2 and also different hashes
#Salt$="59#ö#3:_,.45ß$/($(/=)?=JjB$§/(&=$?=)((/&)%WE/()T&%z#'" ; Salt - You can change
cryptextender_length=8+8+#HashLength>>3
restart:
Protected path$="", hash$, key$, message$, method_0$, method__0$, method___0$
Protected method_1$, method__1$, method___1$, hash_1$="", key_2$, hash_2$=""
Protected file, readed, writen=0, check_integrity=0, file_broken=0, block_size, window_event, result
Protected progressbar_state, encrypted_file_found=0, hash_bytes, i, key_presetted, blocks, rest, block_counter=0
Protected file_size.q, get_counter.q, get_magic.q, counter.q, counter_0.q, magic.q
Protected counter_1.q=345645758512426756724 ; Preset startpoint counter 1 - You can change
Protected Dim hash.q(#HashLength>>3-1)
Protected *buffer
If set_counter_protection_mode
counter=set_counter_protection_mode
magic.q=275390641757985374251 ; Preset protected marker - You can change
method_0$=" protected " : method__0$=" protect "
method_1$=" unprotected " : method__1$=" unprotect "
Else
If OpenCryptRandom() : CryptRandomData(@counter, 8) : Else : RandomData(@counter, 8) : EndIf
If Not counter
If Not mode
MessageRequester("ERROR", "Can not create counter")
Else
ProcedureReturn "ERROR ##01QF - Can not create counter !"
EndIf
ProcedureReturn ""
EndIf
magic.q=415628580943792148170 ; Preset crypt marker - You can change
method_0$=" encrypted " : method__0$=" encrypt " : : method___0$=" crypting "
method_1$=" decrypted " : : method__1$=" decrypt "
EndIf
If *buffer : FreeMemory(*buffer) : *buffer=0 : EndIf
If mode Or path_1$<>"" : path$=path_1$ : path_1$="" : EndIf
If IsWindow(window_ID) : progressbar_state=1 : EndIf
If IsGadget(progressbar_ID) : SetGadgetState(progressbar_ID, 0) : progressbar_state+1 : EndIf
If Len(Fingerprint(@magic, 8, #PB_Cipher_SHA3, #HashLength))<>#HashLength>>2 ; Test Fingerprint
If Not mode
MessageRequester("ERROR", "Fingerprint fails")
Else
ProcedureReturn "ERROR ##02QF - Fingerprint fails !"
EndIf
ProcedureReturn ""
EndIf
If key_1$=""
key_1$=InputRequester("", "Set firstly a password !", "")
If key_1$="" : ProcedureReturn "" : EndIf
Else
key_presetted=1
EndIf
key$=ReverseString(#Salt$)+key_1$+#Salt$+ReverseString(key_1$) : key_2$=key_1$ : key_1$=""
QAES_smart_universal_coder(0, @magic, @magic, 8, #Salt$+ReverseString(key$)+Str(magic)+key$)
If Not mode And path$=""
path$=OpenFileRequester("Select a file to"+method___0$, "", "*.*", 0)
If path$="" : ProcedureReturn "" : EndIf
EndIf
file_size=FileSize(path$)
If file_size<0
If Not mode
MessageRequester("ERROR", "File not found")
Goto restart
Else
ProcedureReturn "ERROR ##03QF - File not found !"
EndIf
ElseIf Not file_size
If Not mode
MessageRequester("ERROR", "This is a zero length file"+#CRLF$+#CRLF$+"Can not"+method__0$+"files without a content")
Goto restart
Else
ProcedureReturn "ERROR ##04QF - This is a zero length file - Can not"+method__0$+"files without a content !"
EndIf
EndIf
file=OpenFile(#PB_Any, path$)
If file
block_size=4096<<2 : FileBuffersSize(file, block_size ) : *buffer=AllocateMemory(block_size)
If file_size<cryptextender_length+1
If mode>1
CloseFile(file)
ProcedureReturn "ERROR ##05QF - This is not a"+method_0$+" file !"
Else
Goto encrypt_1
EndIf
EndIf
FileSeek(file, file_size-cryptextender_length)
ReadData(file, @get_counter, 8)
ReadData(file, @get_magic, 8)
ReadData(file, @hash(0), #HashLength>>3)
FileSeek(file, 0)
QAES_smart_universal_coder(0, @get_counter, @get_counter, 8, ReverseString(key$)+key$+#salt$) ; QAES crypter - Try decrypt counter
QAES_smart_universal_coder(0, @hash(0), @hash(0), #HashLength>>3, key$+ReverseString(key$), get_counter) ; QAES crypter - Try decrypt hash
QAES_smart_universal_coder(0, @get_magic, @get_magic, 8, ReverseString(key$)+key$, get_counter) ; QAES crypter - Try decrypt magic
If get_magic=magic
If mode=1
CloseFile(file)
ProcedureReturn "HINT ##06QF - This is a valid"+method_0$+"file !"
ElseIf mode=3
check_integrity=1
ElseIf mode=4
CloseFile(file)
ProcedureReturn "ALLok ##07QF - File checked - This is a valid"+method_0$+"file !"
ElseIf Not mode
result=MessageRequester("HINT", "This is a valid"+method_0$+"file !"+#CRLF$+#CRLF$+
"Want to"+method__1$+"the file now ? - Select Yes"+#CRLF$+#CRLF$+
"Just want to check the integrity of the file ? - Select Cancel"+#CRLF$+#CRLF$+
"Want to select another file ? - Select No", #PB_MessageRequester_YesNoCancel)
If result=#PB_MessageRequester_Cancel
key_1$=key_2$
check_integrity=1
ElseIf result=#PB_MessageRequester_No
key_1$=key_2$
CloseFile(file)
Goto restart
EndIf
EndIf
encrypted_file_found=1 : counter_0=get_counter
For i = 0 To #HashLength>>3-1 : hash_2$+RSet(Hex(PeekA(@hash(0)+i)), 2, "0") : Next i : hash_2$=LCase(hash_2$)
Else
If mode>1
CloseFile(file)
ProcedureReturn "HINT ##08QF - File checked - This is not a valid"+method_0$+"file - Or your key is wrong !"
EndIf
encrypt_1:
If Not mode
message$="This file looking not valid"+method_0$+"!"+#CRLF$+#CRLF$+
"It is also possible that your password is wrong"+#CRLF$+#CRLF$+
"Or it is possible that it is a corrupted"+method_0$+"file"+#CRLF$+#CRLF$+
"Want to"+method__0$+"this file now with your password ? - Select Yes"+#CRLF$+#CRLF$+
"Want to select another file ? - Select No"
If key_presetted
result=MessageRequester("HINT", message$, #PB_MessageRequester_YesNo)
Else
result=MessageRequester("HINT", message$+#CRLF$+#CRLF$+"To change your password - Select Cancel", #PB_MessageRequester_YesNoCancel)
EndIf
If result=#PB_MessageRequester_No
key_1$=key_2$
CloseFile(file) : Goto restart
ElseIf result=#PB_MessageRequester_Cancel
CloseFile(file) : key$="" : Goto restart
EndIf
EndIf
QAES_smart_universal_coder(0, @magic, @magic, 8, ReverseString(key$)+key$, counter) ; QAES crypter - Encrypt magic
counter_0=counter
EndIf
Else
If Not mode
MessageRequester("ERROR", "Can not open file")
Goto restart
Else
ProcedureReturn "ERROR ##09QF - Can not open file !"
EndIf
EndIf
If IsWindow(window_ID)
AddWindowTimer(window_ID, window_ID, 30)
EndIf
If progressbar_state=2 : SetGadgetState(progressbar_ID, 0) : EndIf
blocks=(file_size-cryptextender_length)/block_size
rest=file_size-(block_size*blocks)
If encrypted_file_found
rest-cryptextender_length
EndIf
Repeat
readed=ReadData(file, *buffer, block_size)
If encrypted_file_found
hash_bytes=readed-cryptextender_length
If readed=block_size : hash_bytes=readed : EndIf
If hash_bytes>0
block_counter+1
If blocks
If block_counter>blocks : hash_bytes=rest : EndIf
Else
hash_bytes=file_size-cryptextender_length
EndIf
hash$=Fingerprint(*buffer, hash_bytes, #PB_Cipher_SHA3, #HashLength)
hash$+key$+hash_1$+Str(counter_0)
hash$=Fingerprint(@hash$, StringByteLength(hash$), #PB_Cipher_SHA3, #HashLength)
hash_1$=hash$
EndIf
EndIf
If Not check_integrity And Not set_counter_protection_mode
QAES_smart_universal_coder(0, *buffer, *buffer, block_size, key$, counter_0, counter_1) ; QAES crypter
EndIf
If Not encrypted_file_found
If readed>0
hash$=Fingerprint(*buffer, readed, #PB_Cipher_SHA3, #HashLength)
hash$+key$+hash_1$+Str(counter_0)
hash$=Fingerprint(@hash$, StringByteLength(hash$), #PB_Cipher_SHA3, #HashLength)
hash_1$=hash$
EndIf
EndIf
If check_integrity
writen+readed
Else
FileSeek(file, -readed, #PB_Relative) : writen+WriteData(file, *buffer, readed)
EndIf
If progressbar_state
window_event=WindowEvent()
EndIf
If progressbar_state=2 And window_event=#PB_Event_Timer And EventTimer()=window_ID
SetGadgetState(progressbar_ID, 100*writen/file_size)
EndIf
counter_0+1 : counter_1+1
Until Not readed
If progressbar_state=2 : SetGadgetState(progressbar_ID, 100) : EndIf
hash$+key$+#Salt$ ; Finishing fingerprint
hash$=LCase(Fingerprint(@hash$, StringByteLength(hash$), #PB_Cipher_SHA3, #HashLength))
If encrypted_file_found And hash$<>hash_2$
If check_integrity
CloseFile(file) : FreeMemory(*buffer) : *buffer=0
If Not mode
If MessageRequester("WARNING", "File hash broken !"+#CRLF$+#CRLF$+
"Want to use the file coder again ? - Select Yes",
#PB_MessageRequester_YesNo)=#PB_MessageRequester_No
ProcedureReturn ""
EndIf
Goto restart
Else
ProcedureReturn "WARNING ##10QF - File hash broken ! - Used counter =>"+Str(get_counter)
EndIf
Else
file_broken=1
EndIf
EndIf
If check_integrity
CloseFile(file) : FreeMemory(*buffer) : *buffer=0
If Not mode
SetClipboardText(GetFilePart(path$)+#CRLF$+hash_2$)
If MessageRequester("HINT", "All OK !"+#CRLF$+#CRLF$+"File integrity succesfully checked !"+#CRLF$+#CRLF$+
"I put now the file hash and name in your clipboard"+#CRLF$+#CRLF$+hash_2$+#CRLF$+#CRLF$+
"Want to use the file coder again ? - Select Yes",
#PB_MessageRequester_YesNo)=#PB_MessageRequester_Yes
Goto restart
EndIf
Else
ProcedureReturn "ALLok ##11QF - File integrity succesfully checked ! - Used counter =>"+Str(get_counter)+" - File hash ==>"+hash_2$
EndIf
ProcedureReturn ""
EndIf
If Not encrypted_file_found
For i=0 To #HashLength>>3-1 : PokeA(@hash(0)+i, Val("$"+PeekS(@hash$+i*SizeOf(character)<<1, 2))) : Next i
QAES_smart_universal_coder(0, @hash(0), @hash(0), #HashLength>>3, key$+ReverseString(key$), counter) ; QAES crypter - Crypt hash
QAES_smart_universal_coder(0, @counter, @counter, 8, ReverseString(key$)+key$+#salt$) ; QAES crypter - Crypt counter
writen+WriteData(file, @counter, 8)
writen+WriteData(file, @magic, 8)
writen+WriteData(file, @hash(0), #HashLength>>3)
If writen<>file_size+cryptextender_length
CloseFile(file) : FreeMemory(*buffer)
If Not mode
MessageRequester("ERROR", "Writen fails"+#CRLF$+#CRLF$+"Writen Bytes : "+Str(writen))
Else
ProcedureReturn "ERROR ##12QF - Writen fails - Writen Bytes : "+Str(writen)+" !"
EndIf
ProcedureReturn ""
EndIf
EndIf
If encrypted_file_found
FileSeek(file, -cryptextender_length, #PB_Relative)
TruncateFile(file)
If Lof(file)<>file_size-cryptextender_length
CloseFile(file) : FreeMemory(*buffer)
If Not mode
MessageRequester("ERROR", "Truncate file fails")
Else
ProcedureReturn "ERROR ##13QF - Truncate file fails !"
EndIf
ProcedureReturn ""
EndIf
EndIf
CloseFile(file)
If file_extender$<>""
If encrypted_file_found And Right(path$, Len(file_extender$))=file_extender$
RenameFile(path$, Left(path$, Len(path$)-Len(file_extender$)))
Else
If Not encrypted_file_found
RenameFile(path$, path$+file_extender$)
EndIf
EndIf
EndIf
If file_broken
If Not mode
message$="WARNING - File"+method_1$+"but file hash broken !"
Else
message$="WARNING ##14QF - File"+method_1$+"but file hash broken !"
EndIf
Else
If encrypted_file_found
If Not mode
message$="All OK - File"+method_1$+"!"+#CRLF$+#CRLF$+
"I put now the file hash and name in your clipboard"+#CRLF$+#CRLF$+hash_2$
SetClipboardText(GetFilePart(path$)+#CRLF$+hash_2$)
Else
message$="ALLok ##15QF - File"+method_1$+" ! - Used counter =>"+Str(get_counter)+" - File hash ==>"+hash_2$
EndIf
Else
If Not mode
message$="ALL OK - File "+method_0$+#CRLF$+#CRLF$+
"I put now the file hash and name in your clipboard"+#CRLF$+#CRLF$+hash$
SetClipboardText(GetFilePart(path$)+#CRLF$+hash$)
Else
message$="ALLok ##16QF - File"+method_0$+" ! - File hash ==>"+hash$
EndIf
EndIf
EndIf
If Not mode
If MessageRequester("HINT", message$+#CRLF$+#CRLF$+
"Want to use the file coder again ?",
#PB_MessageRequester_YesNo)=#PB_MessageRequester_Yes
key_1$=key_2$
Goto restart
EndIf
EndIf
FreeMemory(*buffer)
ProcedureReturn message$
EndProcedure
EndModule
UseModule QAES_smart_file_coder
; ===================== Using the file crypt Addon ===============================
EnableExplicit
Define mode, window_ID, progressbar_ID , key$, path_0$, path_1$
; mode=0 - Full automatic mode with file selectors
; mode=1 - Encrypt
; mode=2 - Decrypt
; mode=3 - Check the file integrity
; mode=4 - Check if a file is already encrypted
; If not window_ID or not progressbar_ID, you get not a progressbar
; A empty key (Password) open automatically a string selector
#cryptfile_extender$=" [encrypted]" ; You can change how ever you want
; Automatic mode
key$=""
window_ID=OpenWindow(#PB_Any, 0, 0, 280, 50, "QAES smart universal coder", #PB_Window_ScreenCentered)
progressbar_ID=ProgressBarGadget(#PB_Any, 10, 10, 260, 30, 0, 100, #PB_ProgressBar_Smooth)
QAES_smart_file_coder(0, window_ID, progressbar_ID, "", key$, #cryptfile_extender$)
; Manual modes
; key$="This is a pre defined test key"
; path_0$=GetTemporaryDirectory()+"TestPic.jpg" ; Create a little picture for test
; path_1$=path_0$+#cryptfile_extender$
; UseJPEGImageEncoder()
; SaveImage(CreateImage(#PB_Any, 10, 10), path_0$, #PB_ImagePlugin_JPEG)
; Debug QAES_smart_file_coder(1, window_ID, progressbar_ID, path_0$, key$, #cryptfile_extender$) ; Encrypt a file
; Debug QAES_smart_file_coder(4, window_ID, progressbar_ID, path_1$, key$, #cryptfile_extender$) ; Check if the file is already valid encrypted
; Debug QAES_smart_file_coder(3, window_ID, progressbar_ID, path_1$, key$, #cryptfile_extender$) ; Check the file integrity
; Debug QAES_smart_file_coder(2, window_ID, progressbar_ID, path_1$, key$, #cryptfile_extender$) ; Decrypt a file
ALLok ##16QF - File encrypted - File hash ==>f3c11d468f74e52112939f471da8e0b36c68ad0880c6dd2b27c7a82fb8bfddbb
ALLok ##10QF - File integrity succesfully checked - File hash ==>f3c11d468f74e52112939f471da8e0b36c68ad0880c6dd2b27c7a82fb8bfddbb
ALLok ##14QF - File decrypted - File hash ==>f3c11d468f74e52112939f471da8e0b36c68ad0880c6dd2b27c7a82fb8bfddbb