AES256 Crypter - Complete Solution - Code

Knacken von Verschlüsselungen bei den Projekten RC5-72, Enigma@Home und anderen
Nachricht
Autor
walbus
Mikrocruncher
Mikrocruncher
Beiträge: 17
Registriert: 01.12.2014 20:46

AES256 Crypter - Complete Solution - Code

#1 Ungelesener Beitrag von walbus » 05.09.2018 10:19

Anbei gebe ich euch hier mal noch einen kompletten Crypter für Dateien, binäre Daten, Strings

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
Vereinfachter Base Code

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

walbus
Mikrocruncher
Mikrocruncher
Beiträge: 17
Registriert: 01.12.2014 20:46

Re: AES256 Crypter - Complete Solution - Code

#2 Ungelesener Beitrag von walbus » 06.09.2018 11:35

Hi,
es ist mir gerade aufgefallen das im großen Code die Progressbar nicht angezeigt wird

Ändert hierzu einfach ab Zeile 230 den Code so :
Dies aktiviert die Progress Anzeige, mehr ist nicht nötig

Code: Alles auswählen

If IsGadget(progressbar_ID)
   SetGadgetState(progressbar_ID, 0) : progressbar_state+1
 EndIf

Antworten

Zurück zu „Kryptographie“