AES+Base64 encryption

Just starting out? Need help? Post your questions and find answers here.
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

AES+Base64 encryption

Post by LiK137 »

The below veeery small piece of code is used to encrypt the memory block to AES and then to base64 (to store in database) and backwise

Code: Select all

;{ bAES64
#paData = "#@!$%^&*()(*&^%$!@#"
Procedure aesNCoder(*inData, *outData, szIn, Bits = 256)
  szinData + szIn
  
  If szinData  < 18
    paDataLen = StringByteLength(#paData, #PB_UTF8)
  EndIf
  
  *tmp = AllocateMemory(szinData + SizeOf(byte) + paDataLen)
  CopyMemory(*inData, *tmp, szinData)
  
  If szinData  < 18
    PokeS(*tmp + szinData - 1, #paData, paDataLen, #PB_UTF8)
    szinData + paDataLen
  EndIf
  
  errMod = Mod(szinData, 16) + 16               ; this errMod variable shows how different data size related to each other
  If errMod = 16                                    ; Observed that errMod with value 16 (and 31) makes encryption invalid
    If AESEncoder(*tmp, *outData, szinData + donnowha2nput1, ?Key, Bits, ?InitializationVector)
      RET = szinData 
    EndIf
  ElseIf errMod = 31                                ; Observed that errMod with value 16 (and 31) makes encryption invalid
    If AESEncoder(*tmp, *outData, szinData + donnowha2nput2, ?Key, Bits, ?InitializationVector)
      RET = szinData 
    EndIf
  Else                                              ; This is normaly working except 16/31 cases
    If AESEncoder(*tmp, *outData, szinData + SizeOf(byte), ?Key, Bits, ?InitializationVector)
      RET = szinData 
    EndIf
  EndIf
  
  FreeMemory(*tmp)
  
  ProcedureReturn RET
  
  DataSection
    Key:
      Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $06
  
    InitializationVector:
      Data.b $3d, $af, $ba, $42, $9d, $9e, $b4, $30, $b4, $22, $da, $80, $2c, $9f, $ac, $41
  EndDataSection
EndProcedure
Procedure aesDCoder(*inData, *outData, szIn, Bits = 256)
  szOut + szIn
  If AESDecoder(*inData, *outData, szOut + SizeOf(byte), ?Key, Bits, ?InitializationVector)
    If PeekA(*outData + szOut - 1) = 35
      paDataLen = StringByteLength(#paData, #PB_UTF8)
      *tmp = AllocateMemory(paDataLen + SizeOf(byte))
      PokeS(*tmp, #paData, paDataLen, #PB_UTF8)
      
      If CompareMemory(*outData + szOut - 19, *tmp, 19)
        szOut - 19
      EndIf
      FreeMemory(*tmp)
    Else  ; it is strange behaviour that when input data size constantly affects and breakes encoding/decoding
      errMod = Mod(szOut, 16) + 16 ; this errMod variable shows how different data size related to each other
      If errMod = 30                    ; Observed that errMod with value 30 (and 31) makes encryption invalid
        If AESDecoder(*inData, *outData, szOut + donnowha2input1, ?Key, Bits, ?InitializationVector)
          If PeekA(*outData + szOut - 1) = 35
            paDataLen = StringByteLength(#paData, #PB_UTF8)
            *tmp = AllocateMemory(paDataLen + SizeOf(byte))
            PokeS(*tmp, #paData, paDataLen, #PB_UTF8)
            
            If CompareMemory(*outData + szOut - 19, *tmp, 19)
              szOut - 19
            EndIf
            FreeMemory(*tmp)
          EndIf
        EndIf  
      ElseIf errMod = 31                 ; Observed that errMod with value 31 (and 30) makes encryption invalid
        If AESDecoder(*inData, *outData, szOut + donnowha2input2, ?Key, Bits, ?InitializationVector)
          If PeekA(*outData + szOut - 1) = 35
            paDataLen = StringByteLength(#paData, #PB_UTF8)
            *tmp = AllocateMemory(paDataLen + SizeOf(byte))
            PokeS(*tmp, #paData, paDataLen, #PB_UTF8)
            
            If CompareMemory(*outData + szOut - 19, *tmp, 19)
              szOut - 19
            EndIf
            FreeMemory(*tmp)
          EndIf
        EndIf  
      EndIf
    EndIf  
    ProcedureReturn szOut
  EndIf
  
  ProcedureReturn #False
  
  DataSection
    Key:
      Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $06
  
    InitializationVector:
      Data.b $3d, $af, $ba, $42, $9d, $9e, $b4, $30, $b4, $22, $da, $80, $2c, $9f, $ac, $41
  EndDataSection
EndProcedure
Procedure bAES64enc(*inData, *outData, szIn, Bits = 256) ;inData - BinaryMem, outData - AESEnc&BasedEncMem
  If szIn > 0
    *AESenc = AllocateMemory(4096)
    szAESenc =  aesNCoder(*inData, *AESenc, szIn, Bits)
    If szAESenc > 0
      encoData$ = Base64Encoder(*AESenc, szAESenc)
      szEncodata = StringByteLength(encoData$, #PB_UTF8)
      If szEncodata > 0 
        PokeS(*outData, encoData$, szEncodata, #PB_UTF8)
        RET = szEncodata
      EndIf  
    EndIf  
    FreeMemory(*AESenc)
  EndIf
  ProcedureReturn RET
EndProcedure
Procedure bAES64dec(*inData, *outData, szIn, Bits = 256) ;inData - BasedMem, outData - BaseDec&AESDecMem
  If szIn > 0
    inData$ = PeekS(*inData, szIn, #PB_UTF8)
    *AESdec = AllocateMemory(4096)
    szoutData = Base64Decoder(inData$, *AESdec, szIn)
    If szoutData > 0
      szoutData - SizeOf(byte)
      szAESdec =  aesDCoder(*AESdec, *outData, szoutData, Bits)
    EndIf
    FreeMemory(*AESdec)
  EndIf  
  ProcedureReturn szAESdec
EndProcedure
;{ 
*BAESenc = AllocateMemory(2048)
*BAESdec = AllocateMemory(2048)

For ii = 1 To 1024
  rawstring.s = LSet("",ii,Chr(Random(126,33)))
  *rawData = UTF8(rawstring)
  szRaw = MemorySize(*rawData)
  szBAESenc = bAES64enc(*rawData, *BAESenc, szRaw)
  If szBAESenc > 0
    BAESenc$ = PeekS(*BAESenc, szBAESenc, #PB_UTF8)
    szBAESdec = bAES64dec(*BAESenc, *BAESdec, szBAESenc)
    If szBAESdec > 0 
      BAESdec$ = PeekS(*BAESdec, szBAESdec, #PB_UTF8)
      If BAESdec$ <> rawstring ; hmm something went wrong but Y?
        i + 1
        Debug "lup: " + Str(ii) + " : " + Str(i) + " : NOK : " + rawstring + " sz: " + Str(szBAESenc) + " base64enc: " + BAESenc$  + " sz: " + Str(szBAESdec) + " base64dec: " + BAESdec$
      Else  ; Everything goes fine
        ; working codepiece  
      EndIf
    EndIf  
  EndIf  
    
  FreeMemory(*rawData)
  
  Delay(10)
Next
;}

But for unknown reason when input memory size is relative bytes the code begins mulfunctioning.
I used MOD() to relate input bytes causing functional disorder and will be veeeery glad to understand the reason of such behaviour.
User avatar
Kiffi
Addict
Addict
Posts: 1484
Joined: Tue Mar 02, 2004 1:20 pm
Location: Amphibios 9

Re: AES+Base64 encryption

Post by Kiffi »

At first glance, donnowha2nput1 (donnowha2input1) and donnowha2nput2 (donnowha2input2) are potential typos.
Hygge
Little John
Addict
Addict
Posts: 4775
Joined: Thu Jun 07, 2007 3:25 pm
Location: Berlin, Germany

Re: AES+Base64 encryption

Post by Little John »

Kiffi wrote: Thu Aug 24, 2023 8:31 am At first glance, donnowha2nput1 (donnowha2input1) and donnowha2nput2 (donnowha2input2) are potential typos.
I wonder why people post 150+ lines of code without EnableExplicit on the forum ...
LiK137
Enthusiast
Enthusiast
Posts: 282
Joined: Wed Jun 23, 2010 5:13 pm

Re: AES+Base64 encryption

Post by LiK137 »

Kiffi, You are right but useless in my case but thanx.
Same for Little John and again thanx.

For your convenience, I made corrections according to Your recommendations, and below is the updated code with explicit and typofree. If remove debugs and blank lines it will be less than 150 lines.
Thanks for your replies and recommendations

Code: Select all

;{ bAES64
EnableExplicit
#paData = "#@!$%^&*()(*&^%$!@#"

Procedure aesNCoder(*inData, *outData, szIn, Bits = 256)
  Define szinData, paDataLen, RET
  szinData + szIn
  If szinData  < 18
    paDataLen = StringByteLength(#paData, #PB_UTF8)
  EndIf
  
  Define *tmp = AllocateMemory(szinData + SizeOf(byte) + paDataLen), *tmp2
  
  CopyMemory(*inData, *tmp, szinData)
  
  If szinData  < 18
    PokeS(*tmp + szinData, #paData, paDataLen, #PB_UTF8)
    szinData + paDataLen
  EndIf
  
  Define errMod = Mod(szinData, 16) + 16               ; this errMod variable shows how different data size related to each other
  If errMod = 31                                ; Observed that errMod with value 31 makes encryption invalid
    If AESEncoder(*tmp, *outData, szinData, ?Key, Bits, ?InitializationVector)
      *tmp2 = AllocateMemory(szinData + SizeOf(byte) + paDataLen)
      If AESDecoder(*outData, *tmp2, szinData, ?Key, Bits, ?InitializationVector)
        If CompareMemory(*tmp, *tmp2, szinData)
          RET = szinData 
;           ShowMemoryViewer(*tmp2, szinData)
;           MessageRequester("","b: " + Str(szinData))
        EndIf  
      EndIf
      FreeMemory(*tmp2)
    EndIf
  Else             ; or errMod = 16                                    ; + Observed that errMod with value 16 (and 31) makes encryption invalid                                 ; This is normaly working except 16 cases
    If AESEncoder(*tmp, *outData, szinData + SizeOf(byte), ?Key, Bits, ?InitializationVector)
      *tmp2 = AllocateMemory(szinData + SizeOf(byte) + paDataLen)
      If AESDecoder(*outData, *tmp2, szinData + SizeOf(byte), ?Key, Bits, ?InitializationVector)
        If CompareMemory(*tmp, *tmp2, szinData)
          RET = szinData 
;           ShowMemoryViewer(*tmp2, szinData)
;           MessageRequester("","c: " + Str(szinData))
        EndIf  
      EndIf
      FreeMemory(*tmp2)
    EndIf
  EndIf
  
  FreeMemory(*tmp)
  
  ProcedureReturn RET
  
  DataSection
    Key:
      Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $06
  
    InitializationVector:
      Data.b $3d, $af, $ba, $42, $9d, $9e, $b4, $30, $b4, $22, $da, $80, $2c, $9f, $ac, $41
  EndDataSection
EndProcedure
Procedure aesDCoder(*inData, *outData, szIn, Bits = 256)
  Define szOut, errMod, paDataLen 
  Define *tmp
  
  szOut + szIn
  If AESDecoder(*inData, *outData, szOut + SizeOf(byte), ?Key, Bits, ?InitializationVector)
    errMod = Mod(szOut, 16) + 16 ; this errMod variable shows how different data size related to each other
    If PeekA(*outData + szOut) = 35 Or errMod = 31                 ; + Observed that errMod with value 31 (and 30) makes encryption invalid
      paDataLen = StringByteLength(#paData, #PB_UTF8)
      *tmp = AllocateMemory(paDataLen + SizeOf(byte))
      PokeS(*tmp, #paData, paDataLen, #PB_UTF8)
      
      If CompareMemory(*outData + szOut - 19, *tmp, 19)
        szOut - 19
      EndIf
      
;       ShowMemoryViewer(*outData, szOut + 1)
;       MessageRequester("","D: " + Str(szOut + 1))
      
      FreeMemory(*tmp)
    ElseIf errMod = 30  ; it is strange behaviour that when input data size constantly affects and breakes encoding/decoding. Observed that errMod with value 30 (and 31) makes encryption invalid
      If AESDecoder(*inData, *outData, szOut, ?Key, Bits, ?InitializationVector)
        If PeekA(*outData + szOut) = 35
          paDataLen = StringByteLength(#paData, #PB_UTF8)
          *tmp = AllocateMemory(paDataLen + SizeOf(byte))
          PokeS(*tmp, #paData, paDataLen, #PB_UTF8)
          
          If CompareMemory(*outData + szOut - 19, *tmp, 19)
            szOut - 19
          EndIf
          FreeMemory(*tmp)
        EndIf
      EndIf  
      
;       ShowMemoryViewer(*outData, szOut)
;       MessageRequester("","E: " + Str(szOut))
      
    EndIf  
    ProcedureReturn szOut
  EndIf
  
  ProcedureReturn #False
  
  DataSection
    Key:
      Data.b $06, $a9, $21, $40, $36, $b8, $a1, $5b, $51, $2e, $03, $d5, $34, $12, $00, $06
  
    InitializationVector:
      Data.b $3d, $af, $ba, $42, $9d, $9e, $b4, $30, $b4, $22, $da, $80, $2c, $9f, $ac, $41
  EndDataSection
EndProcedure
Procedure bAES64enc(*inData, *outData, szIn, Bits = 256) ;inData - BinaryMem, outData - AESEnc&BasedEncMem
  Define *AESenc = AllocateMemory(64 + szIn), 
         *AESdec
    Define encoData$, szoutData, szEncodata, RET,
           szAESenc =  aesNCoder(*inData, *AESenc, szIn, Bits)
    If szAESenc > 0
      encoData$ = Base64Encoder(*AESenc, szAESenc, #PB_Cipher_NoPadding)
      *AESdec =  AllocateMemory(64 + szIn)
      szoutData = Base64Decoder(encoData$, *AESdec, 64 + szIn)
      If CompareMemory(*AESdec, *AESenc, szIn) <> 0
        szEncodata = StringByteLength(encoData$, #PB_UTF8)
        If szEncodata > 0 
          PokeS(*outData, encoData$, szEncodata, #PB_UTF8)
          RET = szEncodata
        EndIf  
      EndIf  
      FreeMemory(*AESdec)
    EndIf  
    FreeMemory(*AESenc)
  ProcedureReturn RET
EndProcedure
Procedure bAES64dec(*inData, *outData, szIn, Bits = 256) ;inData - BasedMem, outData - BaseDec&AESDecMem
    Define inData$ = PeekS(*inData, szIn, #PB_UTF8)
    Define *AESdec = AllocateMemory(64 + szIn)
    Define szoutData = Base64Decoder(inData$, *AESdec, 64 + szIn), 
           szAESdec
    If szoutData > 0
      szAESdec =  aesDCoder(*AESdec, *outData, szoutData - SizeOf(byte), Bits) ; 
;       ShowMemoryViewer(*outData, szoutData)
;       MessageRequester("", "F: " + Str(szAESdec + 1))
    EndIf
    FreeMemory(*AESdec)
  ProcedureReturn szoutData
EndProcedure

Procedure test(*rawData, *BAESenc, *BAESdec, szRaw, rawstring.s)
  Define szBAESenc = bAES64enc(*rawData, *BAESenc, szRaw),
         BAESenc$ = PeekS(*BAESenc, szBAESenc, #PB_UTF8),
         szBAESdec = bAES64dec(*BAESenc, *BAESdec, szBAESenc), 
         BAESdec$
  If szBAESdec > 0 
    BAESdec$ = PeekS(*BAESdec, szBAESdec, #PB_UTF8)
    If BAESdec$ <> rawstring ; hmm something went wrong but Y?
      ProcedureReturn #False        
    Else  ; Everything goes fine
          ; working codepiece  
      ProcedureReturn #True
    EndIf
  EndIf  
EndProcedure  

;{ 
Define *BAESenc = AllocateMemory(2048),
       *BAESdec = AllocateMemory(2048), 
       *rawData

Define ii, itm, rawstring.s, szRaw, RET

For ii = 1 To 1024
  rawstring.s = LSet("",ii,Chr(Random(126,33)))
  *rawData = UTF8(rawstring)
  szRaw = MemorySize(*rawData)
  
  RET = test(*rawData, *BAESenc, *BAESdec, szRaw, rawstring.s)
  If RET = #False
    itm + 1
    Debug "NOK   lup: " + Str(ii) + "  itm: " + Str(itm) + "  rawString: " + rawstring + " szRaw: " + Str(szRaw)
  EndIf  
  
  FreeMemory(*rawData)
  
  Delay(10)
Next

FreeMemory(*BAESenc)
FreeMemory(*BAESdec)

;}
Post Reply