Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Secret Key Encryption in .NET

0.00/5 (No votes)
28 Nov 2004 1  
Implemnts secret key encryption.

Symmetric Cryptography (Secret Key Encryption)

Introduction

This tutorial will show how to implement Symmetric Cryptography / Secret Key Encryption in .NET Framework 1.1 through System.Security.Cryptography.

Background

Cryptography is a study of how to scramble data so that:

  1. Anyone who steals it will be unable to scramble it.
  2. Your intended recipients will be able to unscramble it with ease.

In this respect, it also covers multitude of sins in the sense that the nosy people can�t read, or worse yet, modify messages intended for other recipients.

Important terms in Cryptography

The transformation of actual message into coded form (scrambling) is known as Encryption or Enciphering and reverse of this (unscrambling) is known as Decryption or Deciphering. The message to be encrypted is known as Plaintext or Message text. The output of encryption Process is known as Cipher text or Cryptogram. The person who sends a message text is known as Sender and person who intends to receive the message text is known as Receiver. Sending a message in plaintext rather in cipher text to receiver is termed as sending in the Cleartext. The person who intends to hack/steal the cipher text between sender and receiver is known as Intruder or Attacker. The set of data transformation used to do encryption or workhouse of cryptography is known as Cryptographic Algorithm or simply a Cipher, normally the transformation is parameterized by one or more Keys. The art of breaking ciphers is known as Cryptanalysis and the art of developing and breaking cipher is collectively known as Cryptology.

Types of Cryptography

There are two types of Encryption techniques.

  • Symmetric or Conventional encryption
  • Asymmetric or Public key encryption

We will only discuss about Symmetric cryptography or encryption scheme.

Symmetric or Conventional encryption is one of the very old encryption schemes used in very early days and also known as Secret key encryption. In this scheme both the sender and the receiver shares the same encryption and decryption key. Obviously, this scheme uses old substitutions and permutations functions of mathematics to replace one character of plaintext with other to do encryption and decryption and that is why it given the name as symmetric encryption scheme. This scheme is shown in figure below

Sample screenshot

.NET Framework provides us with the following secret key encryption algorithms:

  • DES CryptoServiceProvider
  • RC2 CryptoServiceProvider
  • Rijndael Managed / AES (Advance Encryption Standard)
  • TripleDESCryptoServiceProvider

Block Cipher

Block Ciphers operates in a purely combinational fashion with a fixed transformation applied to a large block of plaintext on block by block basis the most common block size is eight bytes. Because each block is heavily processed, block ciphers provide a higher level of security. However, block cipher algorithms tend to execute more slowly.

Block ciphers use the same encryption algorithm for each block. Because of this, a block of plain text will always return the same cipher text when encrypted with the same key and algorithm. Because this behavior can be used to crack a cipher, cipher modes are introduced that modify the encryption process based on feedback from earlier block encryptions. The resulting encryption provides a higher level of security than a simple block encryption.

Block Cipher modes

  • Cipher Block chaining mode (CBC) introduces feedback. Before each plain text block is encrypted, it is combined with the cipher text of the previous block by a bitwise exclusive OR operation. This ensures that even if the plain text contains many identical blocks, they will each encrypt to a different cipher text block. The initialization vector is combined with the first plain text block by a bitwise exclusive OR operation before the block is encrypted.
  • The Cipher Feedback (CFB) mode processes small increments of plain text into cipher text, instead of processing an entire block at a time. This mode uses a shift register that is one block in length and is divided into sections. For example, if the block size is eight bytes, with one byte processed at a time, the shift register is divided into eight sections.
  • The Electronic Codebook (ECB) mode encrypts each block individually. This means that any blocks of plain text that are identical and are in the same message, or in a different message encrypted with the same key, will be transformed into identical cipher text blocks.

Padding

Most plain text messages do not consist of a number of bytes that completely fill blocks. Often, there are not enough bytes to fill the last block. When this happens, a padding string is added to the text. For example, if the block length is 64 bits and the last block contains only 40 bits, 24 bits of padding are added.

Padding modes

  • The PKCS #7 padding string consists of a sequence of bytes, each of which is equal to the total number of padding bytes added. For example, if 24 bits (3 bytes) of padding need to be added, the padding string is "03 03 03".
  • The Zeros padding string consists of bytes set to zero.

We will use only TripleDES and Rinjndael algorithms.

Let us implement this concept in .NET Framework 1.1. We will encrypt ad decrypt data in Radix/Base64 format for standardization. Start a new Windows Application project and assign a name �digital signing� and do the following.

