On Fri, 06 Sep 2002 12:46:43 EDT, Bryan Ponnwitz <bponnwitat_private> said: > All text is encrypted using the following algorithm: > enc = ((((char + E0) * 2 * E1 + 31 + E2) * E3 + (69 * E4)) * (E5 + E6) + > (E7 * E8)) * 2 * E9 Ouch. This will be quite easy to break, even without the key. Note that you're basically just computing 'char * A + B' where A and B are THE SAME for all characters. So it should be breakable via the same means as 'rot-N' where N is unknown. So you take some 'enc' values X, Y, Z, and solve: char1 * A + B = X char2 * A + B = Y char3 * A + B = Z (starting to see a pattern? ;) (char2-char1) * A = (Y-X) (char3-char1) * A = (Z-X) (char3-char2) * A = (Z-Y) So let's try this: for i = 1 to 256 do try = (Y-X) / i; /* brute-force all possible 'A' */ for j = 1 to 256 do if (j * try) == (Z-X) then break; /* 'try' is A */ done done A bit of mathematical cleverness will allow an even faster method, but I've left it as an exercise for the reader. Can you do it with *one* loop? ;) Computing B is equally trivial - and then the game is over. The biggest flaw is that every encrypted value is an output of *the same* function with *the same state*. Even adding in some chaining (so the second output byte depended on the first and third bytes of input as well as the second input byte) would make it tougher. So would using a 'mod' function - if you used '(char * A + B) mod N' where N was relatively prime to A and B, it would be a lot tougher, as it would require computing an inverse modulus (although at 10-12 digits it's still possible to brute-force. Now an inverse modulus where A, B, and N were all 100 digits or so - THAT gets interesting. ;) > From Server: EB 03 00 00 3F DE B8 73 16 A1 D5 21 3C E7 > Here's your key. (The last 10 bytes are the key and are randomly > generated numbers between 1 and 254.) As you suddenly turn it from having to do some math to trivial brute force: /* pre-compute the table of all possible 'enc' values for this key */ for i = 1 to 256 do enc[i] = ((((i+ E0)*2*E1 + 31 + E2)*E3 + (69*E4)) * (E5+E6)+(E7*E8))*2*E9; /* now take a table crypt[] with the crypted password characters */ for i = 1 to number_of_enc_values /* try first char, second, etc */ for j = 1 to 256 do /* The value has to be in here someplace */ if enc[j] = crypted[j] { print ascii(j); break; } Given that there exist a *LOT* of libraries that will do all this grunt work for you, you might want to ask yourself why you're designing your own instead of just running your protocol over an SSL connection. If you want to design your own crypto anyhow, I'd suggest you get a copy of Bruce Schneier's "Applied Cryptography" and understand *all* of it before trying to design anything. And assume when creating it that all attackers will have read and understood all of it as well. -- Valdis Kletnieks Computer Systems Senior Engineer Virginia Tech
This archive was generated by hypermail 2b30 : Fri Sep 06 2002 - 16:17:31 PDT