Page 1 of 2

I miss something with Base64 and AES.

Posted: Tue Apr 15, 2025 4:46 pm
by doctorized
I use the following code to encrypt some text:

Code: Select all

str$="some text"
size = StringByteLength(str$)+2
*buf = AllocateMemory(size)
*out = AllocateMemory(size)
size2 = size*1.5
PokeS(*buf,str$,size)
AESEncoder(*buf,*out,size,?key,256,?iv,#PB_Cipher_CBC)
Encoded$ = Base64Encoder(*out, size)
Debug Encoded$
FreeMemory(*buf)
FreeMemory(*out)
After that, I copy paste that text in a php file that contains only an echo command to get the encrypted string. I try to decode it as follows:

Code: Select all

*Buffer = ReceiveHTTPMemory("the_link")
If *Buffer
	str$ = PeekS(*Buffer, Size, #PB_UTF8|#PB_ByteLength)
	Debug str$ 
	size = Len(str$)
	*buf = AllocateMemory(size)
	*out = AllocateMemory(size)
	size = Base64Decoder(str$, *buf, size)
	AESDecoder(*buf,*out,size,?key,256,?iv,#PB_Cipher_CBC); key and iv are in DataSection
	Debug "Content: " + PeekS(*out)
EndIf
I feel that it has something to do with formatting (UTF8, ASCII etc) but what?

Re: I miss something with Base64 and AES.

Posted: Tue Apr 15, 2025 7:04 pm
by NicTheQuick
There are a few things missing to test the code:

Code: Select all

str$="some text"
size = StringByteLength(str$)+2
*buf = AllocateMemory(size)
*out = AllocateMemory(size)
size2 = size*1.5	;<< why?
PokeS(*buf,str$,size) ;<< PokeS needs the string length in characters, not the size in bytes
AESEncoder(*buf,*out,size,?key,256,?iv,#PB_Cipher_CBC) ;<< ?key and ?iv are missing to test the code
Encoded$ = Base64Encoder(*out, size)
Debug Encoded$
FreeMemory(*buf)
FreeMemory(*out)
Also it could be written a bit easier:

Code: Select all

str$ = "some text"
size = StringByteLength(str$) + 2
*out = AllocateMemory(size)
AESEncoder(@str$, *out, size, ?key, 256, ?iv, #PB_Cipher_CBC) ;<< ?key and ?iv are missing to test the code
Encoded$ = Base64Encoder(*out, size)
FreeMemory(*out)
Debug Encoded$
On your decoding side PeekS is wrong:

Code: Select all

str$ = PeekS(*Buffer, Size, #PB_UTF8 | #PB_ByteLength) ;<< Size is never set anywhere
Everything else looks good so far. It would be better if you would actually post a working example code.

Re: I miss something with Base64 and AES.

Posted: Tue Apr 15, 2025 7:30 pm
by doctorized
NicTheQuick wrote: Tue Apr 15, 2025 7:04 pm It would be better if you would actually post a working example code.
Ok. At first, we have:
str$ = "Some text to test. Some text too."
size = StringByteLength(str$) + 2
*out = AllocateMemory(size)
AESEncoder(@str$, *out, size, ?key, 256, ?iv, #PB_Cipher_CBC)
Encoded$ = Base64Encoder(*out, size)
FreeMemory(*out)
Debug Encoded$

DataSection
key:
Data.a $97, $74, $91, $AC, $85, $CF, $CA, $37, $B7, $20, $B2, $FD, $D0, $97, $39, $4F, $BE, $E1, $C7, $C1, $B3, $50, $2C, $6C, $F6, $D4, $9A, $E3, $5A, $E1, $40, $AC
iv:
Data.a $86, $43, $1A, $35, $61, $C9, $8A, $E2, $EF, $7C, $49, $8C, $E6, $F4, $6A, $02
EndDataSection
The result is uploaded inside a php file with the content:

Code: Select all

<?php
echo "iV7bpLUqiqGhk/1B/ArzzUnr9sqxVHRdkDks95cT+iZ4jRZx6Qj8hZbKny5egUWIr2BCB/YTglNQjZZYBP+jW5EPZtU=";
?>
We get it to decode:

Code: Select all

*Buffer = ReceiveHTTPMemory("https://arahiotis.sites.sch.gr/PB/update.php")
If *Buffer
	size = MemorySize(*Buffer)
 
	str$ = PeekS(*Buffer, size, #PB_UTF8|#PB_ByteLength)
	Debug str$ 
	
	size = Len(str$)
	Debug "size 1 = " + Str(size)
	*buf = AllocateMemory(size)
	*out = AllocateMemory(size)
	size = Base64Decoder(str$, *buf, size)
	Debug "size 2 = " + Str(size)
	AESDecoder(*buf,*out,size,?key2,256,?iv2,#PB_Cipher_CBC)
	
	Debug "Content: " + PeekS(*out)
EndIf

Re: I miss something with Base64 and AES.

Posted: Tue Apr 15, 2025 8:08 pm
by Caronte3D
Not sure but... Don't you need StringByteLength() instead of Len() for the AllocateMemory()?

Re: I miss something with Base64 and AES.

Posted: Tue Apr 15, 2025 8:32 pm
by Quin
Caronte3D wrote: Tue Apr 15, 2025 8:08 pm Not sure but... Don't you need StringByteLength() instead of Len() for the AllocateMemory()?
Yes

Re: I miss something with Base64 and AES.

Posted: Tue Apr 15, 2025 9:58 pm
by AZJIO
Why don't you check the result of AESEncoder?

Code: Select all

If AESEncoder(...
Why don't you check the result of Allocatemory?

Code: Select all

*MemoryID = AllocateMemory(5000)
If *MemoryID
You insert the line #PB_Unicode

Code: Select all

PokeS(*buf,str$,size)
You read the line #PB_UTF8

Code: Select all

str$ = PeekS(*Buffer, size, #PB_UTF8|#PB_ByteLength)
Base64encoder returns the result in Latin symbols, so you do not need #PB_UTF8 and #PB_Unicode, you need #PB_Ascii to read the line of the result Base64encoder

Re: I miss something with Base64 and AES.

Posted: Wed Apr 16, 2025 8:25 am
by NicTheQuick
For me the code works as expected if I simulate the PHP-Script by just copy-pasting the result from the first code into the second one:

Code: Select all

str$ = "Some text to test. Some text too."
size = StringByteLength(str$) + 2
*out = AllocateMemory(size)
If AESEncoder(@str$, *out, size, ?key, 256, ?iv, #PB_Cipher_CBC)
	Encoded$ = Base64Encoder(*out, size)
	Debug Encoded$
Else
	Debug "Error"
EndIf
FreeMemory(*out)


DataSection
	key:
	Data.a $97, $74, $91, $AC, $85, $CF, $CA, $37, $B7, $20, $B2, $FD, $D0, $97, $39, $4F, $BE, $E1, $C7, $C1, $B3, $50, $2C, $6C, $F6, $D4, $9A, $E3, $5A, $E1, $40, $AC
	iv:
	Data.a $86, $43, $1A, $35, $61, $C9, $8A, $E2, $EF, $7C, $49, $8C, $E6, $F4, $6A, $02
EndDataSection
Result in:
iV7bpLUqiqGhk/1B/ArzzUnr9sqxVHRdkDks95cT+iZ4jRZx6Qj8hZbKny5egUWIr2BCB/YTglNQjZZYBP+jW5EPZtU=
Now put it into the second code:

Code: Select all

s.s = "iV7bpLUqiqGhk/1B/ArzzUnr9sqxVHRdkDks95cT+iZ4jRZx6Qj8hZbKny5egUWIr2BCB/YTglNQjZZYBP+jW5EPZtU="


;*Buffer = ReceiveHTTPMemory("https://arahiotis.sites.sch.gr/PB/update.php")
If #True ;*Buffer
	;size = MemorySize(*Buffer)
	
	;str$ = PeekS(*Buffer, size, #PB_UTF8|#PB_ByteLength)
	str$ = "iV7bpLUqiqGhk/1B/ArzzUnr9sqxVHRdkDks95cT+iZ4jRZx6Qj8hZbKny5egUWIr2BCB/YTglNQjZZYBP+jW5EPZtU="
	Debug str$ 
	
	size = Len(str$)
	Debug "size 1 = " + Str(size)
	*buf = AllocateMemory(size)
	*out = AllocateMemory(size)
	size = Base64Decoder(str$, *buf, size)
	Debug "size 2 = " + Str(size)
	AESDecoder(*buf,*out,size,?key,256,?iv,#PB_Cipher_CBC)
	
	Debug "Content: " + PeekS(*out)
EndIf


DataSection
	key:
	Data.a $97, $74, $91, $AC, $85, $CF, $CA, $37, $B7, $20, $B2, $FD, $D0, $97, $39, $4F, $BE, $E1, $C7, $C1, $B3, $50, $2C, $6C, $F6, $D4, $9A, $E3, $5A, $E1, $40, $AC
	iv:
	Data.a $86, $43, $1A, $35, $61, $C9, $8A, $E2, $EF, $7C, $49, $8C, $E6, $F4, $6A, $02
EndDataSection
Results in:
iV7bpLUqiqGhk/1B/ArzzUnr9sqxVHRdkDks95cT+iZ4jRZx6Qj8hZbKny5egUWIr2BCB/YTglNQjZZYBP+jW5EPZtU=
size 1 = 92
size 2 = 68
Content: Some text to test. Some text too.
But it also works with the PHP output. So the issue seems solved to me. I don't see any errors.
AZJIO wrote: Tue Apr 15, 2025 9:58 pm You insert the line #PB_Unicode

Code: Select all

PokeS(*buf,str$,size)
You read the line #PB_UTF8

Code: Select all

str$ = PeekS(*Buffer, size, #PB_UTF8|#PB_ByteLength)
Base64encoder returns the result in Latin symbols, so you do not need #PB_UTF8 and #PB_Unicode, you need #PB_Ascii to read the line of the result Base64encoder
This is no problem here. He encrypts the string in its Unicode form and after decrypting he also uses a simple PeekS() to catch the string.

Re: I miss something with Base64 and AES.

Posted: Wed Apr 16, 2025 8:31 am
by infratec
Best is: use the UTF8() procedure to generate the buffer.

And ... keep in mind the terminating 0
PHP normally don't include a 0 at the end.

Re: I miss something with Base64 and AES.

Posted: Wed Apr 16, 2025 8:42 am
by AZJIO
NicTheQuick wrote: Wed Apr 16, 2025 8:25 am This is no problem here. He encrypts the string in its Unicode form and after decrypting he also uses a simple PeekS() to catch the string.
Theoretically, Latin letters will read correctly, but this is not a line UTF8

Code: Select all

str$ = PeekS(*Buffer, size, #PB_UTF8|#PB_ByteLength)
"Size" - is it correct? There is added "=" and the size differs from the length of the initial line

Re: I miss something with Base64 and AES.

Posted: Wed Apr 16, 2025 9:22 am
by NicTheQuick
infratec wrote: Wed Apr 16, 2025 8:31 am Best is: use the UTF8() procedure to generate the buffer.

And ... keep in mind the terminating 0
PHP normally don't include a 0 at the end.
This is irrelevant. Sure. You can convert the content to UTF8 before encrypting and encoding it to Base64. But it makes no difference with respect to PHP.
And yes, PHP usually outputs as UTF-8 per default nowadays. But as you can see in the code doctorized uses PeekS() properly with the size parameter and the correct flags, which works fine with a missing terminating null byte/character.

Re: I miss something with Base64 and AES.

Posted: Wed Apr 16, 2025 9:26 am
by NicTheQuick
AZJIO wrote: Wed Apr 16, 2025 8:42 am
NicTheQuick wrote: Wed Apr 16, 2025 8:25 am This is no problem here. He encrypts the string in its Unicode form and after decrypting he also uses a simple PeekS() to catch the string.
Theoretically, Latin letters will read correctly, but this is not a line UTF8

Code: Select all

str$ = PeekS(*Buffer, size, #PB_UTF8|#PB_ByteLength)
"Size" - is it correct? There is added "=" and the size differs from the length of the initial line
At this point the string contains only valid Base64 characters that are exactly the same in UTF8 and ASCII. So this is totally fine.
What do you mean with "the size differs from the length of the initial line"? The Base64 encoded string has a length of 92 characters. After it is received via ReceiveHTTPMemory() it also has a size of 92 bytes which is the same as 92 characters in ASCII which is the superset of Base64 characters.

Re: I miss something with Base64 and AES.

Posted: Wed Apr 16, 2025 10:12 am
by AZJIO
NicTheQuick wrote: Wed Apr 16, 2025 9:26 am What do you mean with "the size differs from the length of the initial line"? The Base64 encoded string has a length of 92 characters. After it is received via ReceiveHTTPMemory() it also has a size of 92 bytes which is the same as 92 characters in ASCII which is the superset of Base64 characters.
#PB_Cipher_NoPadding: it will not insert additional '=' at the end of the encoded buffer to pad it to 3 bytes boundary.
Apparently the buffer is not equivalent to the length of the line, as it inserts an additional symbol "=".

Re: I miss something with Base64 and AES.

Posted: Wed Apr 16, 2025 10:39 am
by NicTheQuick
AZJIO wrote: Wed Apr 16, 2025 10:12 am
NicTheQuick wrote: Wed Apr 16, 2025 9:26 am What do you mean with "the size differs from the length of the initial line"? The Base64 encoded string has a length of 92 characters. After it is received via ReceiveHTTPMemory() it also has a size of 92 bytes which is the same as 92 characters in ASCII which is the superset of Base64 characters.
#PB_Cipher_NoPadding: it will not insert additional '=' at the end of the encoded buffer to pad it to 3 bytes boundary.
Apparently the buffer is not equivalent to the length of the line, as it inserts an additional symbol "=".
Can you please explain exactly what you mean with that? The padding is totally normal behavior and the flag #PB_Cipher_NoPadding is not used anywhere in the code snippets listed in this thread. As I already said:
NicTheQuick wrote: Wed Apr 16, 2025 9:26 amThe Base64 encoded string has a length of 92 characters. After it is received via ReceiveHTTPMemory() it also has a size of 92 bytes which is the same as 92 characters in ASCII which is the superset of Base64 characters.
Everything's fine here. The code works exactly as expected.

Re: I miss something with Base64 and AES.

Posted: Wed Apr 16, 2025 11:28 am
by AZJIO
How large is the size of the BASE64 compared to the original size?
This means that the version of the string or file BASE64 is usually about a third more than its original size

Re: I miss something with Base64 and AES.

Posted: Wed Apr 16, 2025 11:53 am
by NicTheQuick
AZJIO wrote: Wed Apr 16, 2025 11:28 am How large is the size of the BASE64 compared to the original size?
This means that the version of the string or file BASE64 is usually about a third more than its original size
Why does that matter? Did you execute one of the code snippets posted here? With them you can answer your own question. :wink: