Page 1 of 1

Strange behavior of Base64 or something else?

Posted: Sat Oct 02, 2021 10:54 pm
by doctorized
I have the following code for encrypting passwords. Some basic code as I do not want something more sophisticated. I noticed that the same string can be encrypted with different ways. For example, the word “maria” is initially encrypted as 91HZhhCLHk9CPAAAAAAAAAAAAAA=. But when I try to do the same when the user changes the password and I ask to type the current one, typing “maria” again, gives 91HZhhCLHk9CPAAArgMgAMMDxwM=. In the code below, 91HZhhCLHk9CPAAArgMgAMMDxwM= is decrypted as “maria”. Do I do something wrong or there is something to do with base64 encoding/decoding that I do not know?

Code: Select all

Procedure XOrCrypt(*Buffer,Len.l, KeyS.i, KeyE.i)
  ;just some weird xor encryption algorithm by JLC
  Protected i, Byte.b, KeyByte.b
  Protected KeyLength = KeyE - KeyS, KeyPos
  
  For i=0 To Len-1
    Byte = PeekB(*Buffer+i)
    KeyByte = PeekB(KeyS+KeyPos)
    ;PeekB(*Buffer+i) ! PeekB(@Key$+KeyPos) ! Len ! i
    Byte ! KeyByte ! Len ! i ! KeyLength ;xor the shit
    PokeB(*Buffer+i,Byte)
    KeyPos + 1
    If KeyPos > KeyLength
      KeyPos = 0
    EndIf
  Next
EndProcedure

