source: trunk/CrypPlugins/DES/DES.cs @ 1157

Last change on this file since 1157 was 1157, checked in by Arno Wacker, 12 years ago

AnotherEditor

  • Yet another Invoke during a single log message changed into BeginInvoke

IControlEncryption

  • Removed obsolete signature

CryptoolStream

  • Added a try-catch when deleting a file. An exception occurs when the file is locked. Clearly, in this case there not much one can do.. the file remains on the disk. Waiting for CStream...

AES, DES, SDES

  • Cleanup of IControl interface and general code cleanup
  • Fixed compatibility with KeySearcher - now all three should work again. (However, kind of slow)

StreamToStringConverter

  • Updated license

Sample update

  • KeySearcher-Sample-DES.cte, KeySearcher-Sample-DES.cte, KeySearcher-Sample-SDES.cte: Compatibility with IControl changes and slight rearrangement.
  • P2P-DES-BruteforceManger.cte, P2P-DES-BruteforceWorker.cte: Compatibility

New binaries

  • CrypWin.exe
  • AnotherEditor.dll
File size: 23.6 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Text;
5using System.IO;
6using System.Security.Cryptography;
7using Cryptool.PluginBase;
8using System.ComponentModel;
9using Cryptool.PluginBase.Cryptography;
10using Cryptool.PluginBase.IO;
11using System.Windows.Controls;
12using Cryptool.PluginBase.Control;
13using System.Reflection;
14// Reference to the CubeAttackController interface (own dll)
15using Cryptool.CubeAttackController;
16
17namespace Cryptool.Plugins.Cryptography.Encryption
18{
19    [Author("Dr. Arno Wacker", "arno.wacker@cryptool.org", "Uni Duisburg", "http://www.uni-duisburg-essen.de")]
20    [PluginInfo(false, "DES", "Data Encryption Standard", "DES/DetailedDescription/Description.xaml", "DES/icon.png", "DES/Images/encrypt.png", "DES/Images/decrypt.png")]
21    [EncryptionType(EncryptionType.SymmetricBlock)]
22    public class DES : IEncryption
23    {
24        #region Private variables
25        private DESSettings settings;
26        private CryptoolStream inputStream;
27        private CryptoolStream outputStream;
28        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
29        private byte[] inputKey;
30        private byte[] inputIV;
31        private CryptoStream p_crypto_stream;
32        private bool stop = false;
33        private IControlEncryption controlSlave;
34        #endregion
35
36
37        #region Initialisation
38       
39        public DES()
40        {
41            this.settings = new DESSettings();
42        }
43
44
45       
46
47        #endregion
48
49        #region External connection properties
50
51        [PropertyInfo(Direction.ControlSlave, "DES Slave for Cryptanalysis", "Direct access to the DES component for cryptanalysis.", "", DisplayLevel.Beginner)]
52        public IControlEncryption ControlSlave
53        {
54            get
55            {
56                if (controlSlave == null)
57                    controlSlave = new DESControl(this);
58                return controlSlave;
59            }
60        }
61
62        private IControlCubeAttack desSlave;
63        [PropertyInfo(Direction.ControlSlave, "DES Slave for cube attack", "Direct access to the DES component for usage with the cube attack plugin.", "", DisplayLevel.Beginner)]
64        public IControlCubeAttack DESSlave
65        {
66            get
67            {
68                if (desSlave == null)
69                    desSlave = new CubeAttackControl(this);
70                return desSlave;
71            }
72        }
73
74
75        [PropertyInfo(Direction.InputData, "Input", "Data to be encrypted or decrypted", null, true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
76        public CryptoolStream InputStream
77        {
78            get 
79            {
80                if (inputStream != null)
81                {
82                    CryptoolStream cs = new CryptoolStream();
83                    cs.OpenRead(inputStream.FileName);
84                    listCryptoolStreamsOut.Add(cs);
85                    return cs;
86                }
87                else return null;
88            }
89            set 
90            { 
91              this.inputStream = value;
92              if (value != null) listCryptoolStreamsOut.Add(value);
93              OnPropertyChanged("InputStream");
94            }
95        }
96
97        [PropertyInfo(Direction.InputData, "Key", "The key for encryption7decryption. It must be exactly 8 bytes (64 Bits).", null, true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
98        public byte[] InputKey
99        {
100            get { return this.inputKey; }
101            set
102            {
103                this.inputKey = value;
104                OnPropertyChanged("InputKey");
105            }
106        }
107
108        [PropertyInfo(Direction.InputData, "IV", "IV to be used in chaining modes, must be the same as the Blocksize in bytes (8 bytes).", null, false, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
109        public byte[] InputIV
110        {
111            get { return this.inputIV; }
112            set
113            {
114                this.inputIV = value;
115                OnPropertyChanged("InputIV");
116            }
117        }
118       
119        [PropertyInfo(Direction.OutputData, "Output stream", "Encrypted or decrypted output data", null, true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
120        public CryptoolStream OutputStream
121        {
122            get
123            {
124                if (this.outputStream != null)
125                {
126                    CryptoolStream cs = new CryptoolStream();
127                    listCryptoolStreamsOut.Add(cs);
128                    cs.OpenRead(this.outputStream.FileName);
129                    return cs;
130                }
131                return null;
132            }
133            set
134            {
135                outputStream = value;
136                if (value != null) listCryptoolStreamsOut.Add(value);
137                OnPropertyChanged("OutputStream");
138            }
139        }
140
141        #endregion       
142
143        #region Public IPlugin Member
144
145        #region Events
146        public event StatusChangedEventHandler OnPluginStatusChanged;
147        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
148        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
149        #endregion
150
151        public ISettings Settings
152        {
153            get { return this.settings; }
154            set { this.settings = (DESSettings)value; }
155        }
156
157        public UserControl Presentation
158        {
159            get { return null; }
160        }
161
162        public UserControl QuickWatchPresentation
163        {
164            get { return null; }
165        }
166
167        public void Initialize()
168        {
169        }
170
171        public void Execute()
172        {
173            process(settings.Action);
174        }
175
176
177        public void Pause()
178        {
179
180        }
181
182        public void Stop()
183        {
184            this.stop = true;
185        }
186
187        public void Dispose()
188        {
189            try
190            {
191                stop = false;
192                inputKey = null;
193                inputIV = null;
194
195                inputStream = null;
196                outputStream = null;
197
198                foreach (CryptoolStream stream in listCryptoolStreamsOut)
199                {
200                    stream.Close();
201                }
202                listCryptoolStreamsOut.Clear();
203
204                if (p_crypto_stream != null)
205                {
206                    p_crypto_stream.Flush();
207                    p_crypto_stream.Close();
208                    p_crypto_stream = null;
209                }
210            }
211            catch (Exception ex)
212            {
213                GuiLogMessage(ex.Message, NotificationLevel.Error);
214            }
215            this.stop = false;
216        }
217
218       
219
220        public void PostExecution()
221        {
222            Dispose();
223        }
224
225        public void PreExecution()
226        {
227            Dispose();
228        }
229
230        #endregion
231
232        #region INotifyPropertyChanged Members
233
234        public event PropertyChangedEventHandler PropertyChanged;
235
236        public void OnPropertyChanged(string name)
237        {
238            if (PropertyChanged != null)
239            {
240                PropertyChanged(this, new PropertyChangedEventArgs(name));
241            }
242        }
243
244        #endregion
245
246           
247
248        #region Public DES specific members
249
250        public bool isStopped()
251        {
252
253            return this.stop;
254        }
255
256        #endregion
257
258
259        #region Private methods
260
261        private void ConfigureAlg(SymmetricAlgorithm alg)
262        {
263            //check for a valid key
264            if (this.inputKey == null)
265            {
266                //create a trivial key
267                inputKey = new byte[8];
268                // write a warning to the ouside word
269                GuiLogMessage("ERROR: No key provided. Using 0x000..00!", NotificationLevel.Error);
270            }
271            alg.Key = this.inputKey;
272
273            //check for a valid IV
274            if (this.inputIV == null)
275            {
276                //create a trivial key
277                inputIV = new byte[alg.BlockSize / 8];
278                GuiLogMessage("NOTE: No IV provided. Using 0x000..00!", NotificationLevel.Info);
279            }
280            alg.IV = this.inputIV;
281            switch (settings.Mode)
282            { //0="ECB"=default, 1="CBC", 2="CFB", 3="OFB"
283                case 1: alg.Mode = CipherMode.CBC; break;
284                case 2: alg.Mode = CipherMode.CFB; break;
285                case 3: alg.Mode = CipherMode.OFB; break;
286                default: alg.Mode = CipherMode.ECB; break;
287            }
288            switch (settings.Padding)
289            { //0="Zeros"=default, 1="None", 2="PKCS7"
290                case 1: alg.Padding = PaddingMode.None; break;
291                case 2: alg.Padding = PaddingMode.PKCS7; break;
292                case 3: alg.Padding = PaddingMode.ANSIX923; break;
293                case 4: alg.Padding = PaddingMode.ISO10126; break;
294                default: alg.Padding = PaddingMode.Zeros; break;
295            }
296        }
297
298        private void checkForInputStream()
299        {
300            if (settings.Action == 0 && (inputStream == null || (inputStream != null && inputStream.Length == 0)))
301            {
302                //create some input
303                String dummystring = "Dummy string - no input provided - \"Hello DES World\" - dummy string - no input provided!";
304                this.inputStream = new CryptoolStream();
305                this.inputStream.OpenRead(Encoding.Default.GetBytes(dummystring.ToCharArray()));
306                // write a warning to the ouside word
307                GuiLogMessage("WARNING - No input provided. Using dummy data. (" + dummystring + ")", NotificationLevel.Warning);
308            }
309        }
310
311        private void process(int action)
312        {
313            //Encrypt/Decrypt Stream
314            try
315            {
316                checkForInputStream();
317                if (inputStream == null || (inputStream != null && inputStream.Length == 0))
318                {
319                    GuiLogMessage("No input given. Not using dummy data in decrypt mode. Aborting now.", NotificationLevel.Error);
320                    return;
321                }
322
323                if (this.inputStream.CanSeek) this.inputStream.Position = 0;
324                SymmetricAlgorithm p_alg = new DESCryptoServiceProvider();
325
326                ConfigureAlg(p_alg);
327
328                ICryptoTransform p_encryptor = null;
329                switch (action)
330                {
331                    case 0:
332                        p_encryptor = p_alg.CreateEncryptor();
333                        break;
334                    case 1:
335                        p_encryptor = p_alg.CreateDecryptor();
336                        break;
337                }
338
339                outputStream = new CryptoolStream();
340                listCryptoolStreamsOut.Add(outputStream);
341                outputStream.OpenWrite();
342                p_crypto_stream = new CryptoStream((Stream)inputStream, p_encryptor, CryptoStreamMode.Read);
343                byte[] buffer = new byte[p_alg.BlockSize / 8];
344                int bytesRead;
345                int position = 0;
346                GuiLogMessage("Starting encryption [Keysize=" + p_alg.KeySize.ToString() + " Bits, Blocksize=" + p_alg.BlockSize.ToString() + " Bits]", NotificationLevel.Info);
347                DateTime startTime = DateTime.Now;
348                while ((bytesRead = p_crypto_stream.Read(buffer, 0, buffer.Length)) > 0 && !stop)
349                {
350                    outputStream.Write(buffer, 0, bytesRead);
351
352                    if ((int)(inputStream.Position * 100 / inputStream.Length) > position)
353                    {
354                        position = (int)(inputStream.Position * 100 / inputStream.Length);
355                        ProgressChanged(inputStream.Position, inputStream.Length);
356                    }
357                }
358
359                p_crypto_stream.Flush();
360                DateTime stopTime = DateTime.Now;
361                TimeSpan duration = stopTime - startTime;
362                if (!stop)
363                {
364                    GuiLogMessage("Encryption complete! (in: " + inputStream.Length.ToString() + " bytes, out: " + outputStream.Length.ToString() + " bytes)", NotificationLevel.Info);
365                    GuiLogMessage("Wrote data to file: " + outputStream.FileName, NotificationLevel.Info);
366                    GuiLogMessage("Time used: " + duration.ToString(), NotificationLevel.Debug);
367                    outputStream.Close();
368                    OnPropertyChanged("OutputStream");
369                }
370                if (stop)
371                {
372                    outputStream.Close();
373                    GuiLogMessage("Aborted!", NotificationLevel.Info);
374                }
375                ProgressChanged(1, 1);
376
377            }
378            catch (CryptographicException cryptographicException)
379            {
380                p_crypto_stream = null;
381                GuiLogMessage(cryptographicException.Message, NotificationLevel.Error);
382            }
383            catch (Exception exception)
384            {
385                GuiLogMessage(exception.Message, NotificationLevel.Error);
386            }
387            finally
388            {
389                ProgressChanged(1, 1);
390            }
391        }
392
393        private void GuiLogMessage(string message, NotificationLevel logLevel)
394        {
395            if (OnGuiLogNotificationOccured != null)
396            {
397                OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, logLevel));
398            }
399        }
400
401
402        private void ProgressChanged(double value, double max)
403        {
404            if (OnPluginProgressChanged != null)
405            {
406                OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
407            }
408        }
409
410        #endregion
411
412    }
413
414   
415    #region DESControl : IControlCubeAttack
416
417    public class CubeAttackControl : IControlCubeAttack
418    {
419        public event IControlStatusChangedEventHandler OnStatusChanged;
420        private DES plugin;
421
422        public CubeAttackControl(DES Plugin)
423        {
424            this.plugin = Plugin;
425        }
426
427        #region IControlEncryption Members
428
429        public int GenerateBlackboxOutputBit(object IV, object key, object length)
430        {
431            // public bits := plaintext
432            // secret bits := key
433            SymmetricAlgorithm p_alg = new DESCryptoServiceProvider();
434            string secretBits = string.Empty;
435            string publicBits = string.Empty;
436
437            // save public and secret bits as string
438            int[] temp = key as int[];
439            for (int i = 0; i < temp.Length; i++)
440                secretBits += temp[i];
441            temp = IV as int[];
442            for (int i = 0; i < temp.Length; i++)
443                publicBits += temp[i];
444
445            // convert secret bits to byte array
446            int[] arrInt = new int[8];
447            for (int i = 0; i < 8; i++)
448            {
449                for (int j = 0; j < 8; j++)
450                {
451                    if (secretBits[(8 * i) + j] == '1')
452                        arrInt[i] += (int)Math.Pow(2, 7 - j);
453                }
454            }
455            byte[] keyByte = new byte[8];
456            for (int i = 0; i < arrInt.Length; i++)
457                keyByte[i] = (byte)arrInt[i];
458
459            // convert public bits to byte array
460            arrInt = new int[8];
461            for (int i = 0; i < 8; i++)
462            {
463                for (int j = 0; j < 8; j++)
464                {
465                    if (publicBits[(8 * i) + j] == '1')
466                        arrInt[i] += (int)Math.Pow(2, 7 - j);
467                }
468            }
469            byte[] publicByte = new byte[8];
470            for (int i = 0; i < arrInt.Length; i++)
471                publicByte[i] = (byte)arrInt[i];
472
473            ICryptoTransform p_encryptor;
474            p_alg.IV = new byte[8];
475            p_alg.Padding = PaddingMode.Zeros;
476            try
477            {
478                p_alg.Key = keyByte;
479            }
480            catch
481            {
482                //dirty hack to allow weak keys:
483                FieldInfo field = p_alg.GetType().GetField("KeyValue", BindingFlags.NonPublic | BindingFlags.Instance);
484                field.SetValue(p_alg, keyByte);
485            }
486            try
487            {
488                p_encryptor = p_alg.CreateEncryptor();
489            }
490            catch
491            {
492                //dirty hack to allow weak keys:
493                MethodInfo mi = p_alg.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
494                object[] Par = { p_alg.Key, p_alg.Mode, p_alg.IV, p_alg.FeedbackSize, 0 };
495                p_encryptor = mi.Invoke(p_alg, Par) as ICryptoTransform;
496            }
497           
498            Stream inputPublic = new MemoryStream(publicByte);
499            // starting encryption
500            CryptoStream p_crypto_stream = new CryptoStream(inputPublic, p_encryptor, CryptoStreamMode.Read);
501            byte[] buffer = new byte[p_alg.BlockSize / 8];
502            p_crypto_stream.Read(buffer, 0, buffer.Length);
503               
504            // convert encrypted block to binary string
505            string strBytes = string.Empty;
506            for (int i = 0; i < buffer.Length; i++)
507            {
508                for (int j = 7; j >= 0; j--)
509                    strBytes += (buffer[i] & 1 << j) > 0 ? 1 : 0;
510            }
511            p_crypto_stream.Flush();
512
513            // return single output bit
514            return Int32.Parse(strBytes.Substring((int)length-1, 1));
515        }
516        #endregion
517    }
518
519    #endregion
520
521
522    #region DESControl : IControlEncryption
523    public class DESControl : IControlEncryption
524    {
525        public event KeyPatternChanged keyPatternChanged;
526        public event IControlStatusChangedEventHandler OnStatusChanged;
527
528       
529        private DES plugin;
530
531        public DESControl(DES Plugin)
532        {
533            this.plugin = Plugin;
534
535            // Change the padding mode to zeroes, since we want to do bruteforcing..
536            ((DESSettings)plugin.Settings).Padding = 0;
537        }
538
539       
540
541        public byte[] Encrypt(byte[] key, int blocksize)
542        {
543            /// not implemented, currently not needed
544            throw new NotImplementedException();
545        }
546
547        // TODO: add override with iv, mode, blocksize
548        public byte[] Decrypt(byte[] ciphertext, byte[] key)
549        {
550            CryptoStream crypto_stream = null;
551            byte[] output = new byte[ciphertext.Length];
552           
553            // always recreating this instance is thread-safe, but may cost us some performance
554            SymmetricAlgorithm des_algorithm  = new DESCryptoServiceProvider();
555
556            switch (((DESSettings)plugin.Settings).Mode)
557            { //0="ECB"=default, 1="CBC", 2="CFB", 3="OFB"
558                case 1: des_algorithm.Mode = CipherMode.CBC; break;
559                case 2: des_algorithm.Mode = CipherMode.CFB; break;
560                case 3: des_algorithm.Mode = CipherMode.OFB; break;
561                default: des_algorithm.Mode = CipherMode.ECB; break;
562            }
563
564            // Padding for DES must always be set to zeroes
565            // other padding types lead to error while decrypting
566            // padding type of none leads to error if size does not match exactly a multiple of 8 Byte
567            des_algorithm.Padding = PaddingMode.Zeros;
568
569            // TODO: this must be passed via the interface
570            des_algorithm.IV = new byte[des_algorithm.BlockSize / 8]; // IV of 0x00..00
571
572            try
573            {
574                des_algorithm.Key = key;
575            }
576            catch
577            {
578                //dirty hack to allow weak keys:
579                FieldInfo field = des_algorithm.GetType().GetField("KeyValue", BindingFlags.NonPublic | BindingFlags.Instance);
580                //Console.WriteLine(des_algorithm.GetType());
581                field.SetValue(des_algorithm, key);
582            }
583
584            ICryptoTransform p_decryptor;
585            try
586            {
587                p_decryptor = des_algorithm.CreateDecryptor();
588            }
589            catch
590            {
591                //dirty hack to allow weak keys:
592                MethodInfo mi = des_algorithm.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
593                object[] Par = { des_algorithm.Key, des_algorithm.Mode, des_algorithm.IV, des_algorithm.FeedbackSize, 0 };
594                p_decryptor = mi.Invoke(des_algorithm, Par) as ICryptoTransform;
595            }
596
597            crypto_stream = new CryptoStream(new MemoryStream(ciphertext), p_decryptor, CryptoStreamMode.Read);
598
599            int read, readOverall = 0;
600            do
601            {
602                read = crypto_stream.Read(output, readOverall, output.Length - readOverall);
603                readOverall += read;
604            } while (read > 0 && readOverall < output.Length);
605
606            return output;
607        }
608
609        public string getKeyPattern()
610        {
611            return "[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-"
612                +"[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]";
613        }
614
615        public byte[] getKeyFromString(string key, ref int[] arrayPointers, ref int[] arraySuccessors, ref int[] arrayUppers)
616        {
617            byte[] bkey = new byte[8];
618            int counter = 0;
619            bool allocated = false;
620
621            for (int i = 0; i <= 7; i++)
622            {
623                string substr = key.Substring(i * 3, 2);
624
625                if (!allocated && (substr[0] == '*' || substr[1] == '*'))
626                {
627                    arrayPointers = new int[8];
628                    for (int j = 0; j < 8; j++)
629                        arrayPointers[j] = -1;
630                    arraySuccessors = new int[8];
631                    arrayUppers = new int[8];
632                    allocated = true;
633                }
634
635                if (substr[0] != '*' && substr[1] != '*')
636                    bkey[i] = Convert.ToByte(substr, 16);
637                else if (substr[0] == '*' && substr[1] == '*')
638                {
639                    bkey[i] = 0;
640                    arrayPointers[counter] = i;
641                    arraySuccessors[counter] = 1;
642                    arrayUppers[counter] = 255;
643                    counter++;
644                }
645                else if (substr[0] != '*' && substr[1] == '*')
646                {
647                    bkey[i] = Convert.ToByte(substr[0] + "0", 16);
648                    arrayPointers[counter] = i;
649                    arraySuccessors[counter] = 1;
650                    arrayUppers[counter] = Convert.ToByte(substr[0] + "F", 16);
651                    counter++;
652                }
653                else if (substr[0] == '*' && substr[1] != '*')
654                {
655                    bkey[i] = Convert.ToByte("0" + substr[1], 16);
656                    arrayPointers[counter] = i;
657                    arraySuccessors[counter] = 16;
658                    arrayUppers[counter] = Convert.ToByte("F" + substr[1], 16);
659                    counter++;
660                }
661            }
662            return bkey;
663        }
664
665        public IControlEncryption clone()
666        {
667            DESControl des = new DESControl(plugin);
668            return des;
669        }
670
671        public void Dispose()
672        {
673           
674        }
675
676        public void changeSettings(string setting, object value)
677        {
678            throw new NotImplementedException();
679        }
680
681    }
682    #endregion
683}
Note: See TracBrowser for help on using the repository browser.