Graal Forums An encrypt/decrypt function
 FAQ Members List Calendar Search Today's Posts Mark Forums Read

#1
05-27-2013, 08:42 AM
 Gunderak Coder Join Date: Jun 2011 Location: Australia Posts: 795
An encrypt/decrypt function

 Hi, haven't been active on the forums in a while but I was looking for some feedback, the last time I attempted a cipher, it didn't use a key and was pretty basic. Here is my latest attempt, what do you guys/gals think? Uses: To encrypt sensitive player attributes. To encrypt any string on the server really. Pros: Makes strings semi-secure. Cons: Makes strings long. PHP Code:  /*  The logic of this encryption is basically  Get a key/salt and get a numerical value  from the string, so to get that we convert it  to numbers by getting each ascii value of  each character, this gives us an integer  that we can use as a salt.    Once we have out key, we then get each character  of the string to encrypt, get the ascii of it  which returns an integer, plus that with the salt  and add it to an array sort of thing with a seperator  chacarter.    We also base64 it both ways to make it look more neat.*///Seperator character.const sep = ".";function Encrypt(string, key){  temp.key = RealKey(key);  temp.str;  for(temp.i = 0; i < string.length(); i ++){    temp.letter = string.substring(i, +1);    temp.letter = getascii(temp.letter);    temp.str = temp.str@temp.letter+key@sep;  }  return base64encode(temp.str);}function Decrypt(string, key){  temp.string = base64decode(string);  temp.key = RealKey(key);  temp.str;  temp.tok = string.tokenize(sep);  for(temp.i = 0; i < tok.size(); i ++){    temp.letter = tok[i];    temp.letter = char(temp.letter-key);    temp.str = temp.str@letter;  }  return temp.str;}function RealKey(key){  temp.char;  for(temp.i = 0; i < key.length(); i ++){    temp.letter = key.substring(i, +1);    temp.code = getascii(temp.letter);    temp.char += temp.code;  }  return int(temp.char/2);}  
 __________________ Gund for president. Remote PM {P*}x (Graal813044) from eraiphone -> Stefan: I hav 1 qustion *Gunderak: he hav 1 *Gunderak: qustion

Last edited by Gunderak; 05-27-2013 at 09:28 AM..
#2
05-27-2013, 03:48 PM
 Emera Delterian Hybrid Join Date: Mar 2011 Location: Newcastle Upon-Tyne Posts: 1,704
 Cool, but why are you pre-defining variables?
#3
05-27-2013, 06:14 PM
 cbk1994 the fake one Join Date: Mar 2003 Location: San Francisco Posts: 10,718
 This provides almost no security at all. It's just a caesar cipher, and can be easily broken by either frequency analysis or analysis based on a chosen plaintext. Your use of the term "salt" is incorrect. A salt is used to help protect against rainbow table attacks and sometimes against brute-force attacks for a hash function. Yours is not a hash function. I also can't imagine what applications this could possibly have for Graal.
 __________________
#4
05-27-2013, 10:00 PM
 Loriel Somewhat rusty Join Date: Mar 2001 Posts: 5,059
#5
05-27-2013, 10:51 PM
 Fulg0reSama Extrinsical Anomaly Join Date: Sep 2009 Location: Ohio Posts: 3,049
Quote:
pfff' that's what I got skype 'fo.
 __________________ Careful, thoughts and opinions here scare people.
#6
05-28-2013, 06:24 AM
 Gunderak Coder Join Date: Jun 2011 Location: Australia Posts: 795
Quote:
 Originally Posted by cbk1994 This provides almost no security at all. It's just a caesar cipher, and can be easily broken by either frequency analysis or analysis based on a chosen plaintext. Your use of the term "salt" is incorrect. A salt is used to help protect against rainbow table attacks and sometimes against brute-force attacks for a hash function. Yours is not a hash function. I also can't imagine what applications this could possibly have for Graal.