String$ = "maria"
Length = StringByteLength(String$,#PB_Unicode)
XOrCrypt(@String$,Length,?KeyStart,?KeyEnd) ;encrypt
Length * 2
str$ = Base64Encoder(@String$,Length)
Debug str$

str$ = "91HZhhCLHk9CPAAArgMgAMMDxwM="
Length = StringByteLength(str$,#PB_Unicode)
String2$ = Space(Length)
i = Base64Decoder(str$, @String2$,Length)
i = StringByteLength(String2$,#PB_Unicode)
XOrCrypt(@String2$,i,?KeyStart,?KeyEnd) ;decrypt
Debug String2$
Debug ?KeyEnd - ?KeyStart


DataSection
	KeyStart:
	Data.a $D0, $1A, $F0, $CF, $2C, $C4, $3B, $02, $61, $7F, $9F, $3D, $DB, $6C, $13, $61
	Data.a $53, $15, $6D, $31, $BE, $7C, $42, $8C, $1F, $58, $F7, $A3, $F6, $E3, $3E, $03
	Data.a $5F, $6D, $7B, $56, $CF, $27, $68, $AA, $7C, $0E, $47, $55, $DF, $45, $77, $6E
	Data.a $6E, $9A, $B8, $71, $50, $28, $01, $85, $3C, $F0, $12, $48, $82, $ED, $19, $27
	KeyEnd:
EndDataSection

Re: Strange behavior of Base64 or something else?

Posted: Sun Oct 03, 2021 3:56 am
by idle
not sure what was going on there but doesn't make much sense to xor it with more than just the key.

Code: Select all

Procedure XOrCrypt(*Buffer,Len.l, KeyS.i, KeyE.i)
  ;just some weird xor encryption algorithm by JLC
  Protected i, Byte.b, KeyByte.b
  Protected KeyLength = KeyE - KeyS, KeyPos
  
  For i=0 To Len-1
    Byte = PeekB(*Buffer+i)
    KeyByte = PeekB(KeyS+KeyPos)
    Byte ! KeyByte 
    PokeB(*Buffer+i,Byte)
    KeyPos + 1
    If KeyPos > KeyLength
      KeyPos = 0
    EndIf
  Next
EndProcedure

String$ = "maria"
Length = StringByteLength(String$,#PB_Unicode)
XOrCrypt(@String$,Length,?KeyStart,?KeyEnd) ;encrypt
Length * 2
str$ = Base64Encoder(@String$,Length)
Debug str$

str$ = "91HZhhCLHk9CPAAArgMgAMMDxwM="
Length = StringByteLength(str$,#PB_Unicode)
String2$ = Space(Length)
i = Base64Decoder(str$, @String2$,Length)
i = StringByteLength(String2$,#PB_Unicode)
XOrCrypt(@String2$,i,?KeyStart,?KeyEnd) ;decrypt
Debug String2$
Debug ?KeyEnd - ?KeyStart


DataSection
	KeyStart:
	Data.a $D0, $1A, $F0, $CF, $2C, $C4, $3B, $02, $61, $7F, $9F, $3D, $DB, $6C, $13, $61
	Data.a $53, $15, $6D, $31, $BE, $7C, $42, $8C, $1F, $58, $F7, $A3, $F6, $E3, $3E, $03
	Data.a $5F, $6D, $7B, $56, $CF, $27, $68, $AA, $7C, $0E, $47, $55, $DF, $45, $77, $6E
	Data.a $6E, $9A, $B8, $71, $50, $28, $01, $85, $3C, $F0, $12, $48, $82, $ED, $19, $27
	KeyEnd:
EndDataSection

Re: Strange behavior of Base64 or something else?

Posted: Sun Oct 03, 2021 4:35 am
by kenmo
The first half: Why the Length * 2??? In Base64, all those AAAAA... are 0x00 bytes. You have data that is "Length" bytes, but then you encode "Length * 2" bytes, beyond the end of the string. (Which happens to contain nulls, so you get AAAA....)

The second half: Something similar is going on. "91HZhhCLHk9CPAAArgMgAMMDxwM=" has encoded "maria" then a null terminator (remember in Unicode a null terminator is 2 bytes 0x0000) then some garbage data (spaces?). You can confirm this after the XOR decrypt:

Code: Select all

XOrCrypt(@String2$,i,?KeyStart,?KeyEnd) ;decrypt
ShowMemoryViewer(@String2$, Length) : CallDebugger ; <----- show memory bytes
Debug String2$
Debug ?KeyEnd - ?KeyStart
But when you Debug the string (or PeekS() etc) it will stop at the null terminator ("AAA" in Base64) so you don't see the garbage right away.

I think if you can fix the first part, it will solve the second part?

Re: Strange behavior of Base64 or something else?

Posted: Sun Oct 03, 2021 4:59 am
by kenmo
Try this... converts to Base64 and back to verify.

Code: Select all

Procedure XOrCrypt(*Buffer,Len.l, KeyS.i, KeyE.i)
  ;just some weird xor encryption algorithm by JLC
  Protected i, Byte.b, KeyByte.b
  Protected KeyLength = KeyE - KeyS, KeyPos
  
  For i=0 To Len-1
    Byte = PeekB(*Buffer+i)
    KeyByte = PeekB(KeyS+KeyPos)
    ;PeekB(*Buffer+i) ! PeekB(@Key$+KeyPos) ! Len ! i
    Byte ! KeyByte ! Len ! i ! KeyLength ;xor the shit
    PokeB(*Buffer+i,Byte)
    KeyPos + 1
    If KeyPos > KeyLength
      KeyPos = 0
    EndIf
  Next
EndProcedure

Procedure.s Encrypt(String$)
  If String$
    Length = StringByteLength(String$, #PB_Unicode)
    XOrCrypt(@String$, Length, ?KeyStart, ?KeyEnd)
    ProcedureReturn Base64Encoder(@String$, Length)
  EndIf
EndProcedure

Procedure.s Decrypt(String$)
  Length = Len(String$)
  String2$ = Space(Length/2)
  Length = Base64Decoder(String$, @String2$, Length)
  XOrCrypt(@String2$, Length, ?KeyStart, ?KeyEnd)
  ProcedureReturn String2$
EndProcedure

String$ = InputRequester("Input", "Enter name:", "")
Debug String$
Debug Encrypt(String$)
Debug Decrypt(Encrypt(String$))

DataSection
	KeyStart:
	Data.a $D0, $1A, $F0, $CF, $2C, $C4, $3B, $02, $61, $7F, $9F, $3D, $DB, $6C, $13, $61
	Data.a $53, $15, $6D, $31, $BE, $7C, $42, $8C, $1F, $58, $F7, $A3, $F6, $E3, $3E, $03
	Data.a $5F, $6D, $7B, $56, $CF, $27, $68, $AA, $7C, $0E, $47, $55, $DF, $45, $77, $6E
	Data.a $6E, $9A, $B8, $71, $50, $28, $01, $85, $3C, $F0, $12, $48, $82, $ED, $19, $27
	KeyEnd:
EndDataSection

Re: Strange behavior of Base64 or something else?

Posted: Sun Oct 03, 2021 8:49 am
by doctorized
kenmo wrote: Sun Oct 03, 2021 4:59 am Try this... converts to Base64 and back to verify.
The problem is Length * 2 that you mention. As far as I remember, Base64 functions were different in the past, taking as parameter both input and output parameters. Affected by that, I set Len * 2, having in mind the output string. Thank you very much for your help!!

Re: Strange behavior of Base64 or something else?

Posted: Mon Oct 04, 2021 4:46 am
by kenmo
Yeah, just be careful with Base64 and buffers and strings. There are a lot of "lengths" involved, careful not to mix them up.

example: "maria" is 5 chars (6 if you include null terminator)

in Unicode that is 10 bytes (or 12)

to encode 10 or 12 bytes requires 16 Base64 characters (in Unicode, 16 char string is 32 bytes, plus 2 byte null terminator again)

and a 16-char Base64 string can hold 10, 11, or 12 data bytes (determined by the "=" padding amount at the end)

:)

Re: Strange behavior of Base64 or something else?

Posted: Tue Oct 05, 2021 4:15 am
by sec
kenmo wrote: Mon Oct 04, 2021 4:46 am Yeah, just be careful with Base64 and buffers and strings. There are a lot of "lengths" involved, careful not to mix them up.

example: "maria" is 5 chars (6 if you include null terminator)

in Unicode that is 10 bytes (or 12)

to encode 10 or 12 bytes requires 16 Base64 characters (in Unicode, 16 char string is 32 bytes, plus 2 byte null terminator again)

and a 16-char Base64 string can hold 10, 11, or 12 data bytes (determined by the "=" padding amount at the end)

:)
how can you count those numbers fluency as that? :mrgreen:

Re: Strange behavior of Base64 or something else?

Posted: Thu Oct 07, 2021 3:20 am
by kenmo
@sec :lol: Well, I have written my own Base64 library before
https://github.com/kenmo-pb/includes/bl ... e64Lib.pbi
which @doctorized might be interested in?

(Encode/decode in all directions between strings, memory buffers, and files. Always converts strings to UTF-8 first for results consistent with most other programming languages. Accepts same option flags as the PB encoder too.)