Man findet an sich wenig was ohne weiteres Zutun voll lauffähig und als Source verfügbar ist
Dieser Crypter kann Dateien ohne Größenlimit verschlüsseln
Die verschlüsselten Dateien sind selbstüberwachend, sie können nicht manipuliert werden
Es gibt keine erkennbaren oder explorierbaren Header oder Extender
Die erzeugten Dateien sind bis auf Bit Ebene verschieden, selbst wenn die Quelle in Gänze oder Teilen identisch ist
Auch die Dateilänge der verschlüsselten Dateien wird randomisiert
Der Coder basiert auf dem enthaltenen QAES_smart_universal_coder Modul
Dieses Modul kann auch Null terminierte Strings verschlüsseln, ohne sie zu beschädigen, was oftmals als großes oder gar unlösbares Problem beschrieben wird
Der Code ist in PureBasic (PB) erstellt
PureBasic kann als Test Version von der Webseite purearea.net geladen werden
Speichert diesen Code, zB, einfach als ascii Text und ändert die Datei Extension zu .pb
Dies kann man dann einfach mit drag & drop in den Editor von PB ziehen und mit F5 starten
Mehr ist nicht notwendig.
Viel Spaß damit
Anmerkung : Unten habe ich noch einen stark vereinfachten Base Code für beliebige Anwendung angehängt
Full Featured code
Code: Alles auswählen
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 two stage special coder for all things - binarys - strings - text files -----
; This coder can handle automatic string termination for any strings - In compiler mode ASCII and UNICODE !
; The coder works with all data lengths, also <!6 bytes
; mode=0 - Mode BINARY, you can encrypt binary data, use this not for on demand string encryption, it break the string termination
; mode=1 - Mode ASCII, you can encrypt mixed data, string and binary - This ignore the encryption from zero bytes, recommended for mixed datea with ASCII strings
; mode=2 - Mode UNICODE, you can encrypt mixed data, ascii strings, unicode strings and binary - This ignore the encryption from zero bytes
; The coder go ever forward, a extra decoder is unnecessary, use for encrypting and decrypting exactely the same call !
; You cipher a file blockwise, set ever the current block number (consecutive) with the counter - Important, then the result look similar CBC mode encrypting !
; Author Werner Albus - www.nachtoptik.de
; No warranty whatsoever - Use at your own risk
; PureBasic
; counter_key.q : You cipher a file blockwise, set ever the current block number with this counter (consecutive numbering)
; counter_aes.q : This counter use the coder automatic, but you can change the startpoint, this 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
#EnlargeFIleLengthBytes=128 ; You can change
#RandomizeFileLengthBytes=256 ; This feature change full automatic and randomized the length from any encrypted files
restart:
Protected cryptextender_length=8+8+8+#HashLength>>3
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, fake_length.q, get_fake_length.q, get_counter.q, counter.q, counter_0.q, get_magic.q, magic.q
Protected crypt_random.c, set_fake_length.q, set_fake_length_1.q, counter_1.q=345645758512426756724 ; Preset startpoint counter 1 - You can change
Protected Dim hash.q(#HashLength>>3-1)
Protected *buffer, *fake_content
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() : crypt_random=1 : CryptRandomData(@counter, 8) : Else : crypt_random=0 : RandomData(@counter, 8) : EndIf
set_fake_length.q=CryptRandom(#RandomizeFileLengthBytes)+#EnlargeFIleLengthBytes
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
; ; Tweak the OS progressbar :)
; progressbar_ex(progressbar_ID, 0, 0, $FFFF)
; 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$=""
select_again:
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 select_again
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 select_again
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_fake_length, 8)
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_fake_length, @get_fake_length, 8, key$+ReverseString(key$)) ; QAES crypter - Try decrypt fake length
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
cryptextender_length+get_fake_length
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 select_again
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
*fake_content=AllocateMemory(set_fake_length)
If Not *fake_content : set_fake_length=0 : set_fake_length_1=0 : EndIf
set_fake_length_1=set_fake_length
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, @set_fake_length_1, @set_fake_length_1, 8, key$+ReverseString(key$)) ; QAES crypter - Crypt fake length
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
If Not *fake_content : set_fake_length=0 : set_fake_length_1=0 : EndIf
If set_fake_length
If crypt_random
CryptRandomData(*fake_content, set_fake_length)
Else
RandomData(*fake_content, set_fake_length)
EndIf
QAES_smart_universal_coder(0, *fake_content, *fake_content, set_fake_length, key$)
EndIf
writen+WriteData(file, *fake_content, set_fake_length)
If *fake_content : FreeMemory(*fake_content) : EndIf
writen+WriteData(file, @set_fake_length_1, 8)
writen+WriteData(file, @counter, 8)
writen+WriteData(file, @magic, 8)
writen+WriteData(file, @hash(0), #HashLength>>3)
If writen<>file_size+cryptextender_length+set_fake_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 become 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
Code: Alles auswählen
;- QAES AES256 OFB mode two stage special coder for all things - binarys - strings - text files -----
; This coder can handle automatic string termination for any strings - In compiler mode ASCII and UNICODE !
; The coder works with all data lengths, also <!6 bytes
; 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 the counter - Important !
; Author Werner Albus - www.nachtoptik.de
; No warranty whatsoever - Use at your own risk
; Purebasic
DeclareModule QAES_smart_universal_coder
Declare QAES_smart_universal_coder(mode, *buffer_in.word, *buffer_out.word, bytes.q, key$, counter.q=0)
EndDeclareModule
Module QAES_smart_universal_coder
EnableExplicit
UseSHA3Fingerprint()
Procedure QAES_smart_universal_coder(mode, *buffer_in.word, *buffer_out.word, bytes.q, key$, counter.q=0)
If Not bytes.q Or key$="" : ProcedureReturn 0 : EndIf
Protected.q i, swap_
Protected ii, iii, bytes_minus_x, stepp=SizeOf(character)<<1
Protected *buffer_in_asc.ascii, *buffer_out_asc.ascii
Protected hash$=key$+Str(counter)+"t8690352cj2p1ch7fgw34uotmq09745$%()=)&%" ; + Salt, you can change
Static fixed_key_string${64}
Static Dim register.q(3)
fixed_key_string$=Fingerprint(@hash$, StringByteLength(hash$), #PB_Cipher_SHA3, 256)
If mode=2
bytes_minus_x=bytes-3
Else
bytes_minus_x=bytes-2
*buffer_in_asc.ascii=*buffer_in
*buffer_out_asc.ascii=*buffer_out
EndIf
For ii = 0 To 31 : PokeA(@register(0)+ii, Val("$"+PeekS(@fixed_key_string$+iii, 2))) : iii+stepp : Next ; Create a key
Repeat
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 !
If Not AESEncoder(@register(0), @register(0), 16, @register(0), 256, 0, #PB_Cipher_ECB) : ProcedureReturn 0 : EndIf
If mode=2
Protected *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
ElseIf mode=1
Protected *register_asc.ascii=@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
Else
*register_asc.ascii=@register(0)
For ii=0 To 15
*buffer_out_asc\a=*buffer_in_asc\a ! *register_asc\a
If i>bytes_minus_x : Break 2 : EndIf
*buffer_in_asc+1 : *buffer_out_asc+1 : *register_asc+1 : i+1
Next ii
EndIf
ForEver
ProcedureReturn 1
EndProcedure
EndModule
UseModule QAES_smart_universal_coder
; ============== AES256 OFB mode two stage special coder - For binarys, text and strings =================
; ; counter.q : You cipher a file blockwise, set ever the current block number (consecutive numbering) - This is important !
; ; : You can set the counter as quad, positive and negative
; ; key$ : You can use any strings as key
; ; @text$ / @string_result$ : Set a pointer to the source data
; ; @string_result$ : 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
;
; ; A sample : QAES_smart_universal_coder(mode_ascii_or_unicode, *source_data, *destination_data, length_of_data, key$, counter)
;
; counter=123456
; string$="The quick brown fox jumps over the lazy dog"
; string$="A"+RSet("Z", 50, "x") ; Demo text string to encryption - For unicode, the length from 1 char = 2 bytes !
; key$="This is a simple key"
; ; mode=2 ; UNICODE
; mode=SizeOf(character)
;
; ; Encoding
; QAES_smart_universal_coder(mode, @string$, @string$, StringByteLength(string$), key$, counter)
; Debug "QAES smart universal coder : Encoded : "+string$
; ShowMemoryViewer(@string$,StringByteLength(string$))
; Debug ""
; ; Decoding
; QAES_smart_universal_coder(mode, @string$, @string$, StringByteLength(string$), key$, counter)
; Debug "QAES smart text coder : Decoded : "+string$
;-----------------------------------
mode=SizeOf(character)
path$ = OpenFileRequester("Select a file to encrypting or decrypting !", "", "*.*", 0)
file=OpenFile(#PB_Any, path$)
If file
*buffer=AllocateMemory(Lof(file))
ReadData(file, *buffer, MemorySize(*buffer))
QAES_smart_universal_coder(mode, *buffer, *buffer, MemorySize(*buffer), "Your key")
FileSeek(file, 0) : WriteData(file, *buffer, MemorySize(*buffer)) : CloseFile(file)
EndIf