Crypted Pinboard -Five pages &File/Folder crypter &Source

Applications, Games, Tools, User libs and useful stuff coded in PureBasic
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Crypted Pinboard -Five pages &File/Folder crypter &Source

Post by walbus »


Crypted Pinboard

All OS / modules
Author : Werner Albus - http://www.nachtoptik.de - http://www.quick-aes-256.de

Features:
Full drag and drop
AES256 OFB mode, one or two stage
Crypted pinboard with five pages, & file & folder crypter
With file integrity check and string termination handling
Encrypted identical files are completely different in content and length

The folder crypter encrypt all not encrypted files in a folder
and decrypt all encrypted files, with undo !

A other, bare SHA3 512 bit based special crypter you found here
http://www.purebasic.fr/english/viewtop ... 27&t=68742

Code: Select all

; QAES crypted Pinboard - Author : (c) Werner Albus - www-nachtoptik.de - www.quick-aes-256.de
; Please set a hint in your software for using QAES contents 

; ===== QAES smart universal coder =====
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  
  
  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 remains=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 remains
        *buffer_out_asc=*buffer_out_quad : *buffer_in_asc=*buffer_in_quad : *register_asc=@register(0)
        go_1
        For ii=0 To remains-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

; ==== Progressbar_ex ====
DeclareModule progressbar_ex
  Declare progressbar_ex(progressbar_ID, flags, foreground_color=$32CD32, background_color=$DDDDDD)
EndDeclareModule

Module progressbar_ex
  ; This is a module for replacing a OS progressbar with a multi color progressbar
  ; Author : Werner Albus - www.nachtoptik.de - www.quick-aes-256.de
  
  ; Add simple the progressbar_ex call after any progressbar SetGadgetState calls
  ; SetGadgetState(progressbar_ID, 100*writen/file_size) ; OS progress bar
  ; progressbar_ex(progressbar_ID, flags, $32CD32, $FFFF) ; progressbar_ex
  
  ; This module can handle one progressbar in a event loop
  ; For handling different progressbars at the same loop, create other modules
  ; As sample, progressbar_ex_1, progressbar_ex_2, for each different progressbar one
  
  Procedure progressbar_ex(progressbar_ID, flags, foreground_color=$32CD32, background_color=$DDDDDD)
    ; Available flags : #PB_ProgressBar_Vertical
    ; -1 remove the progressbar_ex
    Static image_ID, image_gadget_ID
    If flags=-1
      If IsImage(image_ID) : FreeImage(image_ID) : image_ID=0 : EndIf
      If IsGadget(image_gadget_ID) : FreeGadget(image_gadget_ID) : image_gadget_ID=0 : EndIf
      DisableGadget(progressbar_ID, 0)
      HideGadget(progressbar_ID, 0)
      ProcedureReturn 0
    EndIf  
    Protected state=GetGadgetState(progressbar_ID)
    Protected width.f=GadgetWidth(progressbar_ID)
    Protected height.f=GadgetHeight(progressbar_ID)
    Protected min=GetGadgetAttribute(progressbar_ID, #PB_ProgressBar_Minimum)
    Protected max=GetGadgetAttribute(progressbar_ID, #PB_ProgressBar_Maximum)
    If min<1 : min=1 : EndIf : If max<1 : max=1 : EndIf
    DisableGadget(progressbar_ID, 1)
    HideGadget(progressbar_ID, 1)
    If Not image_ID : image_ID=CreateImage(#PB_Any, width, height, 24, background_color) : EndIf
    StartDrawing(ImageOutput(image_ID))
    Box(0, 0, width, height, background_color)
    If flags=#PB_ProgressBar_Vertical
      Box(1, height-(state-min)*(height/(max-min)), width-1, height, foreground_color)
    Else
      Box(0, 1, (state-min)*(width/(max-min)), height-1, foreground_color)
    EndIf
    DrawingMode(#PB_2DDrawing_Outlined)
    Box(0, 0, width, height, $BBBBBB)
    StopDrawing()
    If Not image_gadget_ID
      image_gadget_ID=ImageGadget(#PB_Any, GadgetX(progressbar_ID), GadgetY(progressbar_ID), width, height, ImageID(image_ID))
    EndIf
    SetGadgetState(image_gadget_ID, ImageID(image_ID))
    ProcedureReturn image_gadget_ID
  EndProcedure
EndModule
UseModule progressbar_ex

; ===== 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()
  UseModule progressbar_ex
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
    Declare FixWriteData(file, *adress, length) ; Workaround Linux PB 560
  CompilerEndIf
EndDeclareModule

Module QAES_smart_file_coder
  ; Smart file crypting addon or the QAES_smart_universal_coder
  
  ; 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:
    cryptextender_length=8+8+8+#HashLength>>3 ; Global
    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, window_event, result, block_size=4096<<2 
    Protected progressbar_state, encrypted_file_found=0, hash_bytes, i, key_presetted, blocks, rest, block_counter=0
    Protected file_size.q, fake_length.q, set_fake_length.q, get_fake_length.q, get_counter.q, counter.q, counter_0.q, get_magic.q, magic.q
    Protected set_fake_length_1.q, counter_1.q=345645758512426756724 ; Preset startpoint counter 1 - You can change
    Protected Dim hash.q(#HashLength>>3-1)
    Protected Dim buffer.q(block_size>>3-1)
    
    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 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
      FileBuffersSize(file, 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_fake_length>block_size Or get_fake_length<0 : get_fake_length=0 : EndIf ; Fuse
      
      If get_magic=magic And file_size>cryptextender_length+get_fake_length
        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)
      ; Tweak the OS progressbar :)
      progressbar_ex(progressbar_ID, 0, 0, $FFFF) 
    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(0), 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(0), 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(0), @buffer(0), block_size, key$, counter_0, counter_1) ; QAES crypter
      EndIf
      
      If Not encrypted_file_found
        If readed>0
          hash$=Fingerprint(@buffer(0), 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(0), 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)
        ; Tweak the OS progressbar :)
        If encrypted_file_found : Protected progress_foreground_color=$32CD32 : Else : progress_foreground_color=$FF : EndIf
        progressbar_ex(progressbar_ID, 0, progress_foreground_color, $FFFF)
      EndIf
      counter_0+1 : counter_1+1
    Until Not readed
    
    If progressbar_state=2
      SetGadgetState(progressbar_ID, 100)
      ; Tweak the OS progressbar :)
      If encrypted_file_found : progress_foreground_color=$32CD32 : Else : progress_foreground_color=$FF : EndIf
      progressbar_ex(progressbar_ID, 0, progress_foreground_color, $FFFF)
    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)
        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)
      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 OpenCryptRandom()
      set_fake_length.q=Random(#RandomizeFileLengthBytes)+#EnlargeFileLengthBytes
      Dim fake_content.a(set_fake_length-1)
      CryptRandomData(@fake_content(0), set_fake_length)
    Else
      set_fake_length.q=Random(#RandomizeFileLengthBytes)+#EnlargeFileLengthBytes
      Dim fake_content.a(set_fake_length-1)
      RandomData(@fake_content(0), set_fake_length)
    EndIf
    
    set_fake_length_1=set_fake_length
    
    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, @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
      
      writen+WriteData(file, @fake_content(0), set_fake_length)
      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)
        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)
        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
    
    ProcedureReturn message$
    
  EndProcedure
  