Add following controls on FORM1 (Interface should like the form as shown below: for more clarity download code).

Sample screenshot

  1. Groupbox named Session Key with following controls on it:
    • A label control with text �Choose a key phrase to derive a key or leave empty to derive a random session key �.
    • A textbox control with name �TxtKeyPharse� and set its Multiline property to true.
  2. Groupbox named Padding Mode with following controls on it:
    • Radio button named Radiobutton2 with Text property �Zeros�.
    • Radio button named Radiobutton5 with Text property �PKCS7 (Default)�.
  3. Groupbox named Block Mode with following controls on it:
    • Radio button named Radiobutton1 with Text property �CBC (Cipher BlockChaining) Default mode�.
    • Radio button named Radiobutton3 with Text property �ECB (Electronic Codebook).
    • Radio button named Radiobutton4 with Text property �CFB (Cipher Feedback)�.
  4. Groupbox with the following controls on it:
    • Three textbox named txtPlaintex, TxtEncrypt, TxtDecrypt . Later two have read-only property set to true.
    • A label control named Label1 with Text property �Enter your plain text here�.
    • A button named Button1 with Text property as �Encrypt�.
    • A button named Button3 with Text property as �Decrypt�.
    • Groupbox named Cipher mode with following controls on it:
      • Radio button named Radiobutton10 with Text property �TripleDES�.
      • Radio button named Radiobutton11 with Text property �Rinjndael/AES�.
  5. A label control Label3 at bottom to display valid Key/Block sizes of cipher selected.

That�s all for interface now. It's time for coding. Let�s start it:

Code listing for �Form1�:

