View Single Post
  #9  
Old 05-28-2013, 11:24 PM
cbk1994 cbk1994 is offline
the fake one
cbk1994's Avatar
Join Date: Mar 2003
Location: San Francisco
Posts: 10,718
cbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond reputecbk1994 has a reputation beyond repute
Send a message via AIM to cbk1994
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) removed

def encrypt(plainkey) {
  
def encrypted ""

  
for (c in plain) {
    
encrypted += (((int) c) + key) + "."
  
}

  return 
encrypted
}

def decrypt(encryptedkey) {
  
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^ro`bdr^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: Uifsf`bsf`op`tqbdft`ifsf"
-1: There_are_no_spaces_here!
0: Sgdqd^`qd^mn^ro`bdr^gdqd
1: Rfcpc]_pc]lm]qn_acq]fcpc
2: Qebob\^ob\kl\pm^`bp\ebob
3: Pdana[]na[jk[ol]_ao[dana
4: Oc`m`Z\m`ZijZnk\^`nZc`m`
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: FZWdWQSdWQ`aQebSUWeQZWdW
14: EYVcVPRcVP_`PdaRTVdPYVcV
15: DXUbUOQbUO^_Oc`QSUcOXUbU
16: CWTaTNPaTN]^Nb_PRTbNWTaT
17: BVS`SMO`SM\]Ma^OQSaMVS`S
18: AUR_RLN_RL[\L`]NPR`LUR_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: <PMZMGIZMGVWG[XIKM[GPMZM
24: ;OLYLFHYLFUVFZWHJLZFOLYL
25: :NKXKEGXKETUEYVGIKYENKXK
26: 9MJWJDFWJDSTDXUFHJXDMJWJ
27: 8LIVICEVICRSCWTEGIWCLIVI
28: 7KHUHBDUHBQRBVSDFHVBKHUH
29: 6JGTGACTGAPQAURCEGUAJGTG
30: 5IFSF@BSF@OP@TQBDFT@IFSF
31: 4HERE?ARE?NO?SPACES?HERE
32: 3GDQD>@QD>MN>RO@BDR>GDQD
33: 2FCPC=?PC=LM=QN?ACQ=FCPC￿
34: 1EBOB<>OB<KL<PM>@BP<EBOB￾
35: 0DANA;=NA;JK;OL=?AO;DANA�
36: /C@M@:<M@:IJ:NK<>@N:C@M@
37: .B?L?9;L?9HI9MJ;=?M9B?L?
38: -A>K>8:K>8GH8LI:<>L8A>K>
39: ,@=J=79J=7FG7KH9;=K7@=J=
40: +?<I<68I<6EF6JG8:<J6?<I<￸
41: *>;H;57H;5DE5IF79;I5>;H;￷
42: )=:G:46G:4CD4HE68:H4=:G:￶
43: (<9F935F93BC3GD579G3<9F9￵
44: ';8E824E82AB2FC468F2;8E8￴
45: &:7D713D71@A1EB357E1:7D7￳
46: %96C602C60?@0DA246D096C6￲
47: $85B5/1B5/>?/C@135C/85B5￱
48: #74A4.0A4.=>.B?024B.74A4￰
49: "63@3-/@3-<=-A>/13A-63@3￯
50: !52?2,.?2,;<,@=.02@,52?2○
51: 41>1+->1+:;+?<-/1?+41>1■
52: 30=0*,=0*9:*>;,.0>*30=0↓
53: 2/</)+</)89)=:+-/=)2/</→
54: 1.;.(*;.(78(<9*,.<(1.;.↑
55: 0-:-'):-'67';8)+-;'0-:-←
56: 9,&(9,&56&:7(*,:&/,9,│
57: .+8+%'8+%45%96')+9%.+8+￧
58: -*7*$&7*$34$85&(*8$-*7*₩
59: ,)6)#%6)#23#74%')7#,)6)¥
60: +(5("$5("12"63$&(6"+(5(¦
61: *'4'!#4'!01!52#%'5!*'4' ̄
62: )&3& "3& /0 41"$&4 )&3&¬
63: (%2%!2%./30!#%3(%2%£
64: '$1$ 1$-.2/ "$2'$1$¢
65: �#0#,-1.!#1�#￟
66: %"/"/"+,0- "0%"/"￞
67: $!.!!/!.!￝
68: # - - )*.+ .# - ᅵ
note: some of the last ones removed because they contained non-printing characters and Incapsula wouldn't let me post them
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 View Post
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.
__________________
Reply With Quote