EndModule
UseModule QAES_smart_file_coder

; === Module QAES get folders and files ===
DeclareModule QAES_get_folder_files
  UseModule QAES_smart_file_coder
  Declare QAES_get_folder_files(mode, List PathList$(), path_found$, include_hidden=#True)
  Global NewList PathList$()
EndDeclareModule

Module QAES_get_folder_files
  
  EnableExplicit
  
  Procedure QAES_get_folder_files(mode, List PathList$(), path_found$, include_hidden=#True)
    
    If Right(path_found$, 1)<>"/" : path_found$+"/" : EndIf
    
    ; Set mode=1 for broken file hash messages
    Protected directory, entry_atrributes, entry_type
    Protected pathslash$, entry_name$, result$
    
    directory=ExamineDirectory(#PB_Any, path_found$, "*.*")
    If directory
      While NextDirectoryEntry(directory)
        While WindowEvent() : Wend
        entry_name$=DirectoryEntryName(directory)
        entry_atrributes=DirectoryEntryAttributes(directory)
        entry_type=DirectoryEntryType(directory)
        If entry_name$="." Or entry_name$=".." : Continue : EndIf
        If Not include_hidden
          CompilerIf #PB_Compiler_OS = #PB_OS_Windows
            If entry_atrributes & #PB_FileSystem_Hidden : Continue : EndIf
          CompilerElse
            If Left(entry_name$, 1) = "." : Continue : EndIf
          CompilerEndIf
        EndIf
        Select entry_type 
          Case #PB_DirectoryEntry_Directory
            CompilerIf #PB_Compiler_OS=#PB_OS_Windows
              QAES_get_folder_files(1, PathList$(), path_found$+entry_name$+"\", include_hidden) 
            CompilerElse
              QAES_get_folder_files(1, PathList$(), path_found$+entry_name$+"/", include_hidden)
            CompilerEndIf
          Case #PB_DirectoryEntry_File
            AddElement(PathList$())
            PathList$()=path_found$+entry_name$
        EndSelect 
      Wend
      FinishDirectory(directory)
      ProcedureReturn 1
    EndIf
  EndProcedure
EndModule
UseModule QAES_get_folder_files

; === Module QAES_crypted_Pinboard with five pages plus file and folder crypter ===
DeclareModule QAES_crypted_Pinboard
  UseModule QAES_smart_universal_coder
  UseModule QAES_smart_file_coder
  UseModule QAES_get_folder_files
  UseModule progressbar_ex
  Declare QAES_crypted_Pinboard()
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    Declare EditorProc(hwnd, msg, wParam, lParam)
  CompilerEndIf
EndDeclareModule

Module QAES_crypted_Pinboard
  ; Crypted pinboard with five pages - AES256 OFB mode
  ; Author Werner Albus - www-nachtoptik.de - www.quick-aes-256.de
  ; No warranty whatsoever - Use at your own risk
  
  EnableExplicit
  
  #KeyStretchingLoops=1e6 ; You can here enable key stretching - zero is without
  
  Enumeration
    #Page_1
    #Page_2
    #Page_3
    #Page_4
    #Page_5
    #FileCrypter
    #Editor_1
    #Editor_2
    #Progressbar
    #Window_1
    #KeyHash
  EndEnumeration
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    Global proc 
    Procedure EditorProc(hwnd, msg, wParam, lParam) 
      If msg=#WM_CONTEXTMENU 
        DisplayPopupMenu(1, WindowID(#Window_1))
      EndIf 
      ProcedureReturn CallWindowProc_(proc, hwnd, msg, wParam, lParam) 
    EndProcedure
  CompilerEndIf
  
  Procedure QAES_crypted_Pinboard()
    
    CompilerIf #PB_Compiler_OS = #PB_OS_Linux
      CompilerIf Not Subsystem("gtk2")
        MessageRequester("HINT", "Preset in the compiler options subsystem gtk2")
        End
      CompilerEndIf
    CompilerEndIf
    
    CompilerIf #PB_Compiler_Version<560
      If SizeOf(character)=1
        MessageRequester("HINT", "Compile in mode unicode")
        End
      EndIf
    CompilerEndIf
    
    #content_file="QAES_Pinboard"
    
    #file_extender$=" [encrypted]" ; You can change how ever you want
    
    Protected content_path$=GetHomeDirectory()+#content_file, key$, result$, path$, path_found$
    Protected page_1$, page_2$, page_3$, page_4$, page_5$, content$, old_content$, pathslash$, message$, key_1$
    Protected result, result_1, file, counter_aes, old_active_page, menu_event, content_broken, find_lf_0, find_lf_1
    Protected  mode, win_event, window_width=800, window_height=600
    Protected data_length.q, i.q
    #Salt$="R=NÜ?=M&FeB$VM*Ä:t68e59ewr0ßT)/&R(B)=Ü=)M/T%Eku§WB)Nr?P=/$§!?"
    
    Structure pages
      page.q[5] ; Five pages
      active_page.a
    EndStructure
    Protected pages.pages
    
    Macro set_strings
      If Not GetGadgetData(#Page_1)
        page_1$=GetGadgetText(#Editor_1)
      ElseIf Not GetGadgetData(#Page_2)
        page_2$=GetGadgetText(#Editor_1)
      ElseIf Not GetGadgetData(#Page_3)
        page_3$=GetGadgetText(#Editor_1)
      ElseIf Not GetGadgetData(#Page_4)
        page_4$=GetGadgetText(#Editor_1) 
      ElseIf Not GetGadgetData(#Page_5)
        page_5$=GetGadgetText(#Editor_1)           
      EndIf
    EndMacro
    
    Macro enable_buttons
      DisableGadget(#Page_1, 0) : SetGadgetData(#Page_1, 1)
      DisableGadget(#Page_2, 0) : SetGadgetData(#Page_2, 1)
      DisableGadget(#Page_3, 0) : SetGadgetData(#Page_3, 1)
      DisableGadget(#Page_4, 0) : SetGadgetData(#Page_4, 1)
      DisableGadget(#Page_5, 0) : SetGadgetData(#Page_5, 1)
    EndMacro
    
    Macro editor_2_text_output
      result$=Left(result$, FindString(result$, "!")-1)
      result$=Right(result$, Len(result$)-FindString(result$, "-"))
      SetGadgetText(#Editor_2, result$) : result$=""
    EndMacro
    
    OpenWindow(#Window_1, #PB_Ignore, #PB_Ignore, window_width, window_height,
               "QAES Crypted Pinboard - www.nachtoptik.de - No warranty whatsoever - Use at your own risk",
               #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
    
    SetWindowColor(#Window_1, $FFFFFF)
    
    EditorGadget(#Editor_1, 5, 20, window_width-10, window_height-46)
    
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      EditorGadget(#Editor_2, 316, window_height-24, window_width-412, 20, #PB_Editor_ReadOnly)
      ButtonGadget(#Page_1, 5, window_height-25, 60, 22, "Page 1")
      ButtonGadget(#Page_2, 67, window_height-25, 60, 22, "Page 2")
      ButtonGadget(#Page_3, 129, window_height-25, 60, 22, "Page 3")
      ButtonGadget(#Page_4, 191, window_height-25, 60, 22, "Page 4")
      ButtonGadget(#Page_5, 253, window_height-25, 60, 22, "Page 5")
      ButtonGadget(#FileCrypter, 707, window_height-25, 89, 22, "File Crypter")
    CompilerEndIf
    
    CompilerIf #PB_Compiler_OS = #PB_OS_Linux
      EditorGadget(#Editor_2, 316, window_height-24, window_width-411, 20, #PB_Editor_ReadOnly)
      ButtonGadget(#Page_1, 5, window_height-25, 61, 22, "Page 1")
      ButtonGadget(#Page_2, 67, window_height-25, 61, 22, "Page 2")
      ButtonGadget(#Page_3, 129, window_height-25, 61, 22, "Page 3")
      ButtonGadget(#Page_4, 191, window_height-25, 61, 22, "Page 4")
      ButtonGadget(#Page_5, 253, window_height-25, 61, 22, "Page 5")
      ButtonGadget(#FileCrypter, 707, window_height-25, 89, 22, "File Crypter")
    CompilerEndIf
    
    CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
      EditorGadget(#Editor_2, 317, window_height-24, window_width-412, 20, #PB_Editor_ReadOnly)
      ButtonGadget(#Page_1, 5, window_height-26, 62, 24, "Page 1")
      ButtonGadget(#Page_2, 67, window_height-26, 62, 24, "Page 2")
      ButtonGadget(#Page_3, 129, window_height-26, 62, 24, "Page 3")
      ButtonGadget(#Page_4, 191, window_height-26, 62, 24, "Page 4")
      ButtonGadget(#Page_5, 253, window_height-26, 62, 24, "Page 5")
      ButtonGadget(#FileCrypter, 707, window_height-26, 90, 24, "File Crypter")
    CompilerEndIf
    
    EnableGadgetDrop(#Editor_1, #PB_Drop_Files, #PB_Drag_Link)
    
    ProgressBarGadget(#Progressbar, Window_width-365, 5, 360, 10, 0, 100, #PB_ProgressBar_Smooth)
    
    TextGadget(#KeyHash, 6, 0, 0, 0, "")
    
    HideGadget(#Progressbar, 1)
    SetGadgetText(#Editor_1, "Welcome to the QAES256 OFB mode crypted pinboard, with integrated file / folder crypter and automatic integrity check"+
                             #CRLF$+#CRLF$+"Saving a empty pinboard delete your used password and the content file"+#CRLF$+
                             "You can move simple files and folders with drag and drop in the pinboard"+#CRLF$+
                             "The encrypted pinboard content file you found in your home directory, named 'QAES_Pinboard'"+#CRLF$+
                             "The displayed key hash is just a hint to give you the possibility to check if you entered the correct key again"+#CRLF$+
                             "You can remember or write down a part of the key hash, you don't have to hide it")
    
    If FileSize(content_path$)>0
      key$="Your password is needed !" : result=#PB_InputRequester_Password
    Else
      key$="Set firstly a password !"
    EndIf
    key$=InputRequester("", key$, "", result)
    If key$="" : End : EndIf
    
    key$+#Salt$
    key$=Fingerprint(@key$, StringByteLength(key$), #PB_Cipher_SHA3, 512)
    
    Macro hash64
      For i=1 To #KeyStretchingLoops
        key$+Str(i)
        key$=Fingerprint(@key$, StringByteLength(key$), #PB_Cipher_SHA3, 512)
        While WindowEvent() : Wend
      Next i
      key$=ReverseString(key$+#Salt$)
      key$=Fingerprint(@key$, StringByteLength(key$), #PB_Cipher_SHA3, 512)
    EndMacro
    
    If #KeyStretchingLoops>0
      SetGadgetText(#Editor_1, "")
      DisableGadget(#Editor_1, 1)
      SetGadgetText(#Editor_1, "Key generating - Please wait")
      hash64
      DisableGadget(#Editor_1, 0)
    EndIf
    
    SetGadgetText(#Editor_1, "")
    key_1$=#Salt$+key$+#Salt$+key$
    key_1$=Left(Fingerprint(@key_1$, StringByteLength(key_1$), #PB_Cipher_SHA3), 32)
    CompilerIf #PB_Compiler_OS=#PB_OS_MacOS
      ResizeGadget(#KeyHash, 6, 0, 380, 16)
    CompilerElse
      StartDrawing(WindowOutput(#Window_1))
      ResizeGadget(#KeyHash, 6, 0, TextWidth(key_1$), TextHeight(key_1$))
      StopDrawing()
    CompilerEndIf
    SetGadgetText(#KeyHash, "Key Hash : "+Left(key_1$, 32))
    
    result=FileSize(content_path$)   
    
    If result>0
      result$=QAES_smart_file_coder(3, #Window_1, #Progressbar, content_path$, key$, "", 1) ; Check the file integrity
      counter_aes=Val(Right(result$, Len(result$)-FindString(result$, "=>")-1))             ; Getting the used counter
      If Left(result$, 7)="WARNING" Or Left(result$, 5)="ALLok"
        If Left(result$, 5)<>"ALLok"
          content_broken=1
          editor_2_text_output
        EndIf
      Else
        editor_2_text_output
        While WindowEvent() : Wend
        Delay(3000)
        End
      EndIf
    ElseIf result<1
      pages\active_page=1
      SetGadgetText(#Editor_2, " Page 1 selected - Board empty")
    EndIf
    
    file=ReadFile(#PB_Any, content_path$)
    If Not file
      file=CreateFile(#PB_Any, content_path$)
      If Not file
        MessageRequester("HINT", "Can not create content file")
        End
      EndIf
    EndIf
    
    data_length=Lof(file)-QAES_get_cryptextender_length()-SizeOf(pages)
    
    If data_length>0
      content$=Space(data_length/SizeOf(character))
      result=ReadData(file, @content$, data_length)
      result+ReadData(file, @pages\page[0], SizeOf(pages))
      If result<>data_length+SizeOf(pages)
        MessageRequester("HINT", "Can not read content file")
        content$=""
      EndIf
    EndIf
    
    CloseFile(file)
    
    If content_broken ; Remove found unwanted string terminations on the broken string content
      result=data_length-2
      i=0
      Repeat 
        If Not PeekW(@content$+i) : PokeW(@content$+i, 1) : EndIf 
        i+2
      Until i>result
      MessageRequester("WARNING", "Integrity check content file fails"+#CRLF$+#CRLF$+"File hash broken"+#CRLF$+#CRLF$+"Take with care !")
    EndIf
    
    If content$<>""
      QAES_smart_universal_coder(2, @content$, @content$, StringByteLength(content$), key$, 0, counter_aes) ; Mode unicode
      QAES_smart_universal_coder(0, @pages\page[0], @pages\page[0], SizeOf(pages), ReverseString(key$), 0, counter_aes) ; Mode binary
      old_content$=content$
    EndIf
    
    If Left(result$, 5)="ALLok"
      SetGadgetText(#Editor_2, " Page "+Str(pages\active_page)+" selected")
    EndIf
    
    page_1$=Left(content$, pages\page[0])
    page_2$=Mid(content$, pages\page[0]+1, pages\page[1])
    page_3$=Mid(content$, pages\page[0]+pages\page[1]+1, pages\page[2])
    page_4$=Mid(content$, pages\page[0]+pages\page[1]+pages\page[2]+1, pages\page[3])
    page_5$=Mid(content$, pages\page[0]+pages\page[1]+pages\page[2]+pages\page[3]+1, pages\page[4])
    
    old_active_page=pages\active_page 
    
    enable_buttons
    Select pages\active_page 
      Case 1
        SetGadgetText(#Editor_1, page_1$)
        DisableGadget(#Page_1, 1) : SetGadgetData(#Page_1, 0)
      Case 2
        SetGadgetText(#Editor_1, page_2$)
        DisableGadget(#Page_2, 1) : SetGadgetData(#Page_2, 0)
      Case 3
        SetGadgetText(#Editor_1, page_3$)
        DisableGadget(#Page_3, 1) : SetGadgetData(#Page_3, 0)
      Case 4
        SetGadgetText(#Editor_1, page_4$)
        DisableGadget(#Page_4, 1) : SetGadgetData(#Page_4, 0)
      Case 5
        SetGadgetText(#Editor_1, page_5$)
        DisableGadget(#Page_5, 1) : SetGadgetData(#Page_5, 0)
    EndSelect
    
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      CreatePopupMenu(1) 
      MenuItem(1, "Undo") 
      MenuBar()
      MenuItem(2, "Cut") 
      MenuItem(3, "Copy") 
      MenuItem(4, "Paste") 
      MenuItem(5, "Delete") 
      MenuBar()
      MenuItem(6, "Select all")
    CompilerEndIf
    
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      proc=SetWindowLong_(GadgetID(#Editor_1),#GWL_WNDPROC,@EditorProc())
    CompilerEndIf
    
    progressbar_ex(#Progressbar, 0, $00FFFF, $00FFFF) ; Tweak the OS progressbar :)
    
    Repeat 
      
      Select WaitWindowEvent()
        Case #PB_Event_Gadget
          Select EventGadget()
            Case #Page_1
              enable_buttons 
              DisableGadget(#Page_1, 1)
              SetGadgetData(#Page_1, 0)
              SetGadgetText(#Editor_2, " Page 1 selected")
              SetGadgetText(#Editor_1, page_1$)
              SetActiveGadget(#Editor_1)
            Case #Page_2
              enable_buttons
              DisableGadget(#Page_2, 1)
              SetGadgetData(#Page_2, 0)
              SetGadgetText(#Editor_2, " Page 2 selected")
              SetGadgetText(#Editor_1, page_2$)
              SetActiveGadget(#Editor_1)
            Case #Page_3
              enable_buttons
              DisableGadget(#Page_3, 1)
              SetGadgetData(#Page_3, 0)
              SetGadgetText(#Editor_2, " Page 3 selected")
              SetGadgetText(#Editor_1, page_3$)
              SetActiveGadget(#Editor_1)
            Case #Page_4
              enable_buttons
              DisableGadget(#Page_4, 1)
              SetGadgetData(#Page_4, 0)
              SetGadgetText(#Editor_2, " Page 4 selected")
              SetGadgetText(#Editor_1, page_4$)
              SetActiveGadget(#Editor_1)
            Case #Page_5
              enable_buttons
              DisableGadget(#Page_5, 5)
              SetGadgetData(#Page_5, 0)
              SetGadgetText(#Editor_2, " Page 5 selected")
              SetGadgetText(#Editor_1, page_5$)
              SetActiveGadget(#Editor_1)
            Case #FileCrypter
              HideGadget(#Progressbar, 0) : DisableGadget(#Editor_1, 1) :  DisableGadget(#Editor_2, 1)
              QAES_smart_file_coder(0, #Window_1, #Progressbar, "", key$, #file_extender$)
              SetGadgetState(#Progressbar, 100)
              progressbar_ex(#Progressbar, 0, $FFFF, $FFFF) ; Tweak the OS progressbar :)
              While WindowEvent() : Wend
              Delay(200)
              HideGadget(#Progressbar, 1) : DisableGadget(#Editor_1, 0) :  DisableGadget(#Editor_2, 0)
              SetGadgetState(#Progressbar, 0)
              progressbar_ex(#Progressbar, 0, $FFFF, $FFFF) ; Tweak the OS progressbar :)
              SetActiveGadget(#Editor_1)
            Case #Editor_1
              If EventType()=#PB_EventType_Change
                set_strings
              EndIf
          EndSelect
          
        Case #PB_Event_GadgetDrop
          Protected progress_foreground_color=$FFFF ; Tweak the OS progressbar :)
          path$=EventDropFiles()
          HideGadget(#Progressbar, 0) : DisableGadget(#Editor_1, 1) :  DisableGadget(#Editor_2, 1) 
          Protected break_button_x=GadgetX(#FileCrypter)
          Protected break_button_y=GadgetY(#FileCrypter)
          Protected break_button_xx=GadgetX(#FileCrypter)+GadgetWidth(#FileCrypter)
          Protected break_button_yy=GadgetY(#FileCrypter)+GadgetHeight(#FileCrypter)
          
          CompilerIf #PB_Compiler_OS = #PB_OS_Windows : pathslash$="\" : pathslash$="/" : CompilerEndIf
          ; Get paths
          SetGadgetText(#FileCrypter, "Break")
          message$=GetGadgetText(#Editor_2)
          SetGadgetText(#Editor_2, "Please wait, i read folders")
          Repeat
            little_loop_1:
            win_event=WindowEvent()
            If WindowMouseX(#Window_1)>break_button_x And WindowMouseY(#Window_1)>break_button_y And
               WindowMouseX(#Window_1)<break_button_xx And WindowMouseY(#Window_1)<break_button_yy
              Delay(1)
              If win_event=#PB_Event_Gadget And EventGadget()=#FileCrypter : Goto break_1 : EndIf
              Goto little_loop_1
            EndIf
            find_lf_0=FindString(#LF$+path$+#LF$, #LF$, find_lf_0)
            find_lf_1=FindString(#LF$+path$+#LF$, #LF$, find_lf_1)
            If find_lf_1
              result$=Mid(#LF$+path$+#LF$, find_lf_0+1, find_lf_1-find_lf_0-1)
              path_found$=result$+pathslash$
              
              If FileSize(path_found$)=-2 ; Ordner gefunden
                QAES_get_folder_files(1, PathList$(), path_found$)
              Else
                If result$<>""
                  AddElement(PathList$())
                  PathList$()=result$
                EndIf
              EndIf
            EndIf
            If find_lf_1+3>find_lf_0
              find_lf_0=find_lf_1 : find_lf_1=find_lf_1+3
            Else
              Break
            EndIf
          ForEver
          find_lf_0=0 : find_lf_1=0
          
          ; Crypting
          SetGadgetText(#Editor_2, "Please wait, the crypter runs")
          result=0
          ForEach PathList$()
            result+1
            little_loop_2:
            win_event=WindowEvent()
            If WindowMouseX(#Window_1)>break_button_x And WindowMouseY(#Window_1)>break_button_y And
               WindowMouseX(#Window_1)<break_button_xx And WindowMouseY(#Window_1)<break_button_yy
              Delay(1)
              If win_event=#PB_Event_Gadget And EventGadget()=#FileCrypter
                MessageRequester("HINT", "Break by user"+#CRLF$+#CRLF$+"I will now undo the changes") 
                result_1=result-1 : result=0
                ResetList(PathList$())
                SetGadgetText(#FileCrypter, "Please wait")
                ForEach PathList$()
                  result+1
                  result$=QAES_smart_file_coder(4, #Window_1, #Progressbar, PathList$()+#file_extender$, key$)
                  If Left(result$, 5)="ALLok" Or Left(result$, 7)="WARNING"
                    result$=QAES_smart_file_coder(2, #Window_1, #Progressbar, PathList$()+#file_extender$, key$, #file_extender$)
                  Else
                    result$=PathList$()
                    If Right(result$, Len(#file_extender$))=#file_extender$
                      result$=Left(result$, Len(result$)-Len(#file_extender$))
                    EndIf
                    QAES_smart_file_coder(1, #Window_1, #Progressbar, result$, key$, #file_extender$)
                  EndIf
                  If Left(result$, 7)="WARNING"
                    result$=Left(PathList$()+#file_extender$, Len(PathList$()+#file_extender$)-Len(#file_extender$))
                    MessageRequester("WARNING", "Broken file hash found"+#CRLF$+#CRLF$+
                                                "I mark the file as broken"+#CRLF$+#CRLF$+PathList$()) 
                    RenameFile(result$, result$+" [File hash broken]")
                  EndIf
                  If result=result_1 : Goto break_1 : EndIf
                Next 
              EndIf
              Goto little_loop_2
            EndIf
            
            result$=QAES_smart_file_coder(4, #Window_1, #Progressbar, PathList$(), key$, #file_extender$)
            If Left(result$, 5)="ALLok" : mode=2 : Else : mode=1 : EndIf
            result$=QAES_smart_file_coder(mode, #Window_1, #Progressbar, PathList$(), key$, #file_extender$)
            If mode=2 And Left(result$, 7)="WARNING"
              result$=Left(PathList$(), Len(PathList$())-Len(#file_extender$))
              If mode
                MessageRequester("WARNING", "Broken file hash found"+#CRLF$+#CRLF$+
                                            "I mark the file as broken"+#CRLF$+#CRLF$+PathList$()) 
                Debug RenameFile(result$, result$+" [File hash broken]")
              EndIf
            EndIf
          Next 
          
          ; Crypting finish
          break_1:
          SetGadgetText(#FileCrypter, "File Crypter")
          SetGadgetText(#Editor_2, message$)
          ClearList(PathList$())
          SetGadgetState(#Progressbar, 100)
          progressbar_ex(#Progressbar, 0, progress_foreground_color, $FFFF) ; Tweak the OS progressbar :)
          While WindowEvent() : Wend
          Delay(200)
          HideGadget(#Progressbar, 1) : DisableGadget(#Editor_1, 0) :  DisableGadget(#Editor_2, 0)
          SetGadgetState(#Progressbar, 0)
          progressbar_ex(#Progressbar, 0, progress_foreground_color, $FFFF) ; Tweak the OS progressbar :)
          SetActiveGadget(#Editor_1)
          
        Case #PB_Event_CloseWindow
          set_strings
          content$=page_1$+page_2$+page_3$+page_4$+page_5$
          pages\page[0]=Len(page_1$)
          pages\page[1]=Len(page_2$)
          pages\page[2]=Len(page_3$)
          pages\page[3]=Len(page_4$)
          pages\page[4]=Len(page_5$)
          
          If Not GetGadgetData(#Page_1)
            pages\active_page=1
          ElseIf Not GetGadgetData(#Page_2)
            pages\active_page=2
          ElseIf Not GetGadgetData(#Page_3)
            pages\active_page=3
          ElseIf Not GetGadgetData(#Page_4)
            pages\active_page=4
          ElseIf Not GetGadgetData(#Page_5)
            pages\active_page=5         
          EndIf
          
          If FileSize(content_path$)<1 And content$="" : DeleteFile(content_path$) : End : EndIf
          
          If content$=""        
            result=MessageRequester("HINT", "The pinboard is empty"+#CRLF$+#CRLF$+
                                            "Closing a empty pinboard delete your used password and the content file !"+#CRLF$+#CRLF$+
                                            "You want delete your used password and the content file ?", #PB_MessageRequester_YesNo)
            If result=#PB_MessageRequester_No
              End
            Else
            DeleteFile(content_path$) : End : EndIf
          EndIf
          
          If content$=old_content$ And old_active_page=pages\active_page: End : EndIf
          
          If FileSize(content_path$)>1
            result$="This overwrites an existing content file in your home directory !"
          Else
            result$=""
          EndIf
          
          result=MessageRequester("HINT",
                                  "You want to save this pinboard content before the tool is finished ?"+
                                  #CRLF$+#CRLF$+result$, #PB_MessageRequester_YesNo)
          If result=#PB_MessageRequester_No : End : EndIf
          
          file=OpenFile(#PB_Any, content_path$)
          If Not file
            result=MessageRequester("HINT", "Can not read content file"+#CRLF$+#CRLF$+
                                            "Want you close the tool ?", #PB_MessageRequester_YesNo)
            If result=#PB_MessageRequester_Yes
              End
            EndIf
          Else
            If OpenCryptRandom() : CryptRandomData(@counter_aes, 8) : Else : RandomData(@counter_aes, 8) : EndIf
            QAES_smart_universal_coder(2, @content$, @content$, StringByteLength(content$), key$, 0, counter_aes) ; Mode unicode
            QAES_smart_universal_coder(0, @pages\page[0], @pages\page[0], SizeOf(pages), ReverseString(key$), 0, counter_aes) ; Mode binary
            
            TruncateFile(file)
            result=WriteData(file, @content$, StringByteLength(content$))
            result+WriteData(file, @pages\page[0], SizeOf(pages))
            If result<>StringByteLength(content$)+SizeOf(pages)
              result=MessageRequester("HINT", "Can not writen content file"+#CRLF$+#CRLF$+
                                              "Want you close the tool ?", #PB_MessageRequester_YesNo)
              If result=#PB_MessageRequester_Yes
                CloseFile(file)
                End
              EndIf
            EndIf
            CloseFile(file)
            
            If FileSize(content_path$)>0
              ; The window ID is setted, so the file coder can handle the events
              result$=QAES_smart_file_coder(1, #Window_1, #Progressbar, content_path$, key$, "", counter_aes)
              editor_2_text_output
              While WindowEvent() : Wend
              Delay(2000)
            EndIf
            End
          EndIf
          
        Case #PB_Event_CloseWindow
          set_strings
          content$=page_1$+page_2$+page_3$+page_4$+page_5$
          pages\page[0]=Len(page_1$)
          pages\page[1]=Len(page_2$)
          pages\page[2]=Len(page_3$)
          pages\page[3]=Len(page_4$)
          pages\page[4]=Len(page_5$)
          
          If Not GetGadgetData(#Page_1)
            pages\active_page=1
          ElseIf Not GetGadgetData(#Page_2)
            pages\active_page=2
          ElseIf Not GetGadgetData(#Page_3)
            pages\active_page=3
          ElseIf Not GetGadgetData(#Page_4)
            pages\active_page=4
          ElseIf Not GetGadgetData(#Page_5)
            pages\active_page=5         
          EndIf
          
          If FileSize(content_path$)<1 And content$="" : DeleteFile(content_path$) : End : EndIf
          
          If content$=""        
            result=MessageRequester("HINT", "The pinboard is empty"+#CRLF$+#CRLF$+
                                            "Closing a empty pinboard delete your used password and the content file !"+#CRLF$+#CRLF$+
                                            "You want delete your used password and the content file ?", #PB_MessageRequester_YesNo)
            If result=#PB_MessageRequester_No
              End
            Else
            DeleteFile(content_path$) : End : EndIf
          EndIf
          
          If content$=old_content$ And old_active_page=pages\active_page: End : EndIf
          
          If FileSize(content_path$)>1
            result$="This overwrites an existing content file in your home directory !"
          Else
            result$=""
          EndIf
          
          result=MessageRequester("HINT",
                                  "You want to save this pinboard content before the tool is finished ?"+
                                  #CRLF$+#CRLF$+result$, #PB_MessageRequester_YesNo)
          If result=#PB_MessageRequester_No : End : EndIf
          
          file=OpenFile(#PB_Any, content_path$)
          If Not file
            result=MessageRequester("HINT", "Can not read content file"+#CRLF$+#CRLF$+
                                            "Want you close the tool ?", #PB_MessageRequester_YesNo)
            If result=#PB_MessageRequester_Yes
              End
            EndIf
          Else
            If OpenCryptRandom() : CryptRandomData(@counter_aes, 8) : Else : RandomData(@counter_aes, 8) : EndIf
            QAES_smart_universal_coder(2, @content$, @content$, StringByteLength(content$), key$, 0, counter_aes) ; Mode unicode
            QAES_smart_universal_coder(0, @pages\page[0], @pages\page[0], SizeOf(pages), ReverseString(key$), 0, counter_aes) ; Mode binary
            
            TruncateFile(file)
            result=WriteData(file, @content$, StringByteLength(content$))
            result+WriteData(file, @pages\page[0], SizeOf(pages))
            If result<>StringByteLength(content$)+SizeOf(pages)
              result=MessageRequester("HINT", "Can not writen content file"+#CRLF$+#CRLF$+
                                              "Want you close the tool ?", #PB_MessageRequester_YesNo)
              If result=#PB_MessageRequester_Yes
                CloseFile(file)
                End
              EndIf
            EndIf
            CloseFile(file)
            
            If FileSize(content_path$)>0
              ; The window ID is setted, so the file coder can handle the events
              result$=QAES_smart_file_coder(1, #Window_1, #Progressbar, content_path$, key$, "", counter_aes)
              editor_2_text_output
              While WindowEvent() : Wend
              Delay(2000)
            EndIf
            End
          EndIf
          
          CompilerIf #PB_Compiler_OS = #PB_OS_Windows
          Case #PB_Event_Menu 
            Select EventMenu() 
              Case 1
                SendMessage_(GadgetID(1), #WM_UNDO, 0, 0) 
              Case 2
                SendMessage_(GadgetID(#Editor_1), #WM_CUT, 0, 0) 
              Case 3 
                SendMessage_(GadgetID(#Editor_1), #WM_COPY, 0, 0) 
              Case 4
                SendMessage_(GadgetID(#Editor_1), #WM_PASTE, 0, 0) 
              Case 5
                SendMessage_(GadgetID(#Editor_1), #WM_CLEAR, 0, 0) 
              Case 6
                SendMessage_(GadgetID(#Editor_1), #EM_SETSEL, 0, -1) 
            EndSelect
          CompilerEndIf
      EndSelect
    ForEver
  EndProcedure
EndModule
UseModule QAES_crypted_Pinboard

QAES_crypted_Pinboard()
Last edited by walbus on Wed Jan 31, 2018 1:24 pm, edited 113 times in total.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Crypted Pinboard - With source code - As Module

Post by Kwai chang caine »

Thanks for sharing 8)
ImageThe happiness is a road...
Not a destination
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: Crypted Pinboard - With source code - As Module

Post by walbus »

Thank you KCC,
i think it's a good tool for making complicated things simple :wink:

Looking from time to time for code updates, i annonce not all changes
walbus
Addict
Addict
Posts: 929
Joined: Sat Mar 02, 2013 9:17 am

Re: Crypted Pinboard -Five pages &File/Folder crypter &Sourc

Post by walbus »

Code updated d31 m01 y2018

A key hash is now displayed
You don't have to hide this hash
When you remember or write down the first characters of this hash, you can always easily check if you have entered the correct password to decrypt it.
Especially in case of passphrases or complex passwords, mistakes are made quickly, which is avoided by this method.
Post Reply