Dreams and spirits, ded.
Also since you're saying it has almost no security, if I encrypt a string for you, would you be happy to try and decrypt it?
 __________________ Gund for president. Remote PM {P*}x (Graal813044) from eraiphone -> Stefan: I hav 1 qustion *Gunderak: he hav 1 *Gunderak: qustion
#7
05-28-2013, 12:09 PM
 Chompy \(_o)/ Join Date: Sep 2006 Location: Norway Posts: 2,815
Encrypt functions are always fun to make! Remember making one myself some time ago: http://forums.graalonline.com/forums...ad.php?t=79594 (attachment in that post: http://forums.graalonline.com/forums...6&d=1209707502)

Quote:
 Originally Posted by Gunderak ... if I encrypt a string for you, would you be happy to try and decrypt it?
But yeah, I would like to try and reverse engineer it if you don't mind. Will come back with a solution. The most secure part of this script is how you store the key externally and cut of the decimal in the getRealKey() function of yours btw.
 __________________
#8
05-28-2013, 05:42 PM
 Hezzy002 Registered User Join Date: Jul 2011 Posts: 247
Quote:
 Originally Posted by Gunderak Dreams and spirits, ded. Also since you're saying it has almost no security, if I encrypt a string for you, would you be happy to try and decrypt it?
Please do, unless you have a one-time-pad, meaning you have a key the same size as the string you're encrypting, this type of encryption is extremely easy to break. It's basically a crappy version of a XOR cipher. It can be broken with simple frequency analysis and key shifting.

However, if it is a one-time-pad, then this type of encryption is impossible to break without brute forcing. With that being said, one-time-pad's are really bad for networking and it generally means that a new key has to be transmitted over the wire, which can be intercepted anyway.
#9
05-28-2013, 11:24 PM
 cbk1994 the fake one Join Date: Mar 2003 Location: San Francisco Posts: 10,718
You don't seem to believe me when I say this provides almost no security, so let's go through it.

For this example, I've rewritten your code into Groovy since I don't have access to a server to test on at the moment:

PHP Code:
 // Gunderak's encrypt function with some of the irrelevant stuff (e.g. base64, // string keys) removeddef encrypt(plain, key) {  def encrypted = ""  for (c in plain) {    encrypted += (((int) c) + key) + "."  }  return encrypted}def decrypt(encrypted, key) {  def decrypted = ""   for (n in encrypted.split("\\.")) {    decrypted += (char) (n.toInteger() - key)  }  return decrypted}  
I've encrypted some text using a key. You don't know the text or the key. Here's what the output looks like:

Quote:
 14423208.14423228.14423229.14423239.14423156.14423 229.14423239.14423156.14423221.14423156.14423240.1 4423225.14423239.14423240.14423170.
Let's go about trying to figure out what it is by making some reasonable assumptions. We can guess it's probably not binary data, which means the characters, in order to be ASCII and English, are going to be between about 32 to 126.

Let's shift the values so that the lowest one is 32, since that's typically the character with the lowest value we'll see. The smallest value is 14423156, so we'll subtract 14423124 (which is 14423156 - 32) from each of the numbers to get this:

Quote:
 84.104.105.115.32.105.115.32.97.32.116.101.115.116 .46.
Now let's just replace each one of those numbers with the character it represents (look at an ASCII table, or just decrypt with a key equal to zero using your function):

Quote:
 > println decrypt("84.104.105.115.32.105.115.32.97.32.116.10 1.115.116.46.", 0) "This is a test."
And we've solved it! There's the plaintext, and the key is 14423124 (the number we subtracted). You could have done every one of the steps above with no prior knowledge of the key or plaintext.

The only reason we were able to figure out the key in one step is because the plaintext I used happened to have a space, which is the lowest-value ASCII character we're likely to run in to.

What if I was looking at a string with no space? Here's another example:

Quote:
 5245707.5245727.5245724.5245737.5245724.5245718.52 45720.5245737.5245724.5245718.5245733.5245734.5245 718.5245738.5245735.5245720.5245722.5245724.524573 8.5245718.5245727.5245724.5245737.5245724.5245656.