Imports System.Security.Cryptography
Imports System.Text
Imports System.IO
Public Class Form1
  Inherits System.Windows.Forms.Form
       
  Private Sub Form1_Load(ByVal sender As System.Object, _
       ByVal e As System.EventArgs) Handles MyBase.Load
    'set defaults inilizations for

    Me.RadioButton1.Checked = True 'padding,

    Me.RadioButton5.Checked = True 'cipher modes 

    Me.RadioButton10.Checked = True 'Algorithm

  End Sub
  Private Sub Button3_Click(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles                      
    Button3.Click
    Dim fromEncrypt() As Byte, roundtrip As String
    Dim d As String
    'check TripleDEs was selected

    If Me.RadioButton10.Checked = True Then
      ' Now decryption

      Dim decryptor As ICryptoTransform = Tdes.CreateDecryptor(MyKey, MyIV)
      'Now decrypt the previously encrypted message using the decryptor

      ' obtained in the above step.

      'use main memory for I/O.

      Dim msDecrypt As New MemoryStream(Encrypted1)
      'get CryptoStream for decrypted data

      Dim csDecrypt As New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)
      fromEncrypt = New Byte(Encrypted1.Length) {}
      'Read the data out of the crypto stream.

      csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length)
      'Convert the byte array back into a string.

      roundtrip = Encoding.ASCII.GetString(fromEncrypt)
      TxtDecrypt.Text = (roundtrip)
      'get valid TripleDES key (or Block) sizes through KeySizes enumrator

      Dim myKeySizes1 As KeySizes
      For Each myKeySizes1 In Tdes.LegalKeySizes
        With myKeySizes1
          d = "Triple DES Legal key (or Block) sizes in bits:" & vbCrLf _
             & "Max=" & .MaxSize & " bits " & _
             "(" & (.MaxSize / 8) & " bytes)" & vbCrLf _
             & "Min=" & .MinSize & " bits " & _
             "(" & (.MinSize / 8) & " bytes)" & vbCrLf _
             & "Skip=" & .SkipSize & " bits " & _
             "(" & (.SkipSize / 8) & " bytes)"
        End With
      Next
      'display them

      MsgBox(d, MsgBoxStyle.Information)
      Exit Sub
    End If ' 10

    'check TripleDEs was selected

    If Me.RadioButton11.Checked = True Then
      ' Now decryption

      Dim decryptor As ICryptoTransform = Rinjndael.CreateDecryptor(MyKey, MyIV)
      'Now decrypt the previously encrypted message using the decryptor

      ' obtained in the above step.

      'use main memory for I/O.

      Dim msDecrypt As New MemoryStream(Encrypted1)
      'get CryptoStream for decrypted data

      Dim csDecrypt As New CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)
      fromEncrypt = New Byte(Encrypted1.Length) {}
      'Read the data out of the crypto stream.

      csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length)
      'Convert the byte array back into a string.

      roundtrip = Encoding.ASCII.GetString(fromEncrypt)
      TxtDecrypt.Text = (roundtrip)
      'get valid Rinjndael key (or Block) sizes through KeySizes enumrator

      Dim myKeySizes As KeySizes
      For Each myKeySizes In Rinjndael.LegalKeySizes
        With myKeySizes
          d = "Rijndael/AES Legal key (or Block) sizes in bits:" & vbCrLf _
            & "Max=" & .MaxSize & " bits " & _
            "(" & (.MaxSize / 8) & " bytes)" & vbCrLf _
            & "Min=" & .MinSize & " bits " & _
            "(" & (.MinSize / 8) & " bytes)" & vbCrLf _
            & "Skip=" & .SkipSize & " bits " & _
            "(" & (.SkipSize / 8) & " bytes"
        End With
      Next
      'display them

      MsgBox(d, MsgBoxStyle.Information)
      Exit Sub
    End If '11

  End Sub
  Private Sub Button1_Click_1(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) Handles Button1.Click
    Dim fromEncrypt() As Byte
    Dim encrypted() As Byte
    Dim toEncrypt() As Byte
    Dim roundtrip As String
    Dim key1() As Byte
    Dim abytSalt() As Byte
    Dim abytKey() As Byte
    Dim str As String
    'first set ICryptoTransform for encryption later

    Dim encryptor As ICryptoTransform
    'RandomNumberGenerator 

    Dim rng As RandomNumberGenerator = RandomNumberGenerator.Create()
    ' check to see if no key pharse is entered

    If Me.TxtKeyPharse.Text = "" Then
      'derive random key

      Keypharse = False
    End If
    ' check to see CFB mode is selected it will not work on rinjndael

    ' convert to default

    If Me.RadioButton4.Checked = True Then
      PdMode = CipherMode.CBC
    End If
    If Keypharse Then 'if Enter key pharse in textbox

      'asssgin key to string variable

      str = Me.TxtKeyPharse.Text
      If Me.RadioButton10.Checked = True Then 'seleect TDES

        ' Tdes is used so set key and iv/salt arrays to valid size

        ReDim abytSalt(11) '12 bit Salt

        ReDim abytKey(23)  '24 bit key

        'use PasswordDeriveBytes instance to derive a key 

        Dim pdb As New PasswordDeriveBytes(str, abytSalt)
        'fill salt array to specfied size  

        rng.GetBytes(abytSalt)
        'Get the same amount of bytes as the current abytKey length 

        abytKey = pdb.GetBytes(abytKey.Length)
        'set padding mode

        Tdes.Padding = Padd
        'set cipher mode

        Tdes.Mode = PdMode
        'assign key

        Tdes.Key = abytKey
        'set key

        MyKey = Tdes.Key
        'Get  IV.

        Tdes.GenerateIV()
        'set iv

        MyIV = Tdes.IV
        'CreateEncryptor for encryption later

        encryptor = Tdes.CreateEncryptor(MyKey, MyIV)
      End If ' 10

      If Me.RadioButton11.Checked = True Then 'Rijndael is selected

        'Rinjndael is used so set key and iv/salt arrays to valid size

        ' A good rule-of-thumb is to make the salt 1/2 the length of the key.

        ReDim abytSalt(15) '16 bit salt

        ReDim abytKey(31) '32 bit key

        'use PasswordDeriveBytes instance to derive a key 

        Dim pdb As New PasswordDeriveBytes(str, abytSalt)
        'fill salt array to specfied size  

        rng.GetBytes(abytSalt)
        'Get the same amount of bytes as the current abytKey length 

        abytKey = pdb.GetBytes(abytKey.Length)
        'set padding mode

        Rinjndael.Padding = Padd
        'set cipher mode

        Rinjndael.Mode = PdMode
        ' assign key                

        Rinjndael.Key = abytKey
        'set key

        MyKey = Rinjndael.Key
        'Get  IV.

        Rinjndael.GenerateIV()
        'set IV

        MyIV = Rinjndael.IV
        'CreateEncryptor for encryption later

        encryptor = Rinjndael.CreateEncryptor(MyKey, MyIV)
      End If '11

    Else 'no Keypharse is selected then derive random  key and IV

      'see which alogrithm is seected

      If Me.RadioButton10.Checked = True Then 'TDES is used

        'set padding mode

        Tdes.Padding = Padd
        'set cipher mode

        Tdes.Mode = PdMode
        'genrate random key

        Tdes.GenerateKey()
        'genrate random iv

        Tdes.GenerateIV()
        'set values

        MyKey = Tdes.Key
        'set iv

        MyIV = Tdes.IV
        'CreateEncryptor for encryption later

        encryptor = Tdes.CreateEncryptor(MyKey, MyIV)
      End If
      If Me.RadioButton11.Checked = True Then 'Rinjndael is used

        'set padding mode

        Rinjndael.Padding = Padd
        'set cipher mode

        Rinjndael.Mode = PdMode
        'genrate random key

        Rinjndael.GenerateKey()
        'genrate random iv

        Rinjndael.GenerateIV()
        'set values

        MyKey = Rinjndael.Key
        MyIV = Rinjndael.IV
        'CreateEncryptor for encryption later

        encryptor = Rinjndael.CreateEncryptor(MyKey, MyIV)
      End If
    End If 'Keypharse

    'Encrypt the data. Whether TripleDES or Rinjndael is selected

    'use main memory for I/O.

    Dim msEncrypt As New MemoryStream
    'get CryptoStream for encrypted data

    Dim csEncrypt As New CryptoStream(msEncrypt, encryptor, _
            CryptoStreamMode.Write)
    'Convert the data to a byte array.

    toEncrypt = Encoding.ASCII.GetBytes(Me.txtPlaintex.Text)
    'Write all data to the crypto stream and flush it.

    csEncrypt.Write(toEncrypt, 0, toEncrypt.Length)
    csEncrypt.FlushFinalBlock()
    'Get encrypted array of bytes.

    encrypted = msEncrypt.ToArray()
    Encrypted1 = encrypted
    'convert to base64/Radix form

    TxtEncrypt.Text = Convert.ToBase64String(encrypted)
  End Sub
  Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, _
           ByVal e As System.EventArgs)                
    Handles RadioButton1.CheckedChanged, RadioButton3.CheckedChanged, _
           RadioButton4.CheckedChanged
    'return selected cipher mode number

    PdMode = Pmode(sender.tabindex)
  End Sub
  Private Sub RadioButton6_CheckedChanged(ByVal sender As System.Object, _
         ByVal e As System.EventArgs) 
    Handles RadioButton6.CheckedChanged, RadioButton5.CheckedChanged, _
           RadioButton2.CheckedChanged
    'return selected padding mode number

    Padd = Padding(sender.tabindex)
  End Sub
  Private Sub TxtKeyPharse_TextChanged(ByVal sender As System.Object, _
           ByVal e As System.EventArgs) Handles                          
    TxtKeyPharse.TextChanged
    'set to true if dat is enterned to know in future that key 

    'will be derived from key phrase

    Keypharse = True
  End Sub
  Private Sub Button4_Click(ByVal sender As System.Object, _
           ByVal e As System.EventArgs) Handles                 
    Button4.Click
    Help.ShowHelp(Me, Tut)
  End Sub
