TheSwamp
Code Red => AutoLISP (Vanilla / Visual) => Topic started by: MP on August 22, 2004, 02:04:41 PM
-
I'm trying to see how crack proof an XOR based encryption routine I've written for my own use is, and while I'm not trying to meet government / military specs, I want it as secure as possible whilst maintaining reasonable peformance.
So, given ...
(mapcar
(function (lambda (text) (encode text password)))
'(
"theswamp.org"
"It is the answer."
"Do you know the question?"
)
)
;; returns:
(
"uöðwceèý/|ö}"
"Wh»îh¡òy{·òùùwnå¥"
"Eb¯êûs:oôð{8óüy ärnãüöpf³"
)
;; Passing the encoded text back at the
;; encoder returns the original string:
(mapcar
(function (lambda (text) (encode text password)))
'(
"uöðwceèý/|ö}"
"Wh»îh¡òy{·òùùwnå¥"
"Eb¯êûs:oôð{8óüy ärnãüöpf³"
)
)
;; returns:
(
"theswamp.org"
"It is the answer."
"Do you know the question?"
)
... can you crack the algorithm?
If no one cracks it I'll likely keep the algorithm hush hush but may make a vlx or dll available to those that request it.
If you spend any time trying to crack this please accept my abundant thanks in advance.
If you successfully crack this I'll buy you a case of beer (and head back to the drawing board).
:)
-
did you modify the typical XOR encryption method to make it stronger?
-
did you modify the typical XOR encryption method to make it stronger?
Hmmm ... I don't know what the "typical XOR encryption method " is, but I rolled my own algorithm that at its core, like most encryption methods, involves XOR bit twiddling, thought there's more to it than that -- if there weren't it could have been cracked just like that (snapping fingers thusly).
I did not start with a standard recipe and modify it. I've had this idea for quite awhile and finally gave in and coded it. I coded it in both LISP and VB. To my surprise it seems to perform reasonably well in both.
I'm actually looking forward to see who can break it, finding out how they broke it and what they feel is its inherent weakness(es).
Thanks for the question Ron.
Michael.
-
Oh your a bastard MP; Now im gonna be up all night thinking about this lil gem. I tried my hand at ONE encryption program and i got confusused right away. But ill give this one some thought. (Dont count on me cracking anything, but i would like to see if i can get a few letters back)
*Se7en grumbles away, back to bed.*
-
I see no way of cracking it without knowing the password. I did learn something though, I learned how to write my own encryption program in C++.
-
I see no way of cracking it without knowing the password.
Could ya crack it if you had the password?
I did learn something though, I learned how to write my own encryption program in C++.
Excellent, can't be get faster performance than that unless you're an assembly language masochist (masmchist?).
-
Alot of crackers don't bother with your encryption algorhythem.
Instead, they hex edit the point where your program says "if serial it valid then proceed" to read "if serial isn't valid then proceed".
The best encryption in the world isn't any good if your program it weak into your software.
-
>Could ya crack it if you had the password?
Me! Probably not no. But I'm guessing others might.
-
True, but if you wish to put data into a vault encryption is the answer.
-
What happens when the user looses the password?
Can you recover the data? :)
CAB
-
Like adding a backdoor password?
-
There is no back door password. Lose the password and you'd have to resort to bombastic methods the hackers use, like dictionary, hybrid and brute force attacks to recover the data.
If you use a simple password like just a single characters or a simple word, it could easily be cracked by a dictionary or hybrid crack. On the other hand if you used a crack stifling password that's long and has a mix of alpha-numerics and punctuation you might be beyond the ability of a brute force attack simply because of the time required to crack the password.
Dictionary attack
A simple dictionary attack is by far the fastest way to break into a machine. A dictionary file (a text file full of dictionary words) is loaded into a cracking application, which is run against user accounts located by the application. Because the majority of passwords are often simplistic, running a dictionary attack is often sufficient to to the job.
Hybrid attack
Another well-known form of attack is the hybrid attack. A hybrid attack will add numbers or symbols to the filename to successfully crack a password. Many people change their passwords by simply adding a number to the end of their current password. The pattern usually takes this form: first month password is "cat"; second month password is "cat1"; third month password is "cat2"; and so on.
Brute force attack
A brute force attack is the most comprehensive form of attack, though it may often take a really long time to work depending on the complexity of the password. Some brute force attacks can take a week depending on the complexity of the password.
See link (http://www-106.ibm.com/developerworks/library/s-crack).
-
I think your missing the point; He gavve you the origional and the encrypted version of the strings. I think what wants is a crack at "reverse engineering" (sorta) the methods used.
...Well, at least that is what im plaining on doing. Take the strings compair the ASCII and BINARY and see if i cant see a pattern.
-
I think what wants is a crack at "reverse engineering" (sorta) the methods used.
Yep, that's what I was thinking, but if someone wants to try and crack the password they can try that too. Either will do, insomuch as you succeed at either I'll make good on the case of wobbly pops.
-
Just a quick look see.
In ACSIIi here are the values and differences.
;Original
034 117 246 240 119 099 101 232 253 047 124 246 125 034 034 087 104 187 238 104 161 242 121 123 183 242 249 249 119 110 229 165 034 034 069 098 175 234 251 115 058 111 244 240 123 056 243 252 121 032 228 114 110 227 252 246 112 102 179 034
;Encrypted
034 116 104 101 115 119 097 109 112 046 111 114 103 034 034 073 116 032 105 115 032 116 104 101 032 097 110 115 119 101 114 046 034 034 068 111 032 121 111 117 032 107 110 111 119 032 116 104 101 032 113 117 101 115 116 105 111 110 063 034
;Difference
0 -1 -142 -139 -4 20 -4 -123 -141 -1 -13 -132 -22 0 0 -14 12 -155 -133 11 -129 -126 -17 -22 -151 -145 -139 -134 0 -9 -115 -119 0 0 -1 13 -143 -113 -140 2 -26 -4 -134 -129 -4 -24 -127 -148 -20 0 -115 3 -9 -112 -136 -141 -1 8 -116 0
Now it's like one the SAT test questions. What is the corelation.
All extracted in plain Autolisp. -David
-
Thank you David.
In the interests of making it a little clearer, I separated the instances (remember there were three strings way back folks) and removed the quotes at either end of the strings from the analysis:
;; Original
117 246 240 119 099 101 232 253 047 124 246 125
087 104 187 238 104 161 242 121 123 183 242 249 249 119 110 229 165
069 098 175 234 251 115 058 111 244 240 123 056 243 252 121 032 228 114 110 227 252 246 112 102 179
;; Encrypted
116 104 101 115 119 097 109 112 046 111 114 103
073 116 032 105 115 032 116 104 101 032 097 110 115 119 101 114 046
068 111 032 121 111 117 032 107 110 111 119 032 116 104 101 032 113 117 101 115 116 105 111 110 063
;; Difference
-1 -142 -139 -4 20 -4 -123 -141 -1 -13 -132 -22
-14 12 -155 -133 11 -129 -126 -17 -22 -151 -145 -139 -134 0 -9 -115 -119
-1 13 -143 -113 -140 2 -26 -4 -134 -129 -4 -24 -127 -148 -20 0 -115 3 -9 -112 -136 -141 -1 8 -116
And another way to look at it ...
;; String1. Original, Encrypted, Difference
117 246 240 119 099 101 232 253 047 124 246 125
116 104 101 115 119 097 109 112 046 111 114 103
-1 -142 -139 -4 20 -4 -123 -141 -1 -13 -132 -22
;; String2. Original, Encrypted, Difference
087 104 187 238 104 161 242 121 123 183 242 249 249 119 110 229 165
073 116 032 105 115 032 116 104 101 032 097 110 115 119 101 114 046
-14 12 -155 -133 11 -129 -126 -17 -22 -151 -145 -139 -134 0 -9 -115 -119
;; String3. Original, Encrypted, Difference
069 098 175 234 251 115 058 111 244 240 123 056 243 252 121 032 228 114 110 227 252 246 112 102 179
068 111 032 121 111 117 032 107 110 111 119 032 116 104 101 032 113 117 101 115 116 105 111 110 063
-1 13 -143 -113 -140 2 -26 -4 -134 -129 -4 -24 -127 -148 -20 0 -115 3 -9 -112 -136 -141 -1 8 -116
Good luck folks.
-
huh?! thats interisting!? Your obviusly altering either the binary or the ASCII number with a formula a sweet formula.... another neat point is that i dont see that you had a problem where i did in mine. (Over shooting the "bonds" of ACSII code) ...Damn you sir!
OBTW, i think you have your orders screwed up MP.
;; String3. Original, Encrypted, Difference
069 098 175 234 251 115 058 111 244 240 123 056 243 252 121 032 228 114 110 227 252 246 112 102 179 ;; Garbage char's
068 111 032 121 111 117 032 107 110 111 119 032 116 104 101 032 113 117 101 115 116 105 111 110 063 ;; <-- "D" "o" "<space>" ...
*edit* I should prolly mention that i didnt verify my last statement, i just looked at the code and translated the numbers and letters i knew off the top of my head. so take what i said with a grain of salt.
-
OBTW, i think you have your orders screwed up MP.
I may -- I had quickly edited what David posted; apologies to you, David and everyone if I FUBARed it in the process.
Here is new data to play with / analyze:
(progn
(defun xor (a b) (boole 6 a b))
(defun fmt (x / s)
(strcat (if (minusp x) "-" " ")
(substr (setq s (strcat "00" (itoa (abs x))))
(- (strlen s) 2)
)
)
)
(foreach text
'(
"theswamp.org"
"Rocks!"
"Oh yeah!"
)
(print text)
(print (setq giberish (encode text password)))
(print (mapcar 'fmt (setq codes1 (vl-string->list text))))
(print (mapcar 'fmt (setq codes2 (vl-string->list giberish))))
(print (mapcar 'fmt (mapcar '- codes2 codes1)))
(print (mapcar 'fmt (mapcar 'xor codes2 codes1)))
(princ "\n")
)
(princ)
)
"theswamp.org"
"uöðwceèý/|ö}"
( 116 104 101 115 119 097 109 112 046 111 114 103) ;; original
( 117 246 240 119 099 101 232 253 047 124 246 125) ;; encoded
( 001 142 139 004 -020 004 123 141 001 013 132 022) ;; difference
( 001 158 149 004 020 004 133 141 001 019 132 026) ;; xor'd
"Rocks!"
"Eõõya¸"
( 082 111 099 107 115 033) ;; original
( 069 245 245 121 097 184) ;; encoded
(-013 134 146 014 -018 151) ;; difference
( 023 154 150 018 018 153) ;; xor'd
"Oh yeah!"
"_o,tâsã¥"
( 079 104 032 121 101 097 104 033) ;; original
( 095 111 044 116 226 115 227 165) ;; encoded
( 016 007 012 -005 125 018 123 132) ;; difference
( 016 007 012 013 135 018 139 132) ;; xor'd
(Used same password as last time).
Have fun! :D
-
Just a guess on the structure:
The password generates a key value based on it's ascii value total
"Hello": 72 + 101 + 108 + 108 + 111 = 500
Based on the 1st letter being a plus 1 value, the formula probably starts something like
key = 500
oc 'Original character
ec 'Encrypted character
(setq ec (+ (asciii oc) (fix (some_function key))))
and them some way to force that value to between 32 & 255 that can be reversed.
(if (> decrypt_oc 255)
(- or rem or something
-David
Michael, it looks like the font used in the code section for the forum is not a true monspaced font. Maybe it is just me....
-
Well i started to think that he just fliped a bit in the origional ascii value, but then i got an "idea" from David's post where he used the password to generate a mathmatical key of somesort. I think i see what hes doing now.
Here are these values binary:
( 079 104 032 121 101 097 104 033) ;; original
( 095 111 044 116 226 115 227 165) ;; encoded
79 01001111
95 01011111
32 00100000
44 00101100
121 01111001
116 01110100
101 01100101
226 11100010
97 01100001
115 01110011
104 01101000
227 11100011
33 00100001
165 10100101
Here is the password in binary:
"Hello": 72 + 101 + 108 + 108 + 111
72 01001000
101 01100101
108 01101100
111 01101111
Now this wont work but it will help you visualise what im trying to say. Hes taking a letter of the password and applying a logical OR to a letter of the string. As it finsihes it moves the the next char in each. Once the password is used up, it itterates thru again.
...?!?!?!
-
Thats the standard way to do a XOR encryption.
He said he added something new to change it so it isn't so easy to decrypt.
-
Hey guys -- great participation. :)
David get's some points here:
The password generates a key value ...
Let's call this a hash value.
... based on it's ascii value total ...
and then promptly loses points.
Hes taking a letter of the password and applying a logical OR to a letter of the string.
Nope.
As it finsihes it moves the the next char in each. Once the password is used up, it itterates thru again.
Nope.
He said he added something new to change it so it isn't so easy to decrypt.
Yep, that was in my design guidelines. Later on I will post some of them.
Thanks guys! :)
-
>> ... based on it's ascii value total ... <<
or some such formula.
A hash value can usually be duplicated using different passwords. I would think that lots of combinations of letters and numbers can produce the same results given a simple equation. The more complex the equation, the more secure the password.
But all in all it produces a number. -David
-
The more complex the equation, the more secure the password. But all in all it produces a number.
No refuting that.
-
this is an interesting prospect....where the following will be required to be done... not impossible but not the easiest task in the world either....
determine password hash
determine algorithm
Based on the given data there would have to be lots of testing and retesting before a viable solution would be found.
If however, there were more encrypted data strings to review it would make the task a bit simpler, at least I think it would.
-
If however, there were more encrypted data strings to review it would make the task a bit simpler, at least I think it would.
As you wish buttercup ...
(defun test_strings ( list_of_strings / xor fmt prt str2 lst1 lst2 )
;; note, for this exercise PWD is
;; a global defined outside this
;; program [lest I give all the
;; secrets away prematurely].
(defun xor (a b) (boole 6 a b))
(defun fmt (x / s)
(strcat (if (minusp x) "-" " ")
(substr (setq s (strcat "00" (itoa (abs x))))
(- (strlen s) 2)
)
)
)
(defun prt ( lst )
(princ (mapcar 'fmt lst))
(princ "\n")
)
(foreach str1 list_of_strings
(print str1)
(print (setq str2 (encode str1 PWD)))
(princ "\n")
(prt (setq lst1 (vl-string->list str1)))
(prt (setq lst2 (vl-string->list str2)))
(prt (mapcar '- lst2 lst1))
(prt (mapcar 'xor lst2 lst1))
(princ "\n")
)
(princ)
)
(test_strings
'(
"a"
"ab"
"abc"
"abcd"
"abcde"
)
)
"a"
"x"
( 097) ;; original
( 120) ;; encoded
( 023) ;; difference
( 025) ;; xor'd
"ab"
"gà"
( 097 098) ;; original
( 103 224) ;; encoded
( 006 126) ;; difference
( 006 130) ;; xor'd
"abc"
"sêå"
( 097 098 099) ;; original
( 115 234 229) ;; encoded
( 018 136 130) ;; difference
( 018 136 134) ;; xor'd
"abcd"
"ambò"
( 097 098 099 100) ;; original
( 097 109 098 242) ;; encoded
( 000 011 -001 142) ;; difference
( 000 015 001 150) ;; xor'd
"abcde"
"jöxàs"
( 097 098 099 100 101) ;; original
( 106 246 120 224 115) ;; encoded
( 009 148 021 124 014) ;; difference
( 011 148 027 132 022) ;; xor'd
I chose these strings because the output is VERY revealing, and indeed reveals one of my key design requirements if you can see it.
:)
-
.....WHAT?! *How you do that?!*
the letter "A" isnt the same encoded in your tests! Oh, Your killing me!
-
Excellent observation Se7en, that was one of my design requirements (makes it more difficult to crack the algorithm).
Notice anything in the following (subtle but important)?
(foreach x
'(
"I chose these strings because the output is VERY revealing, "
"and indeed reveals key design requirements if you can see it."
)
(print (encode x password))
(princ)
)
"F!pççkù;þèqóå´jêpqøûùµ|laà|n÷7mÿp:xêðåáq)ts?[HÏV(ôvorysæîô¶¨"
"zèj¼mkçsoå6ÿ}øræî÷¼xàý'áçiõ|è5|~tûøà|älûñ|¸jñ¯jpô¦møp³zbö âw¤"
-
the only thing i notice right away is the capital letters; They seem to be retained in the excrypted version. (I dont know it its important or not, but ill have to look this over to see if i see anything else.)
-
Well done Se7en, though not entirely correct.
(foreach x
'( "I Chose These Strings Because The Output Is Very Revealing, "
"And Indeed Reveals Key Design Requirements If You Can See It."
)
(print (encode x password))
(princ)
)
"F!Pççkù;Þèqóå´JêpqøûùµBlaà|n÷7Mÿp:Xêðåáq)Ts?[hïv(Ôvorysæîô¶¨"
"Zèj¼Mkçsoå6ß}øræî÷¼Xàý'Áçiõ|è5R~tûøà|älûñ|¸Jñ¯Jpô¦Møp³Zbö Âw¤"
;; Putting them back to back with the original strings --
"I Chose These Strings Because The Output Is Very Revealing, "
"F!Pççkù;Þèqóå´JêpqøûùµBlaà|n÷7Mÿp:Xêðåáq)Ts?[hïv(Ôvorysæîô¶¨"
"And Indeed Reveals Key Design Requirements If You Can See It."
"Zèj¼Mkçsoå6ß}øræî÷¼Xàý'Áçiõ|è5R~tûøà|älûñ|¸Jñ¯Jpô¦Møp³Zbö Âw¤"
David's correct, the code font does not appear to be a non proprtional one, though I'm doing nothing other than using the code tags. Hmmm.
-
Well, I fail to see the relevant data here, except that there are no characters with a value < 32 .... which leaves the algorithm either:
A) testing for values less than 32 and applying a minimum offset
or
B) using only the character offsets 32 and above for computational requirements
either way I am stumped for the moment
-
... there are no characters with a value < 32 ...
That part of your statement is true and was a design requirement. :)
-
Man, im beat! I dont think i can feel my toes anymore from thinking so hard!
-
I got some free time here at work friday so i assembled a little helper to help me look at the binary of the chararters MP is excrypting.
Here are two strings "converted to binary". Can anyone see a pattern? I'm stumped!
"theswamp.org"
((0 1 1 1 0 1 0 0) (0 1 1 0 1 0 0 0) (0 1 1 0 0 1 0 1) (0 1 1 1 0 0 1 1) (0 1 1 1 0 1 1 1) (0 1 1 0 0 0 0 1) (0 1 1 0 1 1 0 1) (0 1 1 1 0 0 0 0) (0 0 1 0 1 1 1 0) (0 1 1 0 1 1 1 1) (0 1 1 1 0 0 1 0) (0 1 1 0 0 1 1 1))
"uöðwceèý/|ö}"
((0 1 1 1 0 1 0 1) (1 1 1 1 0 1 1 0) (1 1 1 1 0 0 0 0) (0 1 1 1 0 1 1 1) (0 1 1 0 0 0 1 1) (0 1 1 0 0 1 0 1) (1 1 1 0 1 0 0 0) (1 1 1 1 1 1 0 1) (0 0 1 0 1 1 1 1) (0 1 1 1 1 1 0 0) (1 1 1 1 0 1 1 0) (0 1 1 1 1 1 0 1))