There are no spaces in the plaintext, but we don't know that yet, so let's do the exact same thing as above, and subtract 5245624 (5245656 - 32) so that the smallest character above will be 32. We then get:

Quote:
 83.103.100.113.100.94.96.113.100.94.109.110.94.114 .111.96.98.100.114.94.103.100.113.100.32.
Replacing these with their character equivalents yields:

Quote:
 Sgdqd^qd^mn^robdr^gdqd
That doesn't look right, which means that the key probably wasn't 5245624 (it also means that there are no spaces in the plaintext, or that there are characters lower than a space in the plaintext).

That doesn't really matter, though, since we can easily brute force it. Let's try decrypting the 83.103.100... from above using every possible key from -32 to 95 (we know it must be in this range if we're dealing with ASCII data).

A quick script will let you try that. Here are the outputs for decrypting with all keys from -32 to 95:

Quote:
 -32: s‡„‘„~€‘„~Ž~’€‚„’~‡„‘„@ -31: r†ƒƒ}ƒ}Œ}‘Žƒ‘}†ƒƒ? -30: q…‚‚|~‚|‹Œ|~€‚|…‚‚> -29: p„Ž{}Ž{Š‹{Œ}{„Ž= -28: oƒ€€z|€z‰ŠzŽ‹|~€Žzƒ€€< -27: n‚Œy{Œyˆ‰yŠ{}y‚Œ; -26: m~‹~xz‹~x‡ˆxŒ‰z|~Œx~‹~: -25: l€}Š}wyŠ}w†‡w‹ˆy{}‹w€}Š}9 -24: k|‰|vx‰|v…†vŠ‡xz|Šv|‰|8 -23: j~{ˆ{uwˆ{u„…u‰†wy{‰u~{ˆ{7 -22: i}z‡ztv‡ztƒ„tˆ…vxzˆt}z‡z6 -21: h|y†ysu†ys‚ƒs‡„uwy‡s|y†y5 -20: g{x…xrt…xr‚r†ƒtvx†r{x…x4 -19: fzw„wqs„wq€q…‚suw…qzw„w3 -18: eyvƒvprƒvp€p„rtv„pyvƒv2 -17: dxu‚uoq‚uo~oƒ€qsuƒoxu‚u1 -16: cwttnptn}~n‚prt‚nwtt0 -15: bvs€smo€sm|}m~oqsmvs€s/ -14: aurrlnrl{|l€}npr€lurr. -13: tq~qkm~qkz{k|moqktq~q- -12: _sp}pjl}pjyzj~{lnp~jsp}p, -11: ^ro|oik|oixyi}zkmo}iro|o+ -10: ]qn{nhj{nhwxh|yjln|hqn{n* -9: \pmzmgizmgvwg{xikm{gpmzm) -8: [olylfhylfuvfzwhjlzfolyl( -7: Znkxkegxketueyvgikyenkxk' -6: Ymjwjdfwjdstdxufhjxdmjwj& -5: Xlivicevicrscwtegiwclivi% -4: Wkhuhbduhbqrbvsdfhvbkhuh$-3: Vjgtgactgapqaurceguajgtg# -2: Uifsfbsfoptqbdftifsf" -1: There_are_no_spaces_here! 0: Sgdqd^qd^mn^robdr^gdqd 1: Rfcpc]_pc]lm]qn_acq]fcpc 2: Qebob\^ob\kl\pm^bp\ebob 3: Pdana[]na[jk[ol]_ao[dana 4: OcmZ\mZijZnk\^nZcm 5: Nb_l_Y[l_YhiYmj[]_mYb_l_ : Ma^k^XZk^XghXliZ\^lXa^k^ 7: L]j]WYj]WfgWkhY[]kW]j] 8: K_\i\VXi\VefVjgXZ\jV_\i\ 9: J^[h[UWh[UdeUifWY[iU^[h[ 10: I]ZgZTVgZTcdTheVXZhT]ZgZ 11: H\YfYSUfYSbcSgdUWYgS\YfY 12: G[XeXRTeXRabRfcTVXfR[XeX 13: FZWdWQSdWQaQebSUWeQZWdW 14: EYVcVPRcVP_PdaRTVdPYVcV 15: DXUbUOQbUO^_OcQSUcOXUbU 16: CWTaTNPaTN]^Nb_PRTbNWTaT 17: BVSSMOSM\]Ma^OQSaMVSS 18: AUR_RLN_RL[\L]NPRLUR_R 19: @TQ^QKM^QKZ[K_\MOQ_KTQ^Q 20: ?SP]PJL]PJYZJ^[LNP^JSP]P 21: >RO\OIK\OIXYI]ZKMO]IRO\O 22: =QN[NHJ[NHWXH\YJLN\HQN[N 23: @QD>MN>[email protected]>GDQD 33: 2FCPC=?PC=LM=QN?ACQ=FCPC￿ 34: 1EBOB<>OB@BP@N:[email protected]@￼ 37: .B?L?9;L?9HI9MJ;=?M9B?L?￻ 38: -A>K>8:K>8GH8LI:<>L8A>K>￺ 39: ,@=J=79J=7FG7KH9;[email protected]=J=￹ 40: +?;H;57H;5DE5IF79;I5>;H;￷ 42: )=:G:46G:4CD4HE68:H4=:G:￶ 43: (<9F935F93BC3GD579G3<9F9￵ 44: ';8E824E82AB2FC468F2;8E8￴ 45: &:[email protected]:7D7￳ 46: %[email protected]￲ 47:$85B5/1B5/>?/[email protected]/85B5￱ 48: #74A4.0A4.=>.B?024B.74A4￰ 49: "[email protected]/@3-<=-A>/[email protected]￯ 50: !52?2,.?2,;<,@[email protected],52?2￮ 51: 41>1+->1+:;+?<-/1?+41>1￭ 52: 30=0*,=0*9:*>;,.0>*30=0￬ 53: 2/
Scroll through that list and look for one that looks like English. Here it is:

Quote:
 -1: There_are_no_spaces_here!
I shifted it earlier so that the lowest number was 32 (a space in ASCII); if I'd shifted it instead to 33 (an exclamation point in ASCII), we'd have got it first try like we did before. I'd never know to do that, of course, so simply trying all possible values and looking through the list manually is the easiest way to break it, which is what we did.

Does that make sense? Your algorithm will provide almost no security. Encryption is difficult to get right, which is why you should always look at the established algorithms instead of trying to create your own. Modern algorithms aren't susceptible to the kind of simple attacks we performed above.

Quote:
 Originally Posted by Chompy Encrypt functions are always fun to make! Remember making one myself some time ago: http://forums.graalonline.com/forums...ad.php?t=79594 (attachment in that post: http://forums.graalonline.com/forums...6&d=1209707502)
Yours is a hash function, his is not. Yours isn't encryption.
 __________________
#10
05-29-2013, 12:32 AM
 Hezzy002 Registered User Join Date: Jul 2011 Posts: 247
Quote:
 Originally Posted by cbk1994 words
this is what i said to do except he didn't say the stuff about a one time pad so im a better expert

plus i heard chris vimes is a porker and i have 8% bodyfat and was a state ranked athlete in high school so i'm pretty much better all around
#11
05-29-2013, 05:59 AM
 Gunderak Coder Join Date: Jun 2011 Location: Australia Posts: 795
 Well thanks I guess, I suppose it's not viable to use, but nonetheless it was fun to make I didn't really think of brute force, but I will sure as hell try to make another improved harder to crack version aha.
 __________________ Gund for president. Remote PM {P*}x (Graal813044) from eraiphone -> Stefan: I hav 1 qustion *Gunderak: he hav 1 *Gunderak: qustion

Last edited by Gunderak; 05-29-2013 at 09:37 AM..