Introduction
This tutorial will show how to achieve digital signing in .NET framework 1.1 using System.Security.Cryptography
class.
Digital Signatures
Digital signatures are used to achieve Authentication, Non-repudiation, and Authorization.
Authentication is a technique by which a process verifies that its communication partner is who it is supposed to be and not an intruder, and deals with the question of whether or not you are actually communicating with a specific process. Non-repudiation is a mechanism which provides a way to prevent the author from falsely claming that he or she isn’t the author. Authorization is concerned with what that process is permitted to do.
Let’s say Alice and Bob decide to sign digitally, a contract between them which is highly confidential. Here’s the protocol they can use to digitally sign the contact:
- Alice and Bob each get a copy of the file containing the contract.
- Bob prepares a message and computes the hash of it and encrypts the hash value with his private key called Signature Block.
- Then he encrypts the message with Alice's Public Key.
- He sends two files to Alice: encrypted hash and message.
- Upon receiving, Alice decrypts hash value with Bob's public key.
- Then she decrypts message with her private key.
- She then computes the hash of this message.
- Finally, she compares the two hash values. If they are same, the signature is “good”, otherwise bad.
If Bob wants to cheat Alice, he has a big problem. Since Alice knows his RSA public key because she made it well private. Therefore, the entire encrypted message serves as a “digital signature”. So the message is authenticated both in terms of source and in terms of data integrity.
What is Hash?
Hashes are known as One way functions, that is their mathematical property of non reversibility. Further more, they are also known as Message digest functions because message is reduced or digest to a fixed-length number that is smaller than the message. Hashes are the actual sum of ASCII values of all letters of message, and no matter how long the input data is, the hash is always the same number of bits.
.NET provides us with following Hash algorithms:
MD5CryptoServiceProvider
(Message digest 5)
SHA1CryptoServiceProvider
(Secure hash algorithm with key size 160-bits)
SHA256Managed
(Secure hash algorithm with key size 256-bits)
SHA384Managed
(Secure hash algorithm with key size 384-bits)
SHA512Managed
(Secure hash algorithm with key size 512-bits)
HMACSHA1
(Hash-based Message Authentication Code using the SHA1 hash function)
MACTripleDES
(Message Authentication Code using the TripleDES for the input data)
Also, .NET provides us with following Digital Signature Algorithms:
DSACryptoServiceProvider
(Digital Signature Algorithm)
RSACryptoServiceProvider
(Rivest, Shamir and Adlemen)
We will use RSA algorithm since it can be used not only for digital signatures, but for also encryption and decryption. It is tiny but a bit faster than DSA algorithm which can only be used for digital signing, issued by NIST (National Institute of Standards and Technology).
Let us implement this concept in .NET framework 1.1.
Implementation
Start a new Windows Application project and assign a name “digital signing” and do the following”:
Add a new form names FORM1
with controls on it as: (Interface should be like the form as shown below: for more clarity, download code)
GroupBox
named Bob (sender) with following controls on it:
Label
control, three TextBox
es for output.
- A
Button
named Button1
with Text
property as “&Encrypt Plaintext using Receiver's (Alice) Public Key”.
- A
Button
named Button1
with Text
property as “Generate &Signature Block using Sender's (Bob) Private Key”.
GroupBox
named Alice (receiver) with following controls on it:
- A
TextBox
control for output.
- A
Button
named Button3
with Text
property as “Verify Signature block using sender's (Bob) Public Key”.
- A
Button
named Button4
with Text
property as “&Decrypt plaintext using receiver (Alice) private key”.
- A
Button
named Button5
which is the Exit button.
Form1
That’s all for the interface. Now, it's time for coding. Let’s start it:
Code listing for “Form1”:
Imports System.Text
Public Class Form1 ‘Main interface form
Inherits System.Windows.Forms.Form
Private Sub Button3_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button3.Click
If myReceiver.VerifyHash(mySender.PublicParameters, _
encrypted, signature) Then
MsgBox("Signature Valid", MsgBoxStyle.Information)
Button4.Enabled = True
Else
MsgBox("Invalid Signature", MsgBoxStyle.Exclamation)
Button4.Enabled = False
End If
End Sub
Private Sub Button1_Click_1(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button1.Click
If Me.TxtPlainText.Text = "" Then
MsgBox("Please enter a string to sign", MsgBoxStyle.Information)
Exit Sub
End If
toEncrypt = enc.GetBytes(TxtPlainText.Text)
encrypted = mySender.EncryptData(myReceiver.PublicParameters, toEncrypt)
TextBox1.Text = Convert.ToBase64String(encrypted)
Me.Button2.Enabled = True
End Sub
Private Sub Button2_Click_1(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button2.Click
signature = mySender.HashAndSign(encrypted)
TextBox2.Text = Convert.ToBase64String(encrypted)
Me.Button3.Enabled = True
End Sub
Private Sub Button4_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button4.Click
TextBox3.Text = myReceiver.DecryptData(encrypted)
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
Button2.Enabled = False
Button3.Enabled = False
Button4.Enabled = False
End Sub
Private Sub Button5_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles Button5.Click
myReceiver = Nothing
mySender = Nothing
End
End Sub
End Class
Now, do the following:
- Add a
Class
to project and name it “Bob” which plays a role of sender.
- Add another
Class
and name it “Alice” which plays a role of receiver.
- Add a
Module
named “Global” for global declarations of variables.
Code listing for Class “Bob”:
Imports System.Security.Cryptography
Imports System.Text
Public Class Bob
‘Bob Sender is who want to exchange and prepares a encrypted message
Private rsaPubParams As RSAParameters
Private rsaPrivateParams As RSAParameters
Public Sub New()
Dim rsaCSP As New RSACryptoServiceProvider
rsaPrivateParams = rsaCSP.ExportParameters(True)
rsaPubParams = rsaCSP.ExportParameters(False)
End Sub
Public ReadOnly Property PublicParameters() As RSAParameters
Get
Return rsaPubParams
End Get
End Property
Public Function HashAndSign(ByVal encrypted() As Byte) As Byte()
Dim rsaCSP As New RSACryptoServiceProvider
Dim hash As New SHA1Managed
Dim hashedData() As Byte
rsaCSP.ImportParameters(rsaPrivateParams)
hashedData = hash.ComputeHash(encrypted)
Return rsaCSP.SignHash(hashedData, CryptoConfig.MapNameToOID("SHA1"))
End Function
Public Function EncryptData(ByVal rsaParams As RSAParameters, _
ByVal toEncrypt() As Byte) As Byte()
Dim rsaCSP As New RSACryptoServiceProvider
rsaCSP.ImportParameters(rsaParams)
Return rsaCSP.Encrypt(toEncrypt, False)
End Function
End Class
Code listing for Class “Alice”:
Imports System.Security.Cryptography
Imports System.Text
Public Class Alice
Private rsaPubParams As RSAParameters
Private rsaPrivateParams As RSAParameters
Public Sub New()
Dim rsaCSP As New RSACryptoServiceProvider
rsaPrivateParams = rsaCSP.ExportParameters(True)
rsaPubParams = rsaCSP.ExportParameters(False)
End Sub
Public ReadOnly Property PublicParameters() As RSAParameters
Get
Return rsaPubParams
End Get
End Property
Public Function VerifyHash(ByVal rsaParams As RSAParameters, _
ByVal signedData() As Byte, _
ByVal signature() As Byte) As Boolean
Dim rsaCSP As New RSACryptoServiceProvider
Dim hash As New SHA1Managed
Dim hashedData() As Byte
rsaCSP.ImportParameters(rsaParams)
hashedData = hash.ComputeHash(signedData)
Return rsaCSP.VerifyHash(hashedData, _
CryptoConfig.MapNameToOID("SHA1"), signature)
End Function
Public Function DecryptData(ByVal encrypted() As Byte) As String
Dim fromEncrypt() As Byte
Dim roundTrip As String
Dim rsaCSP As New RSACryptoServiceProvider
rsaCSP.ImportParameters(rsaPrivateParams)
fromEncrypt = rsaCSP.Decrypt(encrypted, False)
roundTrip = enc.GetString(fromEncrypt)
Return roundTrip
End Function
End Class ’ Alice
Code listing for Module “Global”:
Imports System.Text
Module Global
Public toEncrypt() As Byte
Public encrypted() As Byte
Public signature() As Byte
Public mySender As New Bob
Public myReceiver As New Alice
Public enc As New UTF8Encoding
End Module
Running the Sample
In the Visual Studio .NET IDE, press the <F5> key. When you are done, click Exit button to close the program.
Conclusion
I am always willing to help, so if you have any questions, suggestions, about my article and code, then feel free to email me. You can also reach me on MSN messenger with screen name “Maxima”.
I am software engineer and working from last four years in the information technology field. I love to do intresting tasks. I love to see diffrent places and listening muzik.