//////////////////////////////////////////////////////////////////// /// frmMain.cs /// © 2005 Carl Johansen /// /// UI for RSA Encryption demonstration //////////////////////////////////////////////////////////////////// using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace CarlInc.Demos.RSA { /// /// UI for RSA Encryption demonstration /// public class frmMain : System.Windows.Forms.Form { private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.RichTextBox richTxtKeyGenProgress; private System.Windows.Forms.GroupBox groupBox2; private System.Windows.Forms.Label label4; private System.Windows.Forms.Label label3; private System.Windows.Forms.Button cmdGenerateKey; private System.Windows.Forms.Label label1; /// /// Required designer variable. /// private System.ComponentModel.Container components = null; private System.Windows.Forms.GroupBox groupBox3; private System.Windows.Forms.Button cmdEncryptPublic; private System.Windows.Forms.Label label6; private System.Windows.Forms.TextBox txtMsgToEncrypt; private System.Windows.Forms.Button cmdEncryptPrivate; private System.Windows.Forms.TextBox txtEncryptedMsg; private System.Windows.Forms.Label label5; private System.Windows.Forms.Label lblPrivateKey; private System.Windows.Forms.Label lblPublicKey; private System.Windows.Forms.Label label9; private System.Windows.Forms.Label label10; private System.Windows.Forms.Label lblPhiNvalue; private System.Windows.Forms.Label lblNvalue; private System.Windows.Forms.Label lblPhiN; private System.Windows.Forms.ComboBox cboPrime1; private System.Windows.Forms.ComboBox cboPrime2; private System.Windows.Forms.GroupBox groupBox4; private System.Windows.Forms.TextBox txtPrivateCipher; private System.Windows.Forms.TextBox txtPublicCipher; private System.Windows.Forms.Label label2; private System.Windows.Forms.Label label7; private System.Windows.Forms.Label lblMsgNum; private System.Windows.Forms.Label lblMsgMod; private System.Windows.Forms.Label lblEncryptionExponent; private RSAEncryptor rsaEncryptor = new RSAEncryptor(); private delegate uint EncryptDelegate(uint theMessage); public frmMain() { // // Required for Windows Form Designer support // InitializeComponent(); } /// /// Clean up any resources being used. /// protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code /// /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() { this.groupBox1 = new System.Windows.Forms.GroupBox(); this.lblPrivateKey = new System.Windows.Forms.Label(); this.lblPublicKey = new System.Windows.Forms.Label(); this.label9 = new System.Windows.Forms.Label(); this.label10 = new System.Windows.Forms.Label(); this.lblPhiNvalue = new System.Windows.Forms.Label(); this.lblNvalue = new System.Windows.Forms.Label(); this.lblPhiN = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); this.richTxtKeyGenProgress = new System.Windows.Forms.RichTextBox(); this.groupBox2 = new System.Windows.Forms.GroupBox(); this.cboPrime2 = new System.Windows.Forms.ComboBox(); this.cboPrime1 = new System.Windows.Forms.ComboBox(); this.cmdGenerateKey = new System.Windows.Forms.Button(); this.label4 = new System.Windows.Forms.Label(); this.label3 = new System.Windows.Forms.Label(); this.groupBox3 = new System.Windows.Forms.GroupBox(); this.lblEncryptionExponent = new System.Windows.Forms.Label(); this.lblMsgMod = new System.Windows.Forms.Label(); this.lblMsgNum = new System.Windows.Forms.Label(); this.label5 = new System.Windows.Forms.Label(); this.txtEncryptedMsg = new System.Windows.Forms.TextBox(); this.cmdEncryptPrivate = new System.Windows.Forms.Button(); this.cmdEncryptPublic = new System.Windows.Forms.Button(); this.label6 = new System.Windows.Forms.Label(); this.txtMsgToEncrypt = new System.Windows.Forms.TextBox(); this.groupBox4 = new System.Windows.Forms.GroupBox(); this.label7 = new System.Windows.Forms.Label(); this.label2 = new System.Windows.Forms.Label(); this.txtPrivateCipher = new System.Windows.Forms.TextBox(); this.txtPublicCipher = new System.Windows.Forms.TextBox(); this.groupBox1.SuspendLayout(); this.groupBox2.SuspendLayout(); this.groupBox3.SuspendLayout(); this.groupBox4.SuspendLayout(); this.SuspendLayout(); // // groupBox1 // this.groupBox1.Controls.Add(this.lblPrivateKey); this.groupBox1.Controls.Add(this.lblPublicKey); this.groupBox1.Controls.Add(this.label9); this.groupBox1.Controls.Add(this.label10); this.groupBox1.Controls.Add(this.lblPhiNvalue); this.groupBox1.Controls.Add(this.lblNvalue); this.groupBox1.Controls.Add(this.lblPhiN); this.groupBox1.Controls.Add(this.label1); this.groupBox1.Controls.Add(this.richTxtKeyGenProgress); this.groupBox1.Location = new System.Drawing.Point(8, 152); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(304, 288); this.groupBox1.TabIndex = 7; this.groupBox1.TabStop = false; this.groupBox1.Text = "Step 2 - Key generation"; // // lblPrivateKey // this.lblPrivateKey.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); this.lblPrivateKey.Location = new System.Drawing.Point(104, 264); this.lblPrivateKey.Name = "lblPrivateKey"; this.lblPrivateKey.Size = new System.Drawing.Size(112, 13); this.lblPrivateKey.TabIndex = 18; // // lblPublicKey // this.lblPublicKey.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); this.lblPublicKey.Location = new System.Drawing.Point(104, 240); this.lblPublicKey.Name = "lblPublicKey"; this.lblPublicKey.Size = new System.Drawing.Size(112, 13); this.lblPublicKey.TabIndex = 17; // // label9 // this.label9.Location = new System.Drawing.Point(24, 264); this.label9.Name = "label9"; this.label9.Size = new System.Drawing.Size(64, 13); this.label9.TabIndex = 16; this.label9.Text = "Private key:"; this.label9.TextAlign = System.Drawing.ContentAlignment.TopRight; // // label10 // this.label10.Location = new System.Drawing.Point(16, 240); this.label10.Name = "label10"; this.label10.Size = new System.Drawing.Size(72, 13); this.label10.TabIndex = 15; this.label10.Text = "Public key:"; this.label10.TextAlign = System.Drawing.ContentAlignment.TopRight; // // lblPhiNvalue // this.lblPhiNvalue.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); this.lblPhiNvalue.Location = new System.Drawing.Point(232, 24); this.lblPhiNvalue.Name = "lblPhiNvalue"; this.lblPhiNvalue.Size = new System.Drawing.Size(56, 13); this.lblPhiNvalue.TabIndex = 14; // // lblNvalue // this.lblNvalue.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((System.Byte)(0))); this.lblNvalue.Location = new System.Drawing.Point(72, 24); this.lblNvalue.Name = "lblNvalue"; this.lblNvalue.Size = new System.Drawing.Size(40, 13); this.lblNvalue.TabIndex = 13; // // lblPhiN // this.lblPhiN.Location = new System.Drawing.Point(120, 24); this.lblPhiN.Name = "lblPhiN"; this.lblPhiN.Size = new System.Drawing.Size(104, 13); this.lblPhiN.TabIndex = 12; this.lblPhiN.Text = "Φ(n) [=(p-1)*(q-1)]:"; this.lblPhiN.TextAlign = System.Drawing.ContentAlignment.TopRight; // // label1 // this.label1.Location = new System.Drawing.Point(16, 24); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(48, 13); this.label1.TabIndex = 10; this.label1.Text = "n [=p*q]:"; this.label1.TextAlign = System.Drawing.ContentAlignment.TopRight; // // richTxtKeyGenProgress // this.richTxtKeyGenProgress.Enabled = false; this.richTxtKeyGenProgress.Location = new System.Drawing.Point(8, 48); this.richTxtKeyGenProgress.Name = "richTxtKeyGenProgress"; this.richTxtKeyGenProgress.Size = new System.Drawing.Size(288, 184); this.richTxtKeyGenProgress.TabIndex = 4; this.richTxtKeyGenProgress.Text = ""; // // groupBox2 // this.groupBox2.Controls.Add(this.cboPrime2); this.groupBox2.Controls.Add(this.cboPrime1); this.groupBox2.Controls.Add(this.cmdGenerateKey); this.groupBox2.Controls.Add(this.label4); this.groupBox2.Controls.Add(this.label3); this.groupBox2.Location = new System.Drawing.Point(8, 8); this.groupBox2.Name = "groupBox2"; this.groupBox2.Size = new System.Drawing.Size(304, 120); this.groupBox2.TabIndex = 8; this.groupBox2.TabStop = false; this.groupBox2.Text = "Step 1 - Enter two prime numbers"; // // cboPrime2 // this.cboPrime2.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.cboPrime2.Location = new System.Drawing.Point(128, 56); this.cboPrime2.Name = "cboPrime2"; this.cboPrime2.Size = new System.Drawing.Size(64, 21); this.cboPrime2.TabIndex = 2; // // cboPrime1 // this.cboPrime1.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; this.cboPrime1.Location = new System.Drawing.Point(128, 24); this.cboPrime1.Name = "cboPrime1"; this.cboPrime1.Size = new System.Drawing.Size(64, 21); this.cboPrime1.TabIndex = 1; // // cmdGenerateKey // this.cmdGenerateKey.Location = new System.Drawing.Point(72, 88); this.cmdGenerateKey.Name = "cmdGenerateKey"; this.cmdGenerateKey.Size = new System.Drawing.Size(128, 24); this.cmdGenerateKey.TabIndex = 3; this.cmdGenerateKey.Text = "Generate Key"; this.cmdGenerateKey.Click += new System.EventHandler(this.cmdGenerateKey_Click); // // label4 // this.label4.Location = new System.Drawing.Point(32, 64); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(96, 13); this.label4.TabIndex = 9; this.label4.Text = "Second prime (q):"; // // label3 // this.label3.Location = new System.Drawing.Point(32, 32); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(80, 13); this.label3.TabIndex = 8; this.label3.Text = "First prime (p):"; // // groupBox3 // this.groupBox3.Controls.Add(this.lblEncryptionExponent); this.groupBox3.Controls.Add(this.lblMsgMod); this.groupBox3.Controls.Add(this.lblMsgNum); this.groupBox3.Controls.Add(this.label5); this.groupBox3.Controls.Add(this.txtEncryptedMsg); this.groupBox3.Controls.Add(this.cmdEncryptPrivate); this.groupBox3.Controls.Add(this.cmdEncryptPublic); this.groupBox3.Controls.Add(this.label6); this.groupBox3.Controls.Add(this.txtMsgToEncrypt); this.groupBox3.Location = new System.Drawing.Point(344, 8); this.groupBox3.Name = "groupBox3"; this.groupBox3.Size = new System.Drawing.Size(296, 120); this.groupBox3.TabIndex = 9; this.groupBox3.TabStop = false; this.groupBox3.Text = "Step 3 - Encrypt a message"; // // lblEncryptionExponent // this.lblEncryptionExponent.Location = new System.Drawing.Point(96, 90); this.lblEncryptionExponent.Name = "lblEncryptionExponent"; this.lblEncryptionExponent.Size = new System.Drawing.Size(32, 13); this.lblEncryptionExponent.TabIndex = 14; // // lblMsgMod // this.lblMsgMod.Location = new System.Drawing.Point(128, 96); this.lblMsgMod.Name = "lblMsgMod"; this.lblMsgMod.Size = new System.Drawing.Size(72, 13); this.lblMsgMod.TabIndex = 13; // // lblMsgNum // this.lblMsgNum.Location = new System.Drawing.Point(56, 96); this.lblMsgNum.Name = "lblMsgNum"; this.lblMsgNum.Size = new System.Drawing.Size(40, 13); this.lblMsgNum.TabIndex = 12; this.lblMsgNum.TextAlign = System.Drawing.ContentAlignment.TopRight; // // label5 // this.label5.Location = new System.Drawing.Point(16, 96); this.label5.Name = "label5"; this.label5.Size = new System.Drawing.Size(40, 13); this.label5.TabIndex = 11; this.label5.Text = "Result:"; // // txtEncryptedMsg // this.txtEncryptedMsg.Location = new System.Drawing.Point(208, 93); this.txtEncryptedMsg.Name = "txtEncryptedMsg"; this.txtEncryptedMsg.Size = new System.Drawing.Size(48, 20); this.txtEncryptedMsg.TabIndex = 10; this.txtEncryptedMsg.Text = ""; // // cmdEncryptPrivate // this.cmdEncryptPrivate.Enabled = false; this.cmdEncryptPrivate.Location = new System.Drawing.Point(152, 56); this.cmdEncryptPrivate.Name = "cmdEncryptPrivate"; this.cmdEncryptPrivate.Size = new System.Drawing.Size(136, 24); this.cmdEncryptPrivate.TabIndex = 9; this.cmdEncryptPrivate.Text = "Encrypt with Private Key"; this.cmdEncryptPrivate.Click += new System.EventHandler(this.cmdEncryptPrivate_Click); // // cmdEncryptPublic // this.cmdEncryptPublic.Enabled = false; this.cmdEncryptPublic.Location = new System.Drawing.Point(8, 56); this.cmdEncryptPublic.Name = "cmdEncryptPublic"; this.cmdEncryptPublic.Size = new System.Drawing.Size(136, 24); this.cmdEncryptPublic.TabIndex = 3; this.cmdEncryptPublic.Text = "Encrypt with Public Key"; this.cmdEncryptPublic.Click += new System.EventHandler(this.cmdEncryptPublic_Click); // // label6 // this.label6.Location = new System.Drawing.Point(32, 32); this.label6.Name = "label6"; this.label6.Size = new System.Drawing.Size(80, 13); this.label6.TabIndex = 8; this.label6.Text = "Message:"; // // txtMsgToEncrypt // this.txtMsgToEncrypt.Location = new System.Drawing.Point(136, 24); this.txtMsgToEncrypt.Name = "txtMsgToEncrypt"; this.txtMsgToEncrypt.Size = new System.Drawing.Size(48, 20); this.txtMsgToEncrypt.TabIndex = 1; this.txtMsgToEncrypt.Text = ""; // // groupBox4 // this.groupBox4.Controls.Add(this.label7); this.groupBox4.Controls.Add(this.label2); this.groupBox4.Controls.Add(this.txtPrivateCipher); this.groupBox4.Controls.Add(this.txtPublicCipher); this.groupBox4.Location = new System.Drawing.Point(344, 144); this.groupBox4.Name = "groupBox4"; this.groupBox4.Size = new System.Drawing.Size(296, 296); this.groupBox4.TabIndex = 10; this.groupBox4.TabStop = false; this.groupBox4.Text = "Cipher list"; // // label7 // this.label7.Location = new System.Drawing.Point(152, 24); this.label7.Name = "label7"; this.label7.Size = new System.Drawing.Size(80, 13); this.label7.TabIndex = 12; this.label7.Text = "Private:"; // // label2 // this.label2.Location = new System.Drawing.Point(16, 24); this.label2.Name = "label2"; this.label2.Size = new System.Drawing.Size(80, 13); this.label2.TabIndex = 11; this.label2.Text = "Public:"; // // txtPrivateCipher // this.txtPrivateCipher.Location = new System.Drawing.Point(152, 40); this.txtPrivateCipher.Multiline = true; this.txtPrivateCipher.Name = "txtPrivateCipher"; this.txtPrivateCipher.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.txtPrivateCipher.Size = new System.Drawing.Size(120, 248); this.txtPrivateCipher.TabIndex = 10; this.txtPrivateCipher.Text = ""; // // txtPublicCipher // this.txtPublicCipher.Location = new System.Drawing.Point(16, 40); this.txtPublicCipher.MaxLength = 3276700; this.txtPublicCipher.Multiline = true; this.txtPublicCipher.Name = "txtPublicCipher"; this.txtPublicCipher.ScrollBars = System.Windows.Forms.ScrollBars.Vertical; this.txtPublicCipher.Size = new System.Drawing.Size(120, 248); this.txtPublicCipher.TabIndex = 1; this.txtPublicCipher.Text = ""; // // frmMain // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(656, 446); this.Controls.Add(this.groupBox4); this.Controls.Add(this.groupBox3); this.Controls.Add(this.groupBox2); this.Controls.Add(this.groupBox1); this.MaximizeBox = false; this.MinimizeBox = false; this.Name = "frmMain"; this.Text = "RSA Encryption Demo"; this.Load += new System.EventHandler(this.Form1_Load); this.groupBox1.ResumeLayout(false); this.groupBox2.ResumeLayout(false); this.groupBox3.ResumeLayout(false); this.groupBox4.ResumeLayout(false); this.ResumeLayout(false); } #endregion /// /// The main entry point for the application. /// [STAThread] static void Main() { Application.Run(new frmMain()); } private void cmdGenerateKey_Click(object sender, System.EventArgs e) { try { rsaEncryptor.P = Convert.ToUInt32(cboPrime1.Items[cboPrime1.SelectedIndex]); } catch(Exception theException) { MessageBox.Show(this, theException.Message); return; } try { rsaEncryptor.Q = Convert.ToUInt32(cboPrime2.Items[cboPrime2.SelectedIndex]); } catch(Exception theException) { MessageBox.Show(this, theException.Message); return; } if(rsaEncryptor.P == rsaEncryptor.Q) MessageBox.Show(this, "Your key won't be very secure if n is a perfect square! Choose a different number for your second prime.","Invalid selection",MessageBoxButtons.OK,MessageBoxIcon.Exclamation); richTxtKeyGenProgress.Enabled = true; richTxtKeyGenProgress.Clear(); rsaEncryptor.GenerateKeyPair(new RSAEncryptor.ProgressWriteLineDelegate(ProgressWriteLine)); lblNvalue.Text = rsaEncryptor.N.ToString(); lblPhiNvalue.Text = rsaEncryptor.PhiN.ToString(); lblPublicKey.Text = String.Format("( {0}, {1} )", rsaEncryptor.N, rsaEncryptor.E); lblPrivateKey.Text = String.Format("( {0}, {1} )", rsaEncryptor.N, rsaEncryptor.D); cmdEncryptPrivate.Enabled = true; cmdEncryptPublic.Enabled = true; FillCipherTable(txtPublicCipher, new EncryptDelegate(rsaEncryptor.EncryptWithPublicKey)); FillCipherTable(txtPrivateCipher, new EncryptDelegate(rsaEncryptor.EncryptWithPrivateKey)); } private void Form1_Load(object sender, System.EventArgs e) { FillWithPrimes(cboPrime1, RSAEncryptor.MaxAllowedPrime); FillWithPrimes(cboPrime2, RSAEncryptor.MaxAllowedPrime); } private void cmdEncryptPublic_Click(object sender, System.EventArgs e) { ValidateAndEncrypt(txtMsgToEncrypt.Text, rsaEncryptor.E, rsaEncryptor.N, new EncryptDelegate(rsaEncryptor.EncryptWithPublicKey)); } private void cmdEncryptPrivate_Click(object sender, System.EventArgs e) { ValidateAndEncrypt(txtMsgToEncrypt.Text, rsaEncryptor.D, rsaEncryptor.N, new EncryptDelegate(rsaEncryptor.EncryptWithPrivateKey)); } private void ShowEncryptionProcess(string msgNumber, uint encryptionExponent, uint N) { //Display the formula msgNumber^encryptionExponent mod N to show how the encrypted value // is derived lblMsgNum.Text = txtMsgToEncrypt.Text; lblEncryptionExponent.Text = encryptionExponent.ToString(); lblMsgMod.Text = "mod " + N.ToString() + " ="; //resize the labels to fit their new contents, then reposition them to close the gaps AutoSizeControl(lblMsgNum, 1); AutoSizeControl(lblEncryptionExponent, 1); AutoSizeControl(lblMsgMod, 1); lblEncryptionExponent.Left = lblMsgNum.Left + lblMsgNum.Width - 1; lblMsgMod.Left = lblEncryptionExponent.Left + lblEncryptionExponent.Width - 1; } private void ValidateAndEncrypt(string messageAsString, uint encryptionExponent, uint N, EncryptDelegate encryptorFunction) { uint theMessage; try { theMessage = Convert.ToUInt32(messageAsString); } catch(Exception) { MessageBox.Show(this, "Please enter the integer to be encrypted"); return; } uint encryptedMsg; try { rsaEncryptor.ValidateMessage(theMessage); } catch(Exception theException) { MessageBox.Show(this, theException.Message); return; } ShowEncryptionProcess(messageAsString, encryptionExponent, N); //Show them how we get the answer encryptedMsg = encryptorFunction(theMessage); //Go and get the answer txtEncryptedMsg.Text = encryptedMsg.ToString(); } private int ProgressWriteLine(string theMessage, Color textColour) { richTxtKeyGenProgress.SelectionColor = textColour; richTxtKeyGenProgress.AppendText(theMessage + "\n"); return 0; } private void FillWithPrimes(ComboBox theList, uint maxPrime) { bool[] isPrime = new bool[maxPrime + 1]; uint i, j; for(i=2; i<=maxPrime; i++) isPrime[i] = true; for(i=2; i<=maxPrime; i++) if(isPrime[i]) { if(i >= 7) theList.Items.Add(i.ToString()); for(j=i*2; j<=maxPrime; j+=i) isPrime[j] = false; } } private void FillCipherTable(TextBox theCipherList, EncryptDelegate encryptorFunction) { const int maxStringLen = 32767; uint i, p = rsaEncryptor.P, q = rsaEncryptor.Q; System.Text.StringBuilder listText = new System.Text.StringBuilder(maxStringLen, maxStringLen+200); theCipherList.Clear(); for(i=2; i < rsaEncryptor.N-1 && listText.Length < maxStringLen - 4; i++) if((i % p != 0) && (i % q != 0)) listText.Append(i.ToString() + " -> " + encryptorFunction(i).ToString() + System.Environment.NewLine); if(listText.Length >= maxStringLen-4) listText = listText.Remove(maxStringLen-4, listText.Length-(maxStringLen-4)).Append("..."); theCipherList.Text = listText.ToString(); } private void AutoSizeControl(Control control, int textPadding) { // Create a Graphics object for the Control Graphics g = control.CreateGraphics(); // Get the Size needed to accommodate the control's formatted Text Size preferredSize = g.MeasureString(control.Text, control.Font).ToSize(); // Pad the text and resize the control control.ClientSize = new Size( preferredSize.Width + textPadding, preferredSize.Height + textPadding ); g.Dispose(); } } }