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;
}
}
C For Windows Desktop: C -Elliptic Curve Digital Signatures >>>>> Download Now
ReplyDelete>>>>> 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