Page 1 of 3

example of trivial text encoding/decoding for ascii strings

Posted: Thu Apr 07, 2016 8:51 pm
by Bo Marchais
I am sure this has been written 10,000 times before but...

Purebasic exposes your text strings to anyone who wishes to open your .exe in an editor such as notepad++ or a hex editor.

Sometimes we don't want people to see what strings are present in our program.
Eventually most professionals use an outside tool to compile local strings into data,
then decompress/decode them at runtime. For everyone else, I present some trivial
encoding and decoding examples.

hmmmm....
It wouldn't be difficult to have the compiler do the encoding for you in a
manner that encodes your strings when compiling, and then at runtime
decodes them (during a string assignment)...

as in:
f$ = "error message that you cannot hide" <--- what you see is what you get
vs.
f$ = obfuscate("error message you dont want to expose") <---encoded at compile, decoded at run

I think maybe it's a useful trick with more applications...

Anyway, here is an example of simple rolling encryption on ascii text.
Once you've encoded the text, you can cut and paste and assign it to a variable,
so that it is hidden in plain sight but also easily decoded at run time.

2016-04-08 : Edited to show examples of procedures for this. The learner version is still below...

Code: Select all

		Procedure.s		rc_encode(string$,salt)
			For i = 1 To Len(string$)
				encoded$ + Right("00"+UCase(Hex(Asc(Mid(string$,i,1)) ! ((salt+i)%256),#PB_Byte)),2)
			Next
			ProcedureReturn	encoded$	
		EndProcedure
		
		
		Procedure.s		rc_decode(string$,salt)
			For i = 1 To (Len(string$)/2)
				ptr = ((i-1)*2)+1 : decoded$ + Chr(Val("$"+Mid(string$,ptr,2)) ! ((salt+i)%256))							
			Next
			ProcedureReturn	decoded$	
		EndProcedure

# example of usage - just cut and paste to see how it works

		salt = 65342		; can be any int from 0-65535
		input$ = "It might be useful..."
		 junk$ = rc_encode(input$,salt)
		output$ = rc_decode(junk$,salt) 
		Debug "SOURCE: "+input$
		Debug "CIPHER: "+junk$
		Debug "OUTPUT: "+output$
		
----

The code is just a way to illustrate the concept. You could also use this to save strings to disk,
or to send them in plaintext via email, web or network transfer. Enjoy!

Warning: This is not crypto... it's just a way to make plain text not so plain. It's not suitable for important data.
This is VERY vulnerable to anyone with even basic crypto knowledge or even if they've heard of Alan Turing.
ALL it does is hide plain text in plain sight!

Code: Select all

string$ = "I am just a simple test of an inefficient algorithm on a string with an embedded CR inside! "+Chr(13)+"Yes, a test!"

Debug "Let's get started!"
Debug "Text to encode. Notice that the example has two lines..."
Debug "---"
Debug string$
Debug "---"

; ---- begin encoding

		salt = 21762										; should be a hash but 0-65535 is fine
		strlen = Len(string$)
		charcount = 0
                output$=""
		For i = 1 To strlen									; this is just an example - we don't care
			                                 							; what the internal representation is. 
			ab$ = Mid(string$,charcount,1)						; use word instead of bytes for unicode
			a.b = Asc(ab$)
			b.b = ((salt+i) % 256) 								; weak salt makes it harder to decode
			c = a ! b										; (in assembly language this is trivial!)
			d$ = Right("00"+UCase(Hex(c,#PB_Byte )),2)
			output$ + d$
		Next
	
; ---- all done encoding
		
		Debug "encodng "+Str(strlen)+" chars with rolling XOR encryption and a weak salt."
		
		Debug "--------"
		Debug "Here's what comes out. This is what would be "
		Debug "seen by a user poking around in the .exe: "
		Debug makeitpretty(output$)+Chr(13)
		Debug "--------"
		
		string$ = output$										; copy encoded string into input
		output$ = "";										; and reset output
		
		; ---- let's decode	this
		
		strlen = Int((Len(string$)+1)/2)
		charcount = 0
		For i = 0 To strlen									; reverse the process
												
			pos = 1 + (i*2)
			ab$ = "$"+Mid(string$,pos,2)							; word instead of bytes for unicode
			a.b = Val(ab$)
			b.b = ((salt+i+1) % 256)	 						; n % 65536	for unicode. 
			c = a ! b
			output$ + Chr(c)
		Next
; ---- all done decoding
		
		Debug "This is the decoded output, ready for use!:"
		Debug output$
		
		

Re: example of trivial text encoding/decoding for ascii stri

Posted: Thu Apr 07, 2016 9:22 pm
by idle
here's a slightly reduced version for you to look over

[edited] to what keya said

Code: Select all


Procedure EncDec(*string,len,salt) 
  Protected *char.ascii
  *char = *string 
  For i = 1 To len                           
    *char\a ! ((salt+i) % 256) 
    *char+1
  Next
EndProcedure 
  

string$ = "I am just a simple test of an inefficient algorithm on a string with an embedded CR inside! "+Chr(13)+"Yes, a test!"

salt = 21762                             
strlen = StringByteLength(string$)

EncDec(@string$,strlen,salt) 

Debug string$ 

EncDec(@string$,strlen,salt)

Debug string$ 


Re: example of trivial text encoding/decoding for ascii stri

Posted: Thu Apr 07, 2016 9:27 pm
by Keya
change "Protected *char.char" to "Protected *char.Ascii" and you can get rid of the Structure :D

Re: example of trivial text encoding/decoding for ascii stri

Posted: Thu Apr 07, 2016 9:40 pm
by idle
I posted to quick, this is what I meant

Code: Select all

Structure char 
  a.a[0]
EndStructure   

Procedure EncDec(*string,len,salt) 
  Protected *char.char 
  *char = *string 
  For i = 0 To len-1                           
    *char\a[i] ! ((salt+i) % 256) 
  Next
EndProcedure 
  

string$ = "I am just a simple test of an inefficient algorithm on a string with an embedded CR inside! "+Chr(13)+"Yes, a test!"
salt = 21762                             
strlen = StringByteLength(string$)

EncDec(@string$,strlen,salt) 
Debug string$ 

EncDec(@string$,strlen,salt)
Debug string$ 


Re: example of trivial text encoding/decoding for ascii stri

Posted: Thu Apr 07, 2016 10:32 pm
by Bo Marchais
yowza!
My examples were optimized for newbies - and are subtly different from yours.

I added the ascii hex conversions on purpose so that the data path could be
treated as ordinary ASCII text - it might not be 8 bit clean from start to stop.
But as far as rolling xor cipher inverters go... that's some amazingly sexy code!
Well done! Code golf in PB... oh yeah!

Re: example of trivial text encoding/decoding for ascii stri

Posted: Fri Apr 08, 2016 6:26 am
by Marc56us
Not very secure, but fast (to mislead newbies), internal function: ReverseString()

Code: Select all

; Debug ReverseString("I am just a simple test of an inefficient algorithm on a string With an embedded CR inside! "+Chr(13)+"Yes, a test!")
In code

Code: Select all

Hello.s = ReverseString("tset a ,seY"+Chr(13)+" !edisni RC deddebme na htiW gnirts a no mhtirogla tneiciffeni na fo tset elpmis a tsuj ma I")

MessageRequester("Hello", Hello)
Avoid using '$' for strings still prefer '.s' to complicate hexa search.

:wink:

Re: example of trivial text encoding/decoding for ascii stri

Posted: Fri Apr 08, 2016 7:37 am
by Keya
Marc56us wrote:Avoid using '$' for strings still prefer '.s' to complicate hexa search.
:wink:
can you elaborate please? the following code:

Code: Select all

test1.s = "APPLE"
test2$ = "ORANGE"
doesn't complicate a hex search:
Image

no comment on ReverseString() :)

Re: example of trivial text encoding/decoding for ascii stri

Posted: Fri Apr 08, 2016 11:38 pm
by Bo Marchais
Yes, reversing a string doesn't work - human brains are just too clever at
spotting patterns.
Lots of bright people think to open an .exe in a text editor or hex editor.

This works very well to let you bury random text. It's not good enough to
hide cc data or secrets, but it'll keep your little sister out of your to do list.
It is only a cipher, and not crpto.

Did I mention you can encode or decode 2 or 3 times? And that text files
zip or compress really well? And that you can use the encode function to
turn binary data to text? Or you can zip data, then encode the zip... all
quite pointless from a real crypto standpoint, but it'll probably slow down
anybody who isn't very good at math.

Now... if that salt was to get jiggy, or you added a 3rd or 4th term to
the xor... well, to quote my favorite waiter: that's a story for another time.
But never forget - debuggers reveal secrets. Create your salt at runtime
and make it unique if you're building a game or something... otherwise the
other kids will figure out your cheat codes. And then where will you be?

Re: example of trivial text encoding/decoding for ascii stri

Posted: Sat Apr 09, 2016 9:40 am
by walbus
Or so :

But, this are all very bad ideas :idea: LOL

Code: Select all


Structure char : a.a[0] : EndStructure 

Procedure EncDec(*string.char,len,salt) 
  For i = 0 To len-1 : *string\a[i] ! ((salt+i) % 256) : Next
EndProcedure 
  
string$ = "I am just a simple test of an inefficient algorithm on a string with an embedded CR inside! "+Chr(13)+"Yes, a test!"
salt = 21762                             
strlen = StringByteLength(string$)

EncDec(@string$,strlen,salt) 
Debug string$ 

EncDec(@string$,strlen,salt)
Debug string$ 

Re: example of trivial text encoding/decoding for ascii stri

Posted: Sat Apr 09, 2016 10:00 am
by Keya
with a lot of these types of encodings it seems there's only 255 possible decodings, i think it would be cool to achieve 32bit possible decodings, if it can still be kept as simple of course :) (and can that still be accomplished one byte at a time or would it have to require operating on 32bits at a time and therefore have undesired boundary or padding requirements?)

Re: example of trivial text encoding/decoding for ascii stri

Posted: Sat Apr 09, 2016 10:15 am
by wilbert
If you want to keep the result a string, it's important that no zero character is generated as result of the encoding.
The whole idea of 32 bits, is to make things faster by processing 32 bits at a time.
If you want to make it more complicated, you can xor the data against the output of a pseudo random generator (or add / sub instead of xor).

Re: example of trivial text encoding/decoding for ascii stri

Posted: Sat Apr 09, 2016 12:44 pm
by walbus
False or missing termination is a trap and can make many nasty bugs.
A other thing is, PB supporting in the future only Unicode.
It is very important to learning and making string handling all over in Unicode.

Re: example of trivial text encoding/decoding for ascii stri

Posted: Sat Apr 09, 2016 4:24 pm
by Bo Marchais
Nah, modern chars sets are easy and will just make the encoded data larger.
It's easy to change this to use words instead of bytes, just see the learner version and change the .b to .w
and change the modulo to 65536 from 256.

Everyone keeps missing that while xor alone works great, the actual application requires conversion into hex
so that the data can be embedded as ordinary string data. You can use base36 or base64(using upper,lower,
nums and punctuation) to slightly decrease the message size using 3 chars instead of 4 PLUS you get the
ability to encode/decode escape sequences or out of band information.

This is still not safe for real crypto purposes. However, it's great fun to use base64 and alter your encodings
(salt/key/whatever) on the fly using escape sequences. One weakness is that character sets are not really
very hard to spot, even in a rolling cipher. This kind of thing is pretty similar to a simple enigma box and can
often be decoded using only paper and pencil. You have to add a lot of rotors and move them on the fly to
slow anyone down...and again, anyone with access to the .exe can undo your clever scheme.

The problem is that no matter how smart you are, there are smarter people out there somewhere.
Hopefully your customers won't be interested enough to waste even a few hours to undo your work.
Security is a rabbit hole and it goes a long way down. I don't lose sleep worrying about it. My rule is:
if it costs more to reverse it than ~70% of the product cost, no one will bother unless it's a game or
your program is really popular!

Re: example of trivial text encoding/decoding for ascii stri

Posted: Sat Apr 09, 2016 5:02 pm
by walbus
Basexx make the strings longer !
So you must ever use padding for encoding and decoding !

You must also ever use padding with Basexx,
Then you can use many better a very good block chiffre,

Re: example of trivial text encoding/decoding for ascii stri

Posted: Sat Apr 09, 2016 5:14 pm
by heartbone
Thanks for this thread and its code contributors. :thumbs up: