simple but effective encryption in PlayBasic

Started by stratum, October 06, 2005, 04:32:03 AM

Previous topic - Next topic

stratum

This is my first attempt to write a tutorial for PlayBasic.

There comes a time in every programmer that he needs some form of encryption in his or her program even if it is only for encrypting High Score data. More serious examples are licence keys and so on.

I explain here a simple but very effective double encryption technique that I have written for my business programs, written in C# and C++, and now translated in PlayBasic.

The technique is using a cipher routine to calculate encryption and decryption of standard text and a HexIt and StringIt routine to make the encrypted string from the cipher routing into a semi hexadecimal representation. The reason for that is that the encrypted string has, due to the encryption technique, non-printable control characters in it, which are hell to save into a file and by recalculating it to a semi hexadecimal representation we make this easier.

There are two cipher routines which are exactly the same and you could use just one of them but by having two: Encrypt(text) and Decrypt(text) you know exactly which you are performing and this rules mistakes out.

PlayBASIC Code: [Select]
Global key$ = "ej3e438024irfj548rfh4ydj7JS3s*kdj4s8djjAqaWHSY67euhYWh749ijmShjn338456HSDmnKjDnuy836750KSuehsdhgwjjAqaWHSY67euhYWhp;asldijdeijndfbchyrfcnb47u3875835ed3js92jdejhfiwej3e438024irfj548rfjkkajsdiwdhs*kdj4s8djjAqaWHSY67euhYWh749ijmShjn338456HSDmnKjDnuy836750KSuehsdhgwjjAqaWHSY67euhYWhp;asldijdeijndfbchyrfcnb47u3875835ed3js92jdejhfiwej3e438024irfj548rfjkkajsdiwdhej3e438024irfj548rfh4ydj7JS3s*kdj4s8djjAqaWHSY67euhYWh749ijmShjn338456HSDmnKjDnuy836750KSuehsdhgwjjAqaWHSY67euhYWhp;asldijdeijndfbchyrfcnb47u3875835ed3js92jdejhfiwej3e438024irfj548rfjkkajsdiwdhs*kdj4s8djjAqaWHSY67euhYWh749ijmShjn338456HSDmnKjDnuy836750KSuehsdhgwjjAqaWHSY67euhYWhp;asldijdeijndfbchyrfcnb47u3875835ed3js92ej3e438024irfj548rfh4ydj7JS3s*kdj4s8djjAqaWHSY67euhYWh749ijmShjn338456HSDmnKjDnuy836750KSuehsdhgwjjAqaWHSY67euhYWhp;asldijdeijndfbchyrfcnb47u3875835ed3js92jdejhfiwej3e438024irfj548rfjkkajsdiwdhs*kdj4s8djjAqaWHSY67euhYWh749ijmShjn338456HSDmnKjDnuy836750KSuehsdhgwjjAqaWHSY67euhYWhp;asldijdeijndfbchyrfcnb47u3875835ed3js92jdejhfiwej3e438024irfj548rfjkkajsdiwdhej3e438024irfj548rfh4ydj7JS3s*kdj4s8djjAqaWHSY67euhYWh749ijmShjn338456HSDmnKjDnuy836750KSuehsdhgwjjAqaWHSY67euhYWhp;asldijdeijndfbchyrfcnb47u3875835ed3js92jdejhfiwej3e438024irfj548rfjkkajsdiwdhs*kdj4s8djjAqaWHSY67euhYWh749ijmShjn338456HSDmnKjDnuy836750KSuehsdhgwjjAqaWHSY67euhYWhp;asldijdeijndfbchyrfcnb47u3875835ed3js92"

Psub Encrypt(MyText$)
returnValue$ = ""
k = Len(MyText$) * 3

For i = 1 To Len(MyText$)
c = Asc(Mid$(MyText$, i, 1))
If k > Len(key$) Then k = 1
x = c Xor Asc(Mid$(key$, k, 1))
s$ = Chr$(x)
returnValue$ = returnValue$ + s$
Inc k
Next i
EndPsub returnValue$


Psub Decrypt(MyText$)
returnValue$ = ""
k = Len(MyText$) * 3
For i = 1 To Len(MyText$)
c = Asc(Mid$(MyText$, i, 1))
If k > Len(key$) Then k = 1
x = c Xor Asc(Mid$(key$, k, 1))
s$ = Chr$(x)
returnValue$ = returnValue$ + s$
Inc k
Next i
EndPsub returnValue$




Global key$, This is a string of characters that is used to encrypt with. You can put in there what you want and make it as long as PlayBasic allows. The longer and more divers the string is the stronger and more difficult to break the encryption becomes.

I only explain the Encrypt routine because they are the same J

We make it a Psub because this is slightly faster then a function and you will run it completely so a function is not necessary.

Psub Encrypt(MyText$)

MyText$ is the text we want to encrypt

returnValue$ = ""
This is the encrypted string we will give back, initialize it to an empty string

k = Len(MyText$) * 3
k represents the place in the key$ to start using for encryption. I base it on the length of the string. This way we have a rotating encryption and makes it very hard to break a text, especially when it exists out of more strings (lines) because of the difference in length letters will be represented different.
Example:
"Test" if different encrypted then "Testing". In a static encryption method you would have the first four letters of "Testing" the same as the first four letters of "Test". We start on a different place in the key for both words and they are different now.

You can change this in whatever you want to make your encryption routine your own. Please change them the same in both routine or else you are in a mess!

For i = 1 To Len(MyText$)
Loop through the text

c = Asc(Mid$(MyText$, i, 1))[/]
Take a character of the string and make it the decimal ASCII value

If k > Len(key$) Then k = 1
See if the value of k is still within the length of the key$ and if not start at the beginning again

