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

Last change on this file since 717 was 717, checked in by Sven Rech, 12 years ago

some KeySearcher changes

File size: 14.7 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;
13
14namespace Cryptool.Plugins.Cryptography.Encryption
15{
16    [PluginInfo(false, "DES", "Data Encryption Standard", "DES/DetailedDescription/Description.xaml", "DES/icon.png", "DES/Images/encrypt.png", "DES/Images/decrypt.png")]
17    [EncryptionType(EncryptionType.SymmetricBlock)]
18    public class DES : IEncryption
19    {
20        #region Private variables
21        private DESSettings settings;
22        private CryptoolStream inputStream;
23        private CryptoolStream outputStream;
24        private List<CryptoolStream> listCryptoolStreamsOut = new List<CryptoolStream>();
25        private byte[] inputKey;
26        private byte[] inputIV;
27        private CryptoStream p_crypto_stream;
28        private bool stop = false;
29        #endregion
30
31        public DES()
32        {
33            this.settings = new DESSettings();
34            this.settings.OnPluginStatusChanged += settings_OnPluginStatusChanged;
35        }
36
37        void settings_OnPluginStatusChanged(IPlugin sender, StatusEventArgs args)
38        {
39            if(OnPluginStatusChanged != null)OnPluginStatusChanged(this, args);
40        }
41
42        public ISettings Settings
43        {
44            get { return this.settings; }
45            set { this.settings = (DESSettings)value; }
46        }
47
48        [PropertyInfo(Direction.InputData, "Input", "Data to be encrypted or decrypted", null, true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
49        public CryptoolStream InputStream
50        {
51            get 
52            {
53                if (inputStream != null)
54                {
55                    CryptoolStream cs = new CryptoolStream();
56                    cs.OpenRead(inputStream.FileName);
57                    listCryptoolStreamsOut.Add(cs);
58                    return cs;
59                }
60                else return null;
61            }
62            set 
63            { 
64              this.inputStream = value;
65              if (value != null) listCryptoolStreamsOut.Add(value);
66              OnPropertyChanged("InputStream");
67            }
68        }
69
70        [PropertyInfo(Direction.InputData, "Key", "Must be 8 bytes.", null, true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
71        public byte[] InputKey
72        {
73            get { return this.inputKey; }
74            set
75            {
76                this.inputKey = value;
77                OnPropertyChanged("InputKey");
78            }
79        }
80
81        [PropertyInfo(Direction.InputData, "IV", "IV to be used in chaining modes, must be the same as the Blocksize in bytes (8 bytes).", null, true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
82        public byte[] InputIV
83        {
84            get { return this.inputIV; }
85            set
86            {
87                this.inputIV = value;
88                OnPropertyChanged("InputIV");
89            }
90        }
91       
92        [PropertyInfo(Direction.OutputData, "Output stream", "Encrypted or decrypted output data", null, true, false, DisplayLevel.Beginner, QuickWatchFormat.Hex, null)]
93        public CryptoolStream OutputStream
94        {
95            get
96            {
97                if (this.outputStream != null)
98                {
99                    CryptoolStream cs = new CryptoolStream();
100                    listCryptoolStreamsOut.Add(cs);
101                    cs.OpenRead(this.outputStream.FileName);
102                    return cs;
103                }
104                return null;
105            }
106            set
107            {
108                outputStream = value;
109                if (value != null) listCryptoolStreamsOut.Add(value);
110                OnPropertyChanged("OutputStream");
111            }
112        }
113
114        private void ConfigureAlg(SymmetricAlgorithm alg)
115        {
116            //check for a valid key
117            if (this.inputKey == null)
118            {
119                //create a trivial key
120                inputKey = new byte[8];
121                // write a warning to the ouside word
122                GuiLogMessage("WARNING - No key provided. Using 0x000..00!", NotificationLevel.Warning);
123            }
124            alg.Key = this.inputKey;
125
126            //check for a valid IV
127            if (this.inputIV == null)
128            {
129                //create a trivial key
130                inputIV = new byte[alg.BlockSize / 8];
131               GuiLogMessage("WARNING - No IV provided. Using 0x000..00!", NotificationLevel.Warning);
132            }
133            alg.IV = this.inputIV;
134            switch (settings.Mode)
135            { //0="ECB"=default, 1="CBC", 2="CFB", 3="OFB"
136                case 1: alg.Mode = CipherMode.CBC; break;
137                case 2: alg.Mode = CipherMode.CFB; break;
138                case 3: alg.Mode = CipherMode.OFB; break;
139                default: alg.Mode = CipherMode.ECB; break;
140            }
141            switch (settings.Padding)
142            { //0="Zeros"=default, 1="None", 2="PKCS7"
143                case 1: alg.Padding = PaddingMode.None; break;
144                case 2: alg.Padding = PaddingMode.PKCS7; break;
145                case 3: alg.Padding = PaddingMode.ANSIX923; break;
146                case 4: alg.Padding = PaddingMode.ISO10126; break;
147                default: alg.Padding = PaddingMode.Zeros; break;
148            }
149        }
150
151        private void checkForInputStream()
152        {
153            if (settings.Action == 0 && (inputStream == null || (inputStream != null && inputStream.Length == 0)))
154            {
155                //create some input
156                String dummystring = "Dummy string - no input provided - \"Hello DES World\" - dummy string - no input provided!";
157                this.inputStream = new CryptoolStream();
158                this.inputStream.OpenRead(this.GetPluginInfoAttribute().Caption, Encoding.Default.GetBytes(dummystring.ToCharArray()));
159                // write a warning to the ouside word
160                GuiLogMessage("WARNING - No input provided. Using dummy data. (" + dummystring + ")", NotificationLevel.Warning);
161            }
162        }
163
164        public void Execute()
165        {
166            process(settings.Action);
167        }
168
169        private void process(int action)
170        {
171            //Encrypt/Decrypt Stream
172            try
173            {
174                checkForInputStream();
175                if (inputStream == null || (inputStream != null && inputStream.Length == 0))
176                {
177                    GuiLogMessage("No input given. Not using dummy data in decrypt mode. Aborting now.", NotificationLevel.Error);
178                    return;
179                }
180
181                if (this.inputStream.CanSeek) this.inputStream.Position = 0;
182                SymmetricAlgorithm p_alg = new DESCryptoServiceProvider();
183
184                ConfigureAlg(p_alg);
185
186                ICryptoTransform p_encryptor = null;
187                switch (action)
188                {
189                    case 0:
190                        p_encryptor = p_alg.CreateEncryptor();
191                        break;
192                    case 1:
193                        p_encryptor = p_alg.CreateDecryptor();
194                        break;
195                }
196
197                outputStream = new CryptoolStream();
198                listCryptoolStreamsOut.Add(outputStream);
199                outputStream.OpenWrite(this.GetPluginInfoAttribute().Caption);
200                p_crypto_stream = new CryptoStream((Stream)inputStream, p_encryptor, CryptoStreamMode.Read);
201                byte[] buffer = new byte[p_alg.BlockSize / 8];
202                int bytesRead;
203                int position = 0;
204                GuiLogMessage("Starting encryption [Keysize=" + p_alg.KeySize.ToString() + " Bits, Blocksize=" + p_alg.BlockSize.ToString() + " Bits]", NotificationLevel.Info);
205                DateTime startTime = DateTime.Now;
206                while ((bytesRead = p_crypto_stream.Read(buffer, 0, buffer.Length)) > 0 && !stop)
207                {
208                    outputStream.Write(buffer, 0, bytesRead);
209
210                    if ((int)(inputStream.Position * 100 / inputStream.Length) > position)
211                    {
212                        position = (int)(inputStream.Position * 100 / inputStream.Length);
213                        ProgressChanged(inputStream.Position, inputStream.Length);
214                    }
215                }
216                p_crypto_stream.Flush();
217                outputStream.Close();
218                DateTime stopTime = DateTime.Now;
219                TimeSpan duration = stopTime - startTime;
220                if (!stop)
221                {
222                    GuiLogMessage("Encryption complete! (in: " + inputStream.Length.ToString() + " bytes, out: " + outputStream.Length.ToString() + " bytes)", NotificationLevel.Info);
223                    GuiLogMessage("Wrote data to file: " + outputStream.FileName, NotificationLevel.Info);
224                    GuiLogMessage("Time used: " + duration.ToString(), NotificationLevel.Debug);
225                    OnPropertyChanged("OutputStream");
226                }
227                if (stop)
228                {
229                    GuiLogMessage("Aborted!", NotificationLevel.Info);
230                }
231            }
232            catch (CryptographicException cryptographicException)
233            {
234                p_crypto_stream = null;
235                GuiLogMessage(cryptographicException.Message, NotificationLevel.Error);
236            }
237            catch (Exception exception)
238            {
239                GuiLogMessage(exception.Message, NotificationLevel.Error);
240            }
241            finally
242            {
243                ProgressChanged(1, 1);
244            }
245        }
246
247        public void Encrypt()
248        {
249            //Encrypt Stream
250            process(0);
251        }
252
253        public void Decrypt()
254        {
255            //Decrypt Stream
256            process(1);
257        }
258
259        #region IPlugin Member
260
261        public UserControl Presentation
262        {
263            get { return null; }
264        }
265
266        public UserControl QuickWatchPresentation
267        {
268          get { return null; }
269        }
270
271        public void Initialize()
272        {
273        }
274
275        public void Dispose()
276        {
277            try
278            {
279                stop = false;
280                inputKey = null;
281                inputIV = null;
282
283                foreach (CryptoolStream stream in listCryptoolStreamsOut)
284                {
285                    stream.Close();
286                }
287                listCryptoolStreamsOut.Clear();
288
289                if (p_crypto_stream != null)
290                {
291                    p_crypto_stream.Flush();
292                    p_crypto_stream.Close();
293                    p_crypto_stream = null;
294                }
295            }
296            catch (Exception ex)
297            {
298                GuiLogMessage(ex.Message, NotificationLevel.Error);
299            }
300            this.stop = false;
301        }
302
303        public void Stop()
304        {
305            this.stop = true;
306        }
307
308        public void PostExecution()
309        {
310            Dispose();
311        }
312
313        public void PreExecution()
314        {
315            Dispose();
316        }
317
318        #endregion
319
320        #region INotifyPropertyChanged Members
321
322        public event PropertyChangedEventHandler PropertyChanged;
323
324        public void OnPropertyChanged(string name)
325        {
326            if (PropertyChanged != null)
327            {
328                PropertyChanged(this, new PropertyChangedEventArgs(name));
329            }
330        }
331
332        #endregion
333
334        #region IPlugin Members
335
336        public event StatusChangedEventHandler OnPluginStatusChanged;
337
338        public event GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
339        private void GuiLogMessage(string message, NotificationLevel logLevel)
340        {
341          if (OnGuiLogNotificationOccured != null)
342          {
343            OnGuiLogNotificationOccured(this, new GuiLogEventArgs(message, this, logLevel));
344          }
345        }
346
347        public event PluginProgressChangedEventHandler OnPluginProgressChanged;
348        private void ProgressChanged(double value, double max)
349        {
350          if (OnPluginProgressChanged != null)
351          {
352            OnPluginProgressChanged(this, new PluginProgressEventArgs(value, max));
353          }
354        }
355
356        public void Pause()
357        {
358         
359        }
360
361        #endregion
362
363        private IControlEncryption controlSlave;
364        [PropertyInfo(Direction.ControlSlave, "DES Slave", "Direct access to DES.", "", DisplayLevel.Beginner)]
365        public IControlEncryption ControlSlave
366        {
367          get
368          {
369              if (controlSlave == null)
370                  controlSlave = new DESControl(this);
371              return controlSlave;
372          }
373        }   
374    }
375
376    public class DESControl : IControlEncryption
377    {
378        public event KeyPatternChanged keyPatternChanged;
379        public event IControlStatusChangedEventHandler OnStatusChanged;
380        private DES plugin;
381
382        public DESControl(DES Plugin)
383        {
384            this.plugin = Plugin;
385        }
386
387        #region IControlEncryption Members
388
389        public byte[] Encrypt(byte[] key, int blocksize)
390        {
391            ((DESSettings)plugin.Settings).Action = 0;
392            return execute(key);
393        }
394
395        public byte[] Decrypt(byte[] key, int blocksize)
396        {
397            ((DESSettings)plugin.Settings).Action = 1;
398            return execute(key);
399        }
400
401        public string getKeyPattern()
402        {
403            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]-"
404                +"[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]";
405        }
406
407        public byte[] getKeyFromString(string key)
408        {
409            byte[] bkey = new byte[8];
410            for (int i = 0; i < 7; i++)
411            {
412                bkey[i] = Convert.ToByte(key.Substring(i * 3, 2), 16);               
413            }
414            return bkey;
415        }
416
417        private byte[] execute(byte[] key)
418        {
419            plugin.InputKey = key;
420            plugin.Execute();
421            CryptoolStream output = plugin.OutputStream;
422
423            byte[] byteValues = new byte[output.Length];
424            int bytesRead;
425            output.Seek(0, SeekOrigin.Begin);
426            bytesRead = output.Read(byteValues, 0, byteValues.Length);
427            plugin.Dispose();
428            output.Close();
429            return byteValues;
430        }
431
432        #endregion
433    }
434}
Note: See TracBrowser for help on using the repository browser.