Wednesday 21 February 2018

C# -Elliptic Curve Digital Signatures

So the prior post showed an example of using RSA asymmetric hashing and signing to implement a digital signature but the latest trend is to use Elliptic Curve Digital Signature Algorithm (ECDSA) because they use shorter keys. So I have given another chunk of source code to demonstrate this.

Also in this code base I am using SHA256 for the hash and I am hashing twice just like BitCoin.

So for the Form1.cs code use this


// Based on code by Adnan Samuel, Code Project,
// https://www.codeproject.com/script/Membership/View.aspx?mid=1307566

using System;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        // instance of class ServerSide (Bob)
        public ServerSide mySender; // = new ServerSide();

        // instance of class ClientSide (Alice)
        public ClientSide myReceiver = new ClientSide();

        public Form1()
        {
            InitializeComponent();
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            myReceiver = null;
            mySender = null;
            Application.Exit();
        }

        private void btn2_GenerateSignatureBlock_Click(object sender, EventArgs e)
        {

            int keySize = Int32.Parse(maskTxtKeySize.Text);
            mySender = new ServerSide(keySize);

            //* Hash and Sign only
            Byte[] nonencryptedSignature;
            nonencryptedSignature = mySender.HashAndSign(Encoding.UTF8.GetBytes(
                                                              txtPlainText.Text));

            txtNonEncryptedSignatureBlock.Text = Convert.ToBase64String(
                                                           nonencryptedSignature);

            //C# 6 grpPublicKey.Text = $"Public Key ({mySender.KeySize} bit)";
            grpPublicKey.Text = "Public Key (" + mySender.KeySize + " bit)";
            txtPublicKey.Text = mySender.ToString2();

            btn3b_VerifySignature.Enabled = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            btn3b_VerifySignature.Enabled = false;

            // build the link
            LinkLabel.Link link = new LinkLabel.Link();
            link.LinkData =
            "https://www.codeproject.com/Articles/8868/Implementing-Digital-Signing-in-NET";
            linkLabel1.Links.Add(link);
        }

        private void btn3b_VerifySignature_Click(object sender, EventArgs e)
        {
            Byte[] signature;
            signature = Convert.FromBase64String(
                                              txtNonEncryptedSignatureBlock.Text);

            Byte[] plainTextAsBytes;
            plainTextAsBytes = Encoding.UTF8.GetBytes(txtPlainText.Text);

            if (myReceiver.VerifyHash(txtPublicKey.Text, plainTextAsBytes,
                                                                       signature))
            {
                txtPlainTextReceiver.Text = txtPlainText.Text;
                MessageBox.Show("Signature Valid", "Verification Results",
                                MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {
                txtPlainTextReceiver.Text = "";
                MessageBox.Show("Invalid Signature", "Verification Results",
                                MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
            }
        }

        private void linkLabel1_LinkClicked(object sender,
                                                  LinkLabelLinkClickedEventArgs e)
        {
            // Send the URL to the operating system.
            Process.Start(e.Link.LinkData as string);
        }

        private void maskTxtKeySize_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                // enter key has been pressed
                btn2_GenerateSignatureBlock_Click(sender, e);
            }
        }
    }

    public class ServerSide //Bob
    {
        //========================================================================
        //  Bob  is the Server who will hash and sign license documents
        //========================================================================
        private ECDsaCng ecDsaCngserverSide = null;

        private ServerSide()
        {
            ecDsaCngserverSide = new ECDsaCng();
        }

        public ServerSide(int keySize)
        {
            try
            {
                ecDsaCngserverSide = new ECDsaCng(keySize);
            }
            catch (Exception ex)
            {
                
                if (ex.HResult == -2146233296)
                {
                    MessageBox.Show("Key size should be 256, 384 or 521", 
                           "Key initialisation error", 
                           MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else
                {
                    //C# 6.0 string errMsg = $"Unhandled error {ex.HResult} : {ex.Message} ";
                    string errMsg = "Unhandled error " + "ex.HResult" + " : " + ex.Message + " ";
                    MessageBox.Show(errMsg, "Key initialisation error", 
                           MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }

        }

        public string PublicParametersAsXml
        {
            get
            {
                return ecDsaCngserverSide.ToXmlString(false);
            }
        }

        public int KeySize
        {
            get
            {
                return ecDsaCngserverSide.KeySize;
            }
        }

        public byte[] HashAndSign(byte[] input)
        {


            // a byte array to store hash value
            byte[] hashedData = null;

            byte[] results = null;

            // create new instance of SHA256 hash algorithm to compute hash
            HashAlgorithm hashAlgo = new SHA256Managed();

            // compute hash with algorithm 
            hashedData = hashAlgo.ComputeHash(input);

            // hasgh again, like BitCoin
            hashedData = hashAlgo.ComputeHash(hashedData);

            // sign Data using private key 
            results = ecDsaCngserverSide.SignHash(hashedData);

            return results;
        }

        public string ToString2()
        {
            return ecDsaCngserverSide.ToXmlString(ECKeyXmlFormat.Rfc4050);
        }
    }

    public class ClientSide
    {
        //'========================================================================
        //' Alice is Client who will import Public Key and verify signed hash
        //'========================================================================

        public Boolean VerifyHash(String ecDsaCngParamsXml, byte[] signedData,
                                                                  byte[] signature)
        {
            // create new instance 
            ECDsaCng client = new ECDsaCng();

            bool bOk = true;
            try
            {
                client.FromXmlString(ecDsaCngParamsXml, ECKeyXmlFormat.Rfc4050);
            }
            catch (Exception ex)
            {
                bOk = false;
                if (ex.HResult == -2146893785)
                {
                    MessageBox.Show("Key has been tampered with", 
                               "Key initialisation error", 
                               MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
                else
                {
                    //C# 6.0 string errMsg = $"Unhandled error {ex.HResult} : {ex.Message} ";
                    string errMsg = "Unhandled error " + "ex.HResult" + " : " + ex.Message + " ";

                    MessageBox.Show(errMsg, "Key initialisation error", 
                                 MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }

            // a byte array to store hash value
            byte[] hashedData = null;

            HashAlgorithm hashAlgo = new SHA256Managed();

            if (bOk && hashAlgo != null)
            {
                // compute hash with algorithm specified 
                hashedData = hashAlgo.ComputeHash(signedData);

                // hash it twice
                hashedData = hashAlgo.ComputeHash(hashedData);

                return client.VerifyHash(hashedData, signature);
            }
            else
            {
                return false;
            }
        }
    }
}

and ther Form1.Designer.cs code is here

namespace WindowsFormsApp1
{
    partial class Form1
    {
        /// 
        /// Required designer variable.
        /// 
        private System.ComponentModel.IContainer components = null;


        /// 
        /// Clean up any resources being used.
        /// 
        /// true if managed resources should be disposed; 
        /// otherwise, false.
        protected override void Dispose(bool disposing)
        {
            if (disposing && (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.grpServer = new System.Windows.Forms.GroupBox();
            this.grpMetrics = new System.Windows.Forms.GroupBox();
            this.maskTxtKeySize = new System.Windows.Forms.MaskedTextBox();
            this.lblKeySize = new System.Windows.Forms.Label();
            this.txtNonEncryptedSignatureBlock = new System.Windows.Forms.TextBox();
            this.btn2_GenerateSignatureBlock = new System.Windows.Forms.Button();
            this.txtPlainText = new System.Windows.Forms.TextBox();
            this.lblEnterPlaintextForSigning = new System.Windows.Forms.Label();
            this.lblTitle = new System.Windows.Forms.Label();
            this.grpClientSide = new System.Windows.Forms.GroupBox();
            this.txtPlainTextReceiver = new System.Windows.Forms.TextBox();
            this.btn3b_VerifySignature = new System.Windows.Forms.Button();
            this.btnExit = new System.Windows.Forms.Button();
            this.grpPublicKey = new System.Windows.Forms.GroupBox();
            this.txtPublicKey = new System.Windows.Forms.TextBox();
            this.lblIOriginalAuthor = new System.Windows.Forms.Label();
            this.linkLabel1 = new System.Windows.Forms.LinkLabel();
            this.grpServer.SuspendLayout();
            this.grpMetrics.SuspendLayout();
            this.grpClientSide.SuspendLayout();
            this.grpPublicKey.SuspendLayout();
            this.SuspendLayout();
            // 
            // grpServer
            // 
            this.grpServer.BackColor = System.Drawing.SystemColors.Control;
            this.grpServer.Controls.Add(this.grpMetrics);
            this.grpServer.Controls.Add(this.txtNonEncryptedSignatureBlock);
            this.grpServer.Controls.Add(this.btn2_GenerateSignatureBlock);
            this.grpServer.Controls.Add(this.txtPlainText);
            this.grpServer.Controls.Add(this.lblEnterPlaintextForSigning);
            this.grpServer.ForeColor = System.Drawing.SystemColors.WindowText;
            this.grpServer.Location = new System.Drawing.Point(12, 39);
            this.grpServer.Name = "grpServer";
            this.grpServer.Size = new System.Drawing.Size(826, 184);
            this.grpServer.TabIndex = 9;
            this.grpServer.TabStop = false;
            this.grpServer.Text = "ServerSide (Bob)";
            // 
            // grpMetrics
            // 
            this.grpMetrics.Controls.Add(this.maskTxtKeySize);
            this.grpMetrics.Controls.Add(this.lblKeySize);
            this.grpMetrics.Location = new System.Drawing.Point(11, 43);
            this.grpMetrics.Name = "grpMetrics";
            this.grpMetrics.Size = new System.Drawing.Size(159, 80);
            this.grpMetrics.TabIndex = 19;
            this.grpMetrics.TabStop = false;
            this.grpMetrics.Text = "Metrics";
            // 
            // maskTxtKeySize
            // 
            this.maskTxtKeySize.BackColor = System.Drawing.SystemColors.Control;
            this.maskTxtKeySize.Location = new System.Drawing.Point(84, 13);
            this.maskTxtKeySize.Mask = "00000";
            this.maskTxtKeySize.Name = "maskTxtKeySize";
            this.maskTxtKeySize.Size = new System.Drawing.Size(61, 20);
            this.maskTxtKeySize.TabIndex = 18;
            this.maskTxtKeySize.Text = "384";
            this.maskTxtKeySize.ValidatingType = typeof(int);
            this.maskTxtKeySize.KeyDown += new System.Windows.Forms.KeyEventHandler(this.maskTxtKeySize_KeyDown);
            // 
            // lblKeySize
            // 
            this.lblKeySize.BackColor = System.Drawing.SystemColors.Control;
            this.lblKeySize.ForeColor = System.Drawing.SystemColors.WindowText;
            this.lblKeySize.Location = new System.Drawing.Point(6, 17);
            this.lblKeySize.Name = "lblKeySize";
            this.lblKeySize.Size = new System.Drawing.Size(62, 16);
            this.lblKeySize.TabIndex = 17;
            this.lblKeySize.Text = "Key Size :";
            // 
            // txtNonEncryptedSignatureBlock
            // 
            this.txtNonEncryptedSignatureBlock.BackColor = System.Drawing.SystemColors.Control;
            this.txtNonEncryptedSignatureBlock.ForeColor = System.Drawing.SystemColors.WindowText;
            this.txtNonEncryptedSignatureBlock.Location = new System.Drawing.Point(192, 130);
            this.txtNonEncryptedSignatureBlock.Multiline = true;
            this.txtNonEncryptedSignatureBlock.Name = "txtNonEncryptedSignatureBlock";
            this.txtNonEncryptedSignatureBlock.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.txtNonEncryptedSignatureBlock.Size = new System.Drawing.Size(628, 48);
            this.txtNonEncryptedSignatureBlock.TabIndex = 15;
            // 
            // btn2_GenerateSignatureBlock
            // 
            this.btn2_GenerateSignatureBlock.BackColor = System.Drawing.SystemColors.Control;
            this.btn2_GenerateSignatureBlock.ForeColor = System.Drawing.SystemColors.WindowText;
            this.btn2_GenerateSignatureBlock.Location = new System.Drawing.Point(11, 130);
            this.btn2_GenerateSignatureBlock.Name = "btn2_GenerateSignatureBlock";
            this.btn2_GenerateSignatureBlock.Size = new System.Drawing.Size(160, 48);
            this.btn2_GenerateSignatureBlock.TabIndex = 10;
            this.btn2_GenerateSignatureBlock.Text = "Generate &Signature Block using Sender\'s (Bob) Private Key";
            this.btn2_GenerateSignatureBlock.UseVisualStyleBackColor = false;
            this.btn2_GenerateSignatureBlock.Click += new System.EventHandler(this.btn2_GenerateSignatureBlock_Click);
            // 
            // txtPlainText
            // 
            this.txtPlainText.BackColor = System.Drawing.SystemColors.Control;
            this.txtPlainText.ForeColor = System.Drawing.SystemColors.WindowText;
            this.txtPlainText.Location = new System.Drawing.Point(192, 20);
            this.txtPlainText.Multiline = true;
            this.txtPlainText.Name = "txtPlainText";
            this.txtPlainText.Size = new System.Drawing.Size(628, 104);
            this.txtPlainText.TabIndex = 8;
            this.txtPlainText.Text = "Hello";
            // 
            // lblEnterPlaintextForSigning
            // 
            this.lblEnterPlaintextForSigning.BackColor = System.Drawing.SystemColors.Control;
            this.lblEnterPlaintextForSigning.ForeColor = System.Drawing.SystemColors.WindowText;
            this.lblEnterPlaintextForSigning.Location = new System.Drawing.Point(54, 23);
            this.lblEnterPlaintextForSigning.Name = "lblEnterPlaintextForSigning";
            this.lblEnterPlaintextForSigning.Size = new System.Drawing.Size(132, 20);
            this.lblEnterPlaintextForSigning.TabIndex = 7;
            this.lblEnterPlaintextForSigning.Text = "Enter Plaintext for signing :";
            // 
            // lblTitle
            // 
            this.lblTitle.BackColor = System.Drawing.SystemColors.Control;
            this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 14.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.lblTitle.ForeColor = System.Drawing.SystemColors.WindowText;
            this.lblTitle.Location = new System.Drawing.Point(107, 4);
            this.lblTitle.Name = "lblTitle";
            this.lblTitle.Size = new System.Drawing.Size(566, 32);
            this.lblTitle.TabIndex = 8;
            this.lblTitle.Text = "Cryptography - Elliptic Curve Digital Signature Algorithm (ECDSA)";
            this.lblTitle.TextAlign = System.Drawing.ContentAlignment.TopCenter;
            // 
            // grpClientSide
            // 
            this.grpClientSide.BackColor = System.Drawing.SystemColors.Control;
            this.grpClientSide.Controls.Add(this.txtPlainTextReceiver);
            this.grpClientSide.Controls.Add(this.btn3b_VerifySignature);
            this.grpClientSide.ForeColor = System.Drawing.SystemColors.WindowText;
            this.grpClientSide.Location = new System.Drawing.Point(12, 424);
            this.grpClientSide.Name = "grpClientSide";
            this.grpClientSide.Size = new System.Drawing.Size(826, 119);
            this.grpClientSide.TabIndex = 11;
            this.grpClientSide.TabStop = false;
            this.grpClientSide.Text = "ClientSide (Alice)";
            // 
            // txtPlainTextReceiver
            // 
            this.txtPlainTextReceiver.BackColor = System.Drawing.SystemColors.Control;
            this.txtPlainTextReceiver.ForeColor = System.Drawing.SystemColors.WindowText;
            this.txtPlainTextReceiver.Location = new System.Drawing.Point(167, 20);
            this.txtPlainTextReceiver.Multiline = true;
            this.txtPlainTextReceiver.Name = "txtPlainTextReceiver";
            this.txtPlainTextReceiver.ReadOnly = true;
            this.txtPlainTextReceiver.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.txtPlainTextReceiver.Size = new System.Drawing.Size(643, 93);
            this.txtPlainTextReceiver.TabIndex = 13;
            // 
            // btn3b_VerifySignature
            // 
            this.btn3b_VerifySignature.BackColor = System.Drawing.SystemColors.Control;
            this.btn3b_VerifySignature.ForeColor = System.Drawing.SystemColors.WindowText;
            this.btn3b_VerifySignature.Location = new System.Drawing.Point(6, 20);
            this.btn3b_VerifySignature.Name = "btn3b_VerifySignature";
            this.btn3b_VerifySignature.Size = new System.Drawing.Size(155, 61);
            this.btn3b_VerifySignature.TabIndex = 0;
            this.btn3b_VerifySignature.Text = "Verify Signature block using sender\'s (Bob) Public Key";
            this.btn3b_VerifySignature.UseVisualStyleBackColor = false;
            this.btn3b_VerifySignature.Click += new System.EventHandler(this.btn3b_VerifySignature_Click);
            // 
            // btnExit
            // 
            this.btnExit.BackColor = System.Drawing.SystemColors.Control;
            this.btnExit.ForeColor = System.Drawing.SystemColors.WindowText;
            this.btnExit.Location = new System.Drawing.Point(696, 549);
            this.btnExit.Name = "btnExit";
            this.btnExit.Size = new System.Drawing.Size(136, 24);
            this.btnExit.TabIndex = 10;
            this.btnExit.Text = "E&xit";
            this.btnExit.UseVisualStyleBackColor = false;
            this.btnExit.Click += new System.EventHandler(this.btnExit_Click);
            // 
            // grpPublicKey
            // 
            this.grpPublicKey.BackColor = System.Drawing.SystemColors.Control;
            this.grpPublicKey.Controls.Add(this.txtPublicKey);
            this.grpPublicKey.ForeColor = System.Drawing.SystemColors.WindowText;
            this.grpPublicKey.Location = new System.Drawing.Point(12, 243);
            this.grpPublicKey.Name = "grpPublicKey";
            this.grpPublicKey.Size = new System.Drawing.Size(826, 175);
            this.grpPublicKey.TabIndex = 12;
            this.grpPublicKey.TabStop = false;
            this.grpPublicKey.Text = "Public Key";
            // 
            // txtPublicKey
            // 
            this.txtPublicKey.BackColor = System.Drawing.SystemColors.Control;
            this.txtPublicKey.ForeColor = System.Drawing.SystemColors.WindowText;
            this.txtPublicKey.Location = new System.Drawing.Point(11, 20);
            this.txtPublicKey.Multiline = true;
            this.txtPublicKey.Name = "txtPublicKey";
            this.txtPublicKey.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.txtPublicKey.Size = new System.Drawing.Size(809, 149);
            this.txtPublicKey.TabIndex = 13;
            // 
            // lblIOriginalAuthor
            // 
            this.lblIOriginalAuthor.AutoSize = true;
            this.lblIOriginalAuthor.Location = new System.Drawing.Point(13, 559);
            this.lblIOriginalAuthor.Name = "lblIOriginalAuthor";
            this.lblIOriginalAuthor.Size = new System.Drawing.Size(165, 13);
            this.lblIOriginalAuthor.TabIndex = 13;
            this.lblIOriginalAuthor.Text = "Based on code by Adnan Samuel";
            // 
            // linkLabel1
            // 
            this.linkLabel1.AutoSize = true;
            this.linkLabel1.Location = new System.Drawing.Point(184, 559);
            this.linkLabel1.Name = "linkLabel1";
            this.linkLabel1.Size = new System.Drawing.Size(248, 13);
            this.linkLabel1.TabIndex = 14;
            this.linkLabel1.TabStop = true;
            this.linkLabel1.Text = "Code Project - Implementing Digital Signing in .NET";
            this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(857, 593);
            this.Controls.Add(this.linkLabel1);
            this.Controls.Add(this.lblIOriginalAuthor);
            this.Controls.Add(this.grpServer);
            this.Controls.Add(this.lblTitle);
            this.Controls.Add(this.grpClientSide);
            this.Controls.Add(this.btnExit);
            this.Controls.Add(this.grpPublicKey);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.grpServer.ResumeLayout(false);
            this.grpServer.PerformLayout();
            this.grpMetrics.ResumeLayout(false);
            this.grpMetrics.PerformLayout();
            this.grpClientSide.ResumeLayout(false);
            this.grpClientSide.PerformLayout();
            this.grpPublicKey.ResumeLayout(false);
            this.grpPublicKey.PerformLayout();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        internal System.Windows.Forms.GroupBox grpServer;
        internal System.Windows.Forms.TextBox txtNonEncryptedSignatureBlock;
        internal System.Windows.Forms.Button btn2_GenerateSignatureBlock;
        internal System.Windows.Forms.TextBox txtPlainText;
        internal System.Windows.Forms.Label lblEnterPlaintextForSigning;
        internal System.Windows.Forms.Label lblTitle;
        internal System.Windows.Forms.GroupBox grpClientSide;
        internal System.Windows.Forms.TextBox txtPlainTextReceiver;
        internal System.Windows.Forms.Button btn3b_VerifySignature;
        internal System.Windows.Forms.Button btnExit;
        internal System.Windows.Forms.GroupBox grpPublicKey;
        internal System.Windows.Forms.TextBox txtPublicKey;
        private System.Windows.Forms.Label lblIOriginalAuthor;
        private System.Windows.Forms.LinkLabel linkLabel1;
        private System.Windows.Forms.MaskedTextBox maskTxtKeySize;
        internal System.Windows.Forms.Label lblKeySize;
        private System.Windows.Forms.GroupBox grpMetrics;
    }
}



1 comment:

  1. C For Windows Desktop: C -Elliptic Curve Digital Signatures >>>>> Download Now

    >>>>> Download Full

    C For Windows Desktop: C -Elliptic Curve Digital Signatures >>>>> Download LINK

    >>>>> Download Now

    C For Windows Desktop: C -Elliptic Curve Digital Signatures >>>>> Download Full

    >>>>> Download LINK

    ReplyDelete