End Class

What all Code Does?

  • Upon whether entering text for key or not and then selecting appropriate padding, cipher and algorithm, the Encrypt button will encrypt text for you.
  • After that pressing Decrypt button will decrypt the text in Base64 format.
  • For detail explanation see code comments.

Now do the following:

  • Add a Module name �Global� for global declarations of variables.

Code listing for Module �Global�:

Imports System.Security.Cryptography
Imports System.Text
Module Global
    'creates new instance of Tripldes 

    Public Tdes As New TripleDESCryptoServiceProvider
    'creates new instance of Rinjndael

    Public Rinjndael As New RijndaelManaged
    'Stores key whether from phrase or random

    Public MyKey() As Byte
    'Stores random IV 

    Public MyIV() As Byte
    'store encrypted data

    Public Encrypted1() As Byte
    'store decrypted data

    Public Decrypted1() As Byte
    'Unicode encoding instnace

    Public MyEncoder As New UTF8Encoding
    'flag to remember that key was derived  from phrase

    Public Keypharse As Boolean = False
    'stores padding mode

    Public Padd As Int16
    'Store cipher mode

    Public PdMode As Int16
    
    'Function that will return selected Padding mode number

    Public Function Padding(ByVal mode As Int16) As Int16
        Padding = mode
        Return Padding
    End Function
    'Function that will return selected Cipher block mode number

    Public Function Pmode(ByVal mode As Int16) As Int16
        Pmode = mode
        Return Pmode
    End Function
End Module 'global

I am always willing to help, so if you have any questions, suggestions about my article, feel free to email me. You can also reach me on MSN messenger with screen name �Maxima�.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here