The fastest possible solution for large files which doesn't inflate them further
This is how a small crypter was created that works as an addon based on the QAES_universal_smart_coders
The generated files are encrypted similar to CBC mode, with randomized IV
I don't think it has ever been possible with PB to do this so easily and effectively
Well, now it's available ...
There is no problem that cannot be easy solved with QAES_smart_universal_coder
Code: Select all
;- 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 - www.quick-aes-256.de
; No warranty whatsoever - Use at your own risk
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()
;- QAES AES256 OFB mode 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 the counter - Important !
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
; =======================================================================
; String to file crypter module
; Addon for the QAES_smart_universal_coder
DeclareModule QAES_StringToFileCrypter
UseModule QAES_smart_universal_coder
Declare create_encrypted_string_file(string$, destination_path_csv$, key$)
Declare.s read_encrypted_string_file(destination_path_csv$, key$)
EndDeclareModule
Module QAES_StringToFileCrypter
EnableExplicit
Procedure create_encrypted_string_file(string$, destination_path_csv$, key$)
; Create a encryoted string file
Protected file=CreateFile(#PB_Any, destination_path_csv$)
If file
Protected counter.q
If OpenCryptRandom()
CryptRandomData(@counter, 8)
Else
RandomData(@counter, 8)
EndIf
Protected *buffer=Ascii(string$)
If Not *buffer : ProcedureReturn 0 : EndIf
If Not QAES_smart_universal_coder(0, *buffer, *buffer, MemorySize(*buffer), key$, counter)
FreeMemory(*buffer) : ProcedureReturn 0
EndIf
If WriteData(file, *buffer, MemorySize(*buffer))<>MemorySize(*buffer)
FreeMemory(*buffer) : ProcedureReturn 0
EndIf
FileSeek(file, Lof(file))
If WriteQuad(file, counter)<>8 : FreeMemory(*buffer) : ProcedureReturn 0 : EndIf
CloseFile(file)
FreeMemory(*buffer)
Else
ProcedureReturn 0
EndIf
ProcedureReturn 1
EndProcedure
Procedure.s read_encrypted_string_file(destination_path_csv$, key$)
; Read a encrypted string file
Protected file=ReadFile(#PB_Any, destination_path_csv$)
If Not file : ProcedureReturn "" : EndIf
Protected *buffer=AllocateMemory(Lof(file))
If Not *buffer : ProcedureReturn "" : EndIf
If file
Protected counter.q
FileSeek(file, Lof(file)-8)
counter=ReadQuad(file)
FileSeek(file, 0)
If ReadData(file, *buffer, Lof(file))<>Lof(file) : FreeMemory(*buffer) : EndIf
FileSeek(file, 0)
If Not QAES_smart_universal_coder(0, *buffer, *buffer, MemorySize(*buffer), key$, counter)
FreeMemory(*buffer) : ProcedureReturn ""
EndIf
Protected string$=PeekS(*buffer , -1, #PB_Ascii )
CloseFile(file)
Else
ProcedureReturn ""
EndIf
If *buffer : FreeMemory(*buffer) : EndIf
ProcedureReturn string$
EndProcedure
EndModule
UseModule QAES_StringToFileCrypter
; =======================================================================
EnableExplicit
Define destination_path_csv$=GetUserDirectory(#PB_Directory_Desktop)+"/Testfile"
Define key$= "this is the key"
Define string$="The quick brown fox jumps over the lazy dog 0123456789"
; Create a encrypted string file -----------------
Debug create_encrypted_string_file(string$, destination_path_csv$, key$)
; Read a encrypted string file ----------------
Debug read_encrypted_string_file(destination_path_csv$, key$)