source: trunk/CrypPlugins/RSA/RSAKeyGenerator.cs @ 1448

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

replaced all BigInteger stuff with the new BigInteger class from .net 4.0

But there are still problems with some plugins (Keysearcher, BigInteger Operations...)

File size: 14.4 KB
Line 
1/*                             
2   Copyright 2009 Team CrypTool (Sven Rech,Dennis Nolte,Raoul Falk,Nils Kopal), Uni Duisburg-Essen
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15*/
16
17using System;
18using System.Collections.Generic;
19using System.Linq;
20using System.Text;
21using Cryptool.PluginBase.Cryptography;
22using Cryptool.PluginBase.Miscellaneous;
23using Cryptool.PluginBase;
24using System.ComponentModel;
25using System.Security.Cryptography;
26using System.Security.Cryptography.X509Certificates;
27using System.Numerics;
28
29namespace Cryptool.Plugins.RSA
30{
31    [Author("Dennis Nolte, Raoul Falk, Sven Rech, Nils Kopal", "", "Uni Duisburg-Essen", "http://www.uni-due.de")]
32    [PluginInfo(true, "RSAKeyGenerator", "RSA Key Generator", "RSA/DetailedDescription/Description.xaml", "RSA/iconkey.png")]
33    [EncryptionType(EncryptionType.Asymmetric)]
34    ///<summary>
35    /// This plugin is a generator plugin which helps the user to generate pairs of private/public keys
36    /// for the RSA algorithm
37    ///
38    /// there are several modes:
39    ///
40    /// 1. manual
41    ///     in this mode the p and q or the n and e and d are given by the user, the d also may be generated
42    ///     
43    /// 2. generated
44    ///     in this mode all will be generated by microsoft classes
45    ///     
46    /// 3. certificate
47    ///     in this mode a x509 certificate will be loaded (the user can give a password for loading)
48    /// </summary>   
49    class RSAKeyGenerator : IEncryption
50    {
51        #region private members
52
53        private BigInteger n;       
54        private BigInteger e;
55        private BigInteger d;
56        private RSAKeyGeneratorSettings settings = new RSAKeyGeneratorSettings();
57
58        #endregion
59       
60        #region envents
61
62        public event Cryptool.PluginBase.StatusChangedEventHandler OnPluginStatusChanged;
63        public event Cryptool.PluginBase.GuiLogNotificationEventHandler OnGuiLogNotificationOccured;
64        public event Cryptool.PluginBase.PluginProgressChangedEventHandler OnPluginProgressChanged;
65        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
66
67        #endregion
68
69        #region public
70
71        /// <summary>
72        /// Sets the N of the public/private key
73        /// </summary>
74        [PropertyInfo(Direction.OutputData, "N", "N", "", DisplayLevel.Beginner)]
75        public BigInteger N
76        {
77            get
78            {
79                return n;
80            }
81            set
82            {
83                this.n = value;
84                OnPropertyChanged("N");
85            }
86        }
87
88        /// <summary>
89        /// Sets the E of the public key
90        /// </summary>
91        [PropertyInfo(Direction.OutputData, "E", "public exponent", "", DisplayLevel.Beginner)]
92        public BigInteger E
93        {
94            get
95            {
96                return e;
97            }
98            set
99            {
100                this.e = value;
101                OnPropertyChanged("E");
102            }
103        }
104
105        /// <summary>
106        /// Sets the D of the private key
107        /// </summary>
108        [PropertyInfo(Direction.OutputData, "D", "private exponent", "", DisplayLevel.Beginner)]
109        public BigInteger D
110        {
111            get
112            {
113                return d;
114            }
115            set
116            {
117                this.d = value;
118                OnPropertyChanged("D");
119            }
120        }
121
122        /// <summary>
123        /// Getter/Setter for the settings of this plugin
124        /// </summary>
125        public ISettings Settings
126        {
127            get { return this.settings; }
128            set { this.settings = (RSAKeyGeneratorSettings)value; }
129        }
130
131        /// <summary>
132        /// Get the presentation of this plugin
133        /// </summary>
134        public System.Windows.Controls.UserControl Presentation
135        {
136            get { return null; }
137        }
138
139        /// <summary>
140        /// Get the quickwatchpresentation of this plugin
141        /// </summary>
142        public System.Windows.Controls.UserControl QuickWatchPresentation
143        {
144            get { return null; }
145        }
146
147        /// <summary>
148        /// This method is called by the environment before execution
149        /// </summary>
150        public void PreExecution()
151        {
152
153        }
154
155        /// <summary>
156        /// Called by the environment to start generating of public/private keys
157        /// </summary>
158        public void Execute()
159        {
160            BigInteger p;
161            BigInteger q;
162            BigInteger n;
163            BigInteger e;
164            BigInteger d;
165
166            ProgressChanged(0.5, 1.0);
167            switch (settings.Source)
168            {
169                // manual
170                case 0:
171                    try
172                    {
173                        p = BigIntegerHelper.parseExpression(settings.P);
174                        q = BigIntegerHelper.parseExpression(settings.Q);
175                        e = BigIntegerHelper.parseExpression(settings.E);
176
177                        if (!BigIntegerHelper.isProbablePrime(p))
178                        {
179                            GuiLogMessage(p.ToString() + " is not prime!", NotificationLevel.Error);
180                            return;
181                        }
182                        if (!BigIntegerHelper.isProbablePrime(q))
183                        {
184                            GuiLogMessage(q.ToString() + " is not prime!", NotificationLevel.Error);
185                            return;
186                        }
187                        if (p == q)
188                        {
189                            GuiLogMessage("The primes P and Q can not be equal!", NotificationLevel.Error);
190                            return;
191                        }
192                    }
193                    catch (Exception ex)
194                    {
195                        GuiLogMessage("Invalid Big Number input: " + ex.Message, NotificationLevel.Error);
196                        return;
197                    }
198
199                    try
200                    {
201                        D = BigIntegerHelper.ModInverse(e, (p - 1) * (q - 1));
202                    }
203                    catch (Exception)
204                    {
205                        GuiLogMessage("RSAKeyGenerator Error: E (" + e + ") can not be inverted.", NotificationLevel.Error);
206                        return;
207                    }
208                    try
209                    {                       
210                        N = p * q;
211                        E = e;                       
212                    }
213                    catch (Exception ex)
214                    {
215                        GuiLogMessage("Big Number fail: " + ex.Message, NotificationLevel.Error);
216                        return;
217                    }
218                    break;
219
220                case 1:
221                    try
222                    {
223                        n = BigIntegerHelper.parseExpression(settings.N);
224                        d = BigIntegerHelper.parseExpression(settings.D);
225                        e = BigIntegerHelper.parseExpression(settings.E);
226                    }
227                    catch (Exception ex)
228                    {
229                        GuiLogMessage("Invalid Big Number input: " + ex.Message, NotificationLevel.Error);
230                        return;
231                    }
232                   
233                    try
234                    {
235                        N = n;
236                        E = e;
237                        D = d;
238                    }
239                    catch (Exception ex)
240                    {
241                        GuiLogMessage("Big Number fail: " + ex.Message, NotificationLevel.Error);
242                        return;
243                    }
244                    break;
245
246                //random generated
247                case 2:
248                    try
249                    {
250                        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
251                        RSAParameters rsaParameters = rsa.ExportParameters(true);
252                        p = new BigInteger(rsaParameters.P);
253                        q = new BigInteger(rsaParameters.Q);
254                        n = new BigInteger(rsaParameters.Modulus);
255                        e = new BigInteger(rsaParameters.Exponent);
256                        d = new BigInteger(rsaParameters.D);
257                    }
258                    catch (Exception ex)
259                    {
260                        GuiLogMessage(ex.Message, NotificationLevel.Error);
261                        return;
262                    }
263
264                    N = n;
265                    E = e;
266                    D = d;
267                    break;
268               
269                //using x509 certificate
270                case 3:
271                    try
272                    {
273
274                        X509Certificate2 cert;
275                        RSAParameters par;
276
277                        if (this.settings.Password != "")
278                        {
279                            GuiLogMessage("Password entered. Try getting public and private key", NotificationLevel.Info);
280                            cert = new X509Certificate2(settings.CertificateFile, settings.Password, X509KeyStorageFlags.Exportable);
281                            if (cert == null || cert.PrivateKey == null)
282                                throw new Exception("Private Key of X509Certificate could not be fetched");
283                            RSACryptoServiceProvider provider = (RSACryptoServiceProvider)cert.PrivateKey;                           
284                            par = provider.ExportParameters(true);                           
285                           
286                        }
287                        else 
288                        {
289                            GuiLogMessage("No Password entered. Try loading public key only", NotificationLevel.Info);
290                            cert = new X509Certificate2(settings.CertificateFile);
291                            if (cert == null || cert.PublicKey == null || cert.PublicKey.Key == null)
292                                throw new Exception("Private Key of X509Certificate could not be fetched");
293                            RSACryptoServiceProvider provider = (RSACryptoServiceProvider)cert.PublicKey.Key;
294                            par = provider.ExportParameters(false);
295                        }
296
297                        try
298                        {
299                            N = new BigInteger(par.Modulus);
300                        }
301                        catch (Exception ex)
302                        {
303                            GuiLogMessage("Could not get N from certificate: " + ex.Message, NotificationLevel.Warning);
304                        }
305
306                        try
307                        {
308                            E = new BigInteger(par.Exponent);
309                        }
310                        catch (Exception ex)
311                        {
312                            GuiLogMessage("Could not get E from certificate: " + ex.Message, NotificationLevel.Warning);
313                        }
314
315                        try
316                        {
317                            if (this.settings.Password != "")
318                                D = new BigInteger(par.D);
319                            else
320                                D = 0;
321                        }
322                        catch (Exception ex)
323                        {
324                            GuiLogMessage("Could not get D from certificate: " + ex.Message, NotificationLevel.Warning);
325                        }
326
327                    }
328                    catch (Exception ex)
329                    {
330                        GuiLogMessage("Could not load the selected certificate: " + ex.Message, NotificationLevel.Error);
331                    }
332                    break;
333            }
334            ProgressChanged(1.0, 1.0);
335        }
336
337        /// <summary>
338        /// This method is called by the environment after execution
339        /// </summary>
340        public void PostExecution()
341        {
342        }
343
344        /// <summary>
345        /// This method is called by the environment to pause this plugin
346        /// </summary>
347        public void Pause()
348        {
349
350        }
351
352        /// <summary>
353        /// This method is called by the environment to stop execution
354        /// </summary>
355        public void Stop()
356        {
357        }
358
359        /// <summary>
360        /// This method is called by the environment to initialise the plugin
361        /// </summary>
362        public void Initialize()
363        {
364            settings.UpdateTaskPaneVisibility();
365        }
366
367        /// <summary>
368        /// This method is called by the environment to dispose
369        /// </summary>
370        public void Dispose()
371        {
372        }
373       
374        #endregion
375
376        #region private
377
378        /// <summary>
379        /// Changes the progress of this plugin
380        /// </summary>
381        private void ProgressChanged(double value, double max)
382        {
383            EventsHelper.ProgressChanged(OnPluginProgressChanged, this, new PluginProgressEventArgs(value, max));
384        }
385
386        /// <summary>
387        /// Logs a message to cryptool
388        /// </summary>
389        private void GuiLogMessage(string p, NotificationLevel notificationLevel)
390        {
391            EventsHelper.GuiLogMessage(OnGuiLogNotificationOccured, this, new GuiLogEventArgs(p, this, notificationLevel));
392        }
393
394        /// <summary>
395        /// The property name changed
396        /// </summary>
397        /// <param name="name">name</param>
398        public void OnPropertyChanged(string name)
399        {
400            EventsHelper.PropertyChanged(PropertyChanged, this, new PropertyChangedEventArgs(name));
401        }
402
403        #endregion
404   
405    }//end RSAKeyGenerator
406
407}//end Cryptool.Plugins.RSA
Note: See TracBrowser for help on using the repository browser.