x = c Xor Asc(Mid$(key$, k, 1))
This is the actual encryption! Take a letter of the key$ and make it decimal ASCII value and then XOR it with the character value of the letter of the text.

s$ = Chr$(x)
Change this back to a character representation

returnValue$ = returnValue$ + s$
and add it to the returnValue$

Inc k
Increase the value of k so that we take the next letter of the key$

Next i   
And the next letter on the text

EndPsub returnValue$

Return the value back to the main routine

After you run this routine on a text you have an encrypted, not readable string

The next stage is to make this readable in a way that we can save this into a file or present on screen

The idea is very simple. You take a the ASCII value of a character and calculate the hexadecimal value for it. But by taking the "real" hexadecimal value you make it easier to break. So what I am doing is to represent my own set of letter, you can take your own set, even for each program different ones, but make sure you are doing it correct in both routines!!

Psub ToHex( c )
   whole = c / 16
   rest  = c - (whole * 16)

Here is where the calculation finds place. We need to calculate the two values of the character, a hexadecimal value consist of a two letter representation like E1
By dividing the value by 16 we have the first value, then take the rest and we have the second value.

The rest of the code is self-explainable use two select statements to get the character representation of it.

Psub ToChar(c$)
   s1$ = Mid$(c$, 1, 1)
   s2$ = Mid$(c$, 2, 1)
   returnValue$ = ""
   value = 0
   value1 = 0

The ToChar routine works the other way around. It take 2 characters, the hexadecimal representation and calculate it back to the decimal value and that to a character representation. The code is self-explainable but if you want some more explanation then you can drop me a line.

PlayBASIC Code: [Select]
Psub ToHex(c)
s1$ = ""
s2$ = ""

whole = c / 16
rest = c - (whole * 16)

Select whole
Case 0
s1$ = "Z"
Case 1
s1$ = "A"
Case 2
s1$ = "Y"
Case 3
s1$ = "B"
Case 4
s1$ = "X"
Case 5
s1$ = "C"
Case 6
s1$ = "W"
Case 7
s1$ = "D"
Case 8
s1$ = "V"
Case 9
s1$ = "E"
Case 10
s1$ = "U"
Case 11
s1$ = "F"
Case 12
s1$ = "T"
Case 13
s1$ = "G"
Case 14
s1$ = "S"
Case 15
s1$ = "H"
EndSelect

Select rest
Case 0
s2$ = "Z"
Case 1
s2$ = "A"
Case 2
s2$ = "Y"
Case 3
s2$ = "B"
Case 4
s2$ = "X"
Case 5
s2$ = "C"
Case 6
s2$ = "W"
Case 7
s2$ = "D"
Case 8
s2$ = "V"
Case 9
s2$ = "E"
Case 10
s2$ = "U"
Case 11
s2$ = "F"
Case 12
s2$ = "T"
Case 13
s2$ = "G"
Case 14
s2$ = "S"
Case 15
s2$ = "H"
EndSelect

returnValue$ = s1$ + s2$
EndPsub returnValue$


Psub ToChar(c$)
s1$ = Mid$(c$, 1, 1)
s2$ = Mid$(c$, 2, 1)
returnValue$ = ""
value = 0
value1 = 0

Select s1$
Case "Z"
value = 0
Case "A"
value = 1 * 16
Case "Y"
value = 2 * 16
Case "B"
value = 3 * 16
Case "X"
value = 4 * 16
Case "C"
value = 5 * 16
Case "W"
value = 6 * 16
Case "D"
value = 7 * 16
Case "V"
value = 8 * 16
Case "E"
value = 9 * 16
Case "U"
value = 10 * 16
Case "F"
value = 11 * 16
Case "T"
value = 12 * 16
Case "G"
value = 13 * 16
Case "S"
value = 14 * 16
Case "H"
value = 15 * 16
EndSelect

Select s2$
Case "Z"
value1 = 0
Case "A"
value1 = 1
Case "Y"
value1 = 2
Case "B"
value1 = 3
Case "X"
value1 = 4
Case "C"
value1 = 5
Case "W"
value1 = 6
Case "D"
value1 = 7
Case "V"
value1 = 8
Case "E"
value1 = 9
Case "U"
value1 = 10
Case "F"
value1 = 11
Case "T"
Login required to view complete source code


Now lets put it all together in two simple routines that does all the work for you

PlayBASIC Code: [Select]
Psub HexIt(MyText$)
MyTextEnc$ = Encrypt(MyText$)
returnValue$ = ""
For t = 1 To Len(MyTextEnc$)
returnValue$ = returnValue$ + ToHex(Asc(Mid$(MyTextEnc$, t, 1)))
Next t
EndPsub returnValue$

Psub StringIt(MyText$)
dsh$ = ""
For t = 1 To Len(MyText$) Step 2
dsh$ = dsh$ + ToChar(Mid$(MyText$, t, 2))
Next t
returnValue$ = Decrypt(dsh$)
EndPsub returnValue$



The Psub HexIt(MyText$) returns an encrypted hexadecimal string en the Psub StringIt(MyText$) returns the decrypted string.

Happy Programming  :D

Theo van Stratum



Related Examples:

    -  Encode File  / Hide File Contents / Xor Encryption
   -   Encrypt Strings / Simple Game Data Protection

  -   PlayBASIC Documentation





Jeku

Cool, thanks!  This will be useful for my new game :)
**
Automaton Games - Home of WordTrix 2.0, WordZap, and GameBasic
Jeku's Music - Easy listening electronic...
**

Adaz

Khm...
Quote from: Jeku on October 12, 2005, 01:44:53 AM
Cool, thanks!  This will be useful for my new game :)
so where is your new game? :-)

Ádáz

Hungary