source: trunk/CrypPlugins/KeySearcher/KeySearcher.cs @ 733

Last change on this file since 733 was 733, checked in by kopal, 12 years ago
  • KeySearcher now can brute force SDES
  • added KeySearcher Sample with SDES
File size: 13.7 KB
Line 
1using System;
2using System.Linq;
3using System.Text;
4using Cryptool.PluginBase.Analysis;
5using Cryptool.PluginBase;
6using System.Windows.Controls;
7using System.ComponentModel;
8using Cryptool.PluginBase.Control;
9using System.Collections;
10using System.Collections.Generic;
11
12namespace KeySearcher
13{
14    public class KeyPattern
15    {
16        private class Wildcard
17        {
18            private char[] values = new char[256];
19            private int length;
20            private int counter;           
21
22            public Wildcard(string valuePattern)
23            {               
24                counter = 0;
25                length = 0;
26                int i = 1;
27                while (valuePattern[i] != ']')
28                {
29                    if (valuePattern[i + 1] == '-')
30                    {
31                        for (char c = valuePattern[i]; c <= valuePattern[i + 2]; c++)
32                            values[length++] = c;
33                        i += 2;
34                    }
35                    else
36                        values[length++] = valuePattern[i];
37                    i++;
38                }
39            }
40
41            public char getChar()
42            {               
43                return (char)values[counter];
44            }
45
46            public bool succ()
47            {
48                counter++;
49                if (counter >= length)
50                {
51                    counter = 0;
52                    return true;
53                }
54                return false;
55            }
56
57            public int Size()
58            {
59                return length;
60            }
61
62        }
63
64        private string pattern;
65        private string key;       
66        private ArrayList wildcardList;
67
68        public KeyPattern(string pattern)
69        {
70            this.pattern = pattern;
71        }
72
73        public string giveWildcardKey()
74        {
75            string res = "";
76            int i = 0;
77            while (i < pattern.Length)
78            {
79                if (pattern[i] != '[')
80                    res += pattern[i];
81                else
82                {
83                    res += '*';
84                    while (pattern[i] != ']')
85                        i++;
86                }
87                i++;
88            }
89            return res;
90        }
91
92        public bool testKey(string key)
93        {
94            int kcount = 0;
95            int pcount = 0;
96            while (kcount < key.Length && pcount < pattern.Length)
97            {
98                if (pattern[pcount] != '[')
99                {
100                    if (key[kcount] != '*' && pattern[pcount] != key[kcount])
101                        return false;
102                    kcount++;
103                    pcount++;
104                }
105                else
106                {
107                    bool contains = false;
108                    pcount++;
109                    while (pattern[pcount] != ']')
110                    {
111                        if (key[kcount] != '*')
112                        {
113                            if (pattern[pcount + 1] == '-')
114                            {
115                                if (key[kcount] >= pattern[pcount] && key[kcount] <= pattern[pcount + 2])
116                                    contains = true;
117                                pcount += 2;
118                            }
119                            else
120                                if (pattern[pcount] == key[kcount])
121                                    contains = true;
122                        }
123                        pcount++;
124                    }
125                    if (!contains && !(key[kcount] == '*'))
126                        return false;
127                    kcount++;
128                    pcount++;
129                }               
130            }
131            if (pcount != pattern.Length || kcount != key.Length)
132                return false;
133            return true;
134        }
135
136        public int initKeyIteration(string key)
137        {
138            int counter = 0;
139            this.key = key;
140            int pcount = 0;
141            wildcardList = new ArrayList();
142            for (int i = 0; i < key.Length; i++)
143            {
144                if (key[i] == '*')
145                {
146                    Wildcard wc = new Wildcard(pattern.Substring(pcount, pattern.IndexOf(']', pcount) + 1 - pcount));
147                    wildcardList.Add(wc);
148                    counter += wc.Size();
149                }
150
151                if (pattern[pcount] == '[')
152                    while (pattern[pcount] != ']')
153                        pcount++;
154                pcount++;
155            }
156            return counter;
157        }
158
159        public bool nextKey()
160        {
161            int wildcardCount = wildcardList.Count-1;
162            bool overflow = ((Wildcard)wildcardList[wildcardCount]).succ();
163            wildcardCount--;
164            while (overflow && (wildcardCount >= 0))
165                overflow = ((Wildcard)wildcardList[wildcardCount--]).succ();
166            return !overflow;
167        }
168
169        public string getKey()
170        {
171            string res = "";
172            int wildcardCount = 0;
173            for (int i = 0; i < key.Length; i++)
174            {
175                if (key[i] != '*')
176                    res += key[i];
177                else
178                {
179                    Wildcard wc = (Wildcard)wildcardList[wildcardCount++];
180                    res += wc.getChar();
181                }
182            }
183            return res;
184        }
185    }
186   
187    [Author("Thomas Schmid", "thomas.schmid@cryptool.org", "Uni Siegen", "http://www.uni-siegen.de")]
188    //[Author("Sven Rech", "rech@cryptool.org", "Uni Duisburg-Essen", "http://www.uni-due.de")]
189    [PluginInfo(true, "KeySearcher", "Bruteforces a decryption algorithm.", null, "KeySearcher/Images/icon.png")]
190    public class KeySearcher : IAnalysisMisc
191    {
192        private KeyPattern pattern = null;
193        public KeyPattern Pattern
194        {
195            get
196            {
197                return pattern;
198            }
199            set
200            {
201                pattern = value;
202                if ((settings.Key == null) ||((settings.Key != null) && !pattern.testKey(settings.Key)))
203                    settings.Key = pattern.giveWildcardKey();
204            }
205        }
206
207        private bool stop;
208
209        #region IPlugin Members
210
211        public event StatusChangedEventHandler OnPluginStatusChanged;
212
213        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
214
215        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
216
217        private KeySearcherSettings settings;       
218
219        public KeySearcher()
220        {
221            settings = new KeySearcherSettings(this);
222        }
223
224        public ISettings Settings
225        {
226            get { return settings; }
227        }
228
229        public UserControl Presentation
230        {
231            get { return null; }
232        }
233
234        public UserControl QuickWatchPresentation
235        {
236            get { return null; }
237        }
238
239        public void PreExecution()
240        {
241        }
242
243        public void Execute()
244        {
245        }
246
247        public void process(IControlEncryption sender)
248        {
249            int counter = 0;
250            if (sender != null && costMaster != null)
251            {
252                int maxInList = 10;
253                LinkedList<ValueKey> costList = new LinkedList<ValueKey>();
254                ValueKey valueKey = new ValueKey();               
255                if (this.costMaster.getRelationOperator() == RelationOperator.LessThen)
256                    valueKey.value = double.MaxValue;
257                else
258                    valueKey.value = double.MinValue;
259                valueKey.key = "dummykey";
260                LinkedListNode<ValueKey> node = costList.AddFirst(valueKey);
261                for (int i = 1; i < maxInList; i++)
262                {
263                    node = costList.AddAfter(node, valueKey);
264                }
265
266                stop = false;
267                if (!Pattern.testKey(settings.Key))
268                {
269                    GuiLogMessage("Wrong key pattern!", NotificationLevel.Error);
270                    return;
271                }
272                int size = Pattern.initKeyIteration(settings.Key);
273                int blocksize = CostMaster.getBlocksize();
274                string key;
275                do
276                {
277                    key = Pattern.getKey();                   
278                    byte[] decryption = sender.Decrypt(ControlMaster.getKeyFromString(key), blocksize);
279
280                    valueKey = new ValueKey();
281                    valueKey.value = CostMaster.calculateCost(decryption);
282                    valueKey.key = key;
283
284                    GuiLogMessage("Tried key " + valueKey.key + " = " + valueKey.value, NotificationLevel.Debug);
285
286                    if (this.costMaster.getRelationOperator() == RelationOperator.LargerThen)
287                    {
288
289                       node = costList.First;
290
291                        while (node != null)
292                        {
293
294                            if (valueKey.value > node.Value.value)
295                            {
296                                costList.AddBefore(node, valueKey);
297                                break;
298                            }
299                            node = node.Next;
300                        }
301                    }
302                    else
303                    {
304                        node = costList.First;
305
306                        while (node != null)
307                        {
308
309                            if (valueKey.value < node.Value.value)
310                            {
311                                costList.AddBefore(node, valueKey);
312                                break;
313                            }
314                            node = node.Next;
315                        }
316                    }
317                    if (costList.Count > maxInList)
318                    {
319                        costList.RemoveLast();
320                    }
321
322                    counter++;
323                    ProgressChanged(counter, size);
324                } while (Pattern.nextKey() && !stop);
325
326                GuiLogMessage("Calculated value/key - list:", NotificationLevel.Info);
327                LinkedListNode<ValueKey> n = costList.First;
328                while (n != null)
329                {
330                    GuiLogMessage(n.Value.value + " = " + n.Value.key, NotificationLevel.Info);
331                    n = n.Next;
332                }
333
334            }//end if
335        }
336
337        public void PostExecution()
338        {
339        }
340
341        public void Pause()
342        {
343        }
344
345        public void Stop()
346        {
347            stop = true;
348        }
349
350        public void Initialize()
351        {
352        }
353
354        public void Dispose()
355        {
356        }
357
358        #endregion
359
360        #region INotifyPropertyChanged Members
361
362        public event PropertyChangedEventHandler PropertyChanged;
363
364        public void OnPropertyChanged(string name)
365        {
366            if (PropertyChanged != null)
367            {
368                PropertyChanged(this, new PropertyChangedEventArgs(name));
369            }
370        }
371
372        #endregion
373
374        private void keyPatternChanged()
375        {
376            Pattern = new KeyPattern(controlMaster.getKeyPattern());
377        }
378
379        private void onStatusChanged(IControl sender, bool readyForExecution)
380        {
381            if (readyForExecution)
382            {
383                this.process((IControlEncryption)sender);
384            }
385        }
386
387        #region IControlEncryption Members
388
389        private IControlEncryption controlMaster;
390        [PropertyInfo(Direction.ControlMaster, "Control Master", "Used for bruteforcing", "", DisplayLevel.Beginner)]
391        public IControlEncryption ControlMaster
392        {
393            get { return controlMaster; }
394            set
395            {
396                if (controlMaster != null)
397                {
398                    controlMaster.keyPatternChanged -= keyPatternChanged;
399                    controlMaster.OnStatusChanged -= onStatusChanged;
400                }
401                if (value != null)
402                {
403                    Pattern = new KeyPattern(value.getKeyPattern());
404                    value.keyPatternChanged += keyPatternChanged;
405                    value.OnStatusChanged += onStatusChanged;
406                    controlMaster = value;
407                    OnPropertyChanged("ControlMaster");
408                   
409                }
410                else
411                    controlMaster = null;
412            }
413        }
414
415        #endregion
416
417        #region IControlCost Members
418
419        private IControlCost costMaster;
420        [PropertyInfo(Direction.ControlMaster, "Cost Master", "Used for cost calculation", "", DisplayLevel.Beginner)]
421        public IControlCost CostMaster
422        {
423            get { return costMaster; }
424            set
425            {
426                costMaster = value;
427            }
428        }
429
430        #endregion
431
432        public void GuiLogMessage(string message, NotificationLevel loglevel)
433        {
434            if (OnGuiLogNotificationOccured != null)
435                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, loglevel));
436        }
437
438        public void ProgressChanged(double value, double max)
439        {
440            if (OnPluginProgressChanged != null)
441            {
442                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
443            }
444        }
445
446        private struct ValueKey
447        {
448            public double value;
449            public String key;
450        };
451    }
452}
Note: See TracBrowser for help on using the repository browser.