The Crypter is AES-256 based, very fast, simplest to use, rock stable and does not create any temporary files.
The crypter always creates completely different encrypted files from the same texts.
This works similar to the CBC mode with a continuously changing IV.
But it does not have the weaknesses of CBC encryption.
For easy further processing, the decrypter provides the file directly line by line in a list.
He can be more than helpful
Code: Select all
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 !
; Author Werner Albus - www.nachtoptik.de - www.quick-aes-256.de
; No warranty whatsoever - Use at your own risk
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 - make not to small
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 !
; Dual crypting, you can activate, but you must not
; 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
; =======================================================================
; Text to file crypter module
; Addon for the QAES_smart_universal_coder
DeclareModule QAES_TextToFileCrypter
UseModule QAES_smart_universal_coder
Declare create_encrypted_file(template_path_csv$, destination_path_csv$, key$)
Declare read_encrypted_file(destination_path_csv$, List result.s(), key$)
EndDeclareModule
Module QAES_TextToFileCrypter
EnableExplicit
Procedure create_encrypted_file(template_path_csv$, destination_path_csv$, key$)
Protected file=ReadFile(#PB_Any, template_path_csv$), *buffer, file_length.q=Lof(file), buffer_length.q
If Not file : ProcedureReturn -1 : EndIf
*buffer=AllocateMemory(file_length+16) : buffer_length=(MemorySize(*buffer))
If Not *buffer : CloseFile(file) : ProcedureReturn -2 : EndIf
If ReadData(file, *buffer, file_length)<>file_length
CloseFile(file) : FreeMemory(*buffer) : ProcedureReturn -3
EndIf
CloseFile(file)
file=CreateFile(#PB_Any, destination_path_csv$)
If Not file : FreeMemory(*buffer) : ProcedureReturn -4 : EndIf
If OpenCryptRandom() : CryptRandomData(*buffer+buffer_length-8, 8) : Else : RandomData(*buffer+buffer_length-8, 8) : EndIf
If Not QAES_smart_universal_coder(0, *buffer, *buffer, buffer_length-8, key$, PeekQ(*buffer+buffer_length-8))
CloseFile(file) : FreeMemory(*buffer) : ProcedureReturn -5
EndIf
If WriteData(file, *buffer, buffer_length)<>buffer_length
CloseFile(file) : FreeMemory(*buffer) : ProcedureReturn -6
EndIf
CloseFile(file) : FreeMemory(*buffer)
ProcedureReturn 1
EndProcedure
Procedure read_encrypted_file(destination_path_csv$, List result.s(), key$)
Protected i, ii, line_length, peek_b, peek_w, row_break, counter.q, offset, *buffer, result$
Protected file=ReadFile(#PB_Any, destination_path_csv$), file_length=Lof(file) , file_length_1=file_length-2
If Not file : ProcedureReturn -7 : EndIf
*buffer=AllocateMemory(file_length+8)
If Not *buffer : ProcedureReturn -8 : EndIf
FileSeek(file, file_length-8)
counter=ReadQuad(file)
FileSeek(file, 0)
*buffer+2
If ReadData(file, *buffer, file_length)<>file_length : CloseFile(file) : FreeMemory(*buffer) : EndIf
CloseFile(file)
If Not QAES_smart_universal_coder(0, *buffer, *buffer, file_length-8, key$, counter)
FreeMemory(*buffer) : ProcedureReturn -9
EndIf
file_length-1
For i=0 To file_length ; Search and handle row break
peek_w=PeekW(*buffer+i) : peek_b=peek_w&$FF
If peek_w=$0A0D : row_break=$0D : offset=2 : PokeW(*buffer-2, $0A0D) : Break : EndIf
If peek_w=$0D0A : row_break=$0A : offset=2 : PokeW(*buffer-2, $0D0A) : Break : EndIf
If peek_b=$0D : row_break=$0D : offset=1 : PokeB(*buffer-1, $0D) : Break : EndIf
If peek_b=$0A : row_break=$0A : offset=1 : PokeB(*buffer-1, $0A) : Break : EndIf
Next i
If offset
file_length-16-offset
If offset<2 : ii-1 : Else :ii-2 : EndIf
For i=ii To file_length
If PeekB(*buffer+i)=row_break : i+offset
line_length=*buffer+i+offset
For ii=i To file_length : If PeekB(*buffer+ii)=row_break : Break : EndIf : Next
AddElement(result())
result()=PeekS(*buffer+i, *buffer+ii+offset-line_length, #PB_UTF8 | #PB_ByteLength)
EndIf
Next
Else
AddElement(result())
result()=PeekS(*buffer, (*buffer+file_length-14)-*buffer, #PB_UTF8 | #PB_ByteLength)
EndIf
FreeMemory(*buffer-2)
ProcedureReturn 1
EndProcedure
EndModule
UseModule QAES_TextToFileCrypter
; ===============================================================================================================================================
; Hint : Dual crypting is deactivated in the QAES crypter
; For very large files you must deactivate the debugger
EnableExplicit
Define template_path_csv$=GetUserDirectory(#PB_Directory_Desktop)+"/QAES_Text_to_File_Crypter_UTF8/Test.csv"
Define destination_path_csv$=GetUserDirectory(#PB_Directory_Desktop)+"/QAES_Text_to_File_Crypter_UTF8/Test.csv [encrypted]"
Define key$= "This is a test key"
NewList result.s()
Debug "=== Encrypt and create a encrypted file ==="
create_encrypted_file(template_path_csv$, destination_path_csv$, key$) ; Create a encrypted file
Debug "=== Load the encrypted file and decrypt ==="
read_encrypted_file(destination_path_csv$, result.s(), key$) ; Read a encrypted file
Debug "=== Get the result ==="
Debug ""
ForEach result() ; Get the result
Debug result()
Next