Cryptographic Libraries

  1. Overview
    1. Requirements
  2. C# .NET
    1. Sample 1
    2. Sample 2
  3. Java Cryptography Extension
    1. Overview of JCE
    2. JCE Programming
    3. Ciphers
    4. Modes
    5. Padding
  4. Exercises
    1. Worksheet

Overview

Microsoft .NET Framework is a development and execution environment that allows interoperability between programming languages, programming libraries, and the Windows platforms. The .NET Framework also provides a variety of tools to support major encryption algorithms, hashing algorithms, and digital signatures. Two programming languages, C# and Visual Basic, can be used to implement these algorithms through the .NET Cryptography classes. In this lab you will lean how to implement some basic cryptographic algorithms provided by the .NET class using C# programming.

This lab is divided into six sections. The first section is an introduction to the lab, which covers two basic C# program. The second section covers encryption under the .NET Framework. The third and fourth section covers authentication, hash algorithms, and digital signatures. The remaining two sections is the lab exercises and resources. This lab is used in Cryptography TELECOM 2820/INFSCI 2170.

Requirements

To complete this tutorial you will need a PC with Microsoft Visual C# .NET installed. Visual C# .NET is included in the Microsoft Visual Studio .NET package, which can found on the computers in the SIS lab. All examples in this lab manual were tested with Microsoft Development Environment 2003/.NET Framework version 1.1. You should also have basic knowledge of Object-Oriented Programming (OOP).


C# .NET Programming

C# is an OOP language; thus, the fundamental concepts of a class and object are similar to those of C++ or Java. The following examples should give you enough information on how to write basic C# programs. However, if you require additional resources you should read the MSDN C# Tutorial, and spend some time reading some of the other online tutorials [2]-[4] found in the references section. You can also refer to [5] and [6] for further studies if you are very serious. To understand how the .NET Framework works, you should skim through reference [7]. Furthermore, if you are looking for anything related to .NET or C# programming, the online MSDN library http://msdn2.microsoft.com/en-us/library/aa288436.aspx is very useful.

Sample Program 1

This section will introduce you to simple Microsoft Visual Studio .NET commands and instructions pertaining to programming in C#. You will also be given a simple C# program, which will be an informal introduction to the language if you are not familiar.

To launch Microsoft Visual Studio .NET open the program menu and select it. After starting Visual Studio to create a new program open the File Menu from the menu toolbar. Once inside the File Menu select New Project, which will invoke the New Project window. From the New Project window you can choose the type of project you wish to create. Select the Visual C# Project option and click Console Application for the template. Enter HelloWorld as the project name, which will also be th ename o your executable file in the HelloWorld/bin/Debug directory. Visual C# .NET will create a file Class1.cs by default. This file should be opened automatically. If you do not see the file, double-click on the file name shown in the Solution Explorer window to open it.

In the Solution Explorer window, right-click on Class1.cs and rename it to HelloClass.cs. Replace the content created by default in HelloClass.cs with the following code:

// HelloClass.cs
 
using System;
using System.Text;
 
class HelloClass {
 
public static int Main() {
 
Console.WriteLine("Hello World!\n");
 
string message_str = "Hello World!";
 
Console.WriteLine("String printout: {0}\n", message_str);
 
byte[] message_byte = Encoding.Default.GetBytes(message_str);
 
Console.WriteLine("Byte printout (in hex):\n");
 
int count = 0;
 
foreach (byte b in message_byte) {
 
Console.Write("{0:X2} ", b);
count++;
 
} // end of foreach
 
Console.WriteLine("\n\nThe number of bytes in {0} is{1}\n", message_str, count);
 
return 0;
 
} // end of main
 
} // end of class

Note:

Compile the program by choosing Build or click the Build button. Check for any error messages and if there are none run the program by choosing Debug and select Start Without Debugging. Examine the source code and output line by line to ensure complete understanding of its workings. Basically, the program prints out the classic word Hello World in different ways.

When working on this lab exercise, you may have several test programs (*.cs) contained within your project. Make sure that the program you want to compile is "included" in the project space. This can be done by right-clicking on the file name in the Solution Explorer to set the property to include In project. Similarly, the program or class that will not be compiled must be set to Exclude From Project.

Sample Program 2

To create another program, in the Solution Explorer window, right-click on the project name, which is HelloWorld, and select Add. Once inside the Add menu select Add Class, and then enter HelloClass2.cs. Replace all the content created by default in HelloClass2.cs with the following code:

// HelloClass2.cs
 
using System;
 
class HelloClass2 {
 
public byte[] Key;
 
public void InitializeKey() {
 
Key = new byte[] { 0xFC, 0x02, 0x03, 0x04,
0x05, 0x06, 0x07, 0x08,
0x09, 0x10, 0x11, 0x12,
0x13, 0x14, 0x15, 0xAA };
 
} // end of InitializeKey
 
public void SayHi() {
Console.WriteLine("Hi there!");
} // end of SayHi
> }
 
public string strY = "AES";
public int intX = 128;
 
//Program entry point.
class HelloApp {
 
public static int Main() {
 
HelloClass2 c1 = new HelloClass2();
 
c1.SayHi();
 
c1.InitializeKey();
 
int num_byte = 0;
 
foreach (byte b in c1.Key) {
 
Console.Write("{0:X2} ", b);
num_byte++;
 
} // end of foreach
 
Console.WriteLine("\n" + "The number of bytes:\t" + num_byte);
 
Console.WriteLine("\nWe're using {0} with {1}-bit key.\n", c1.strY, c1.intX);
 
return 0;
 
} // end of main
 
} // end of class

Since the file HelloClass.cs in the previous example is still included in your project you have to set that file to Exclude From Project before compiling HelloClass2.cs. (see step 11). If you do not remember how to do this refer to the previous example.

Compile and run the program by selecting Debug and then Start Without Debugging. Examine the source code and the output line by line. Make sure that you understand everything in the program. This example shows how to access members of another class. Here the Main method is put inside the class HelloApp, which is used for program entry point. The InitializeKey method will be used later in an encryption example in the next section.

Now you have completed the basic C# programs. The next section will describe how to use classes provided by the .NET Security Framework for cryptography algorithm implementations.

Java Cryptography Extension

Java Cryptography has long been used by many programmers, however, it is used as an external package and requires extensive integrity checks on any piece of code. Recently, Sun Microsystem, the creator of Java, has released a new cryptographic packages that are included with Java 2 Standard Edition version 1.4 (J2SE v1.4). The packages are called Java Cryptography Extension (JCE). It has been widely used from small Java applications such as an Applet to large applications such as Web-based Automating Toolkit. In the current release, JCE has decent APIs that are easy to use. Also in this release, many new ciphers such as AES have been integrated. For more information about JCE. You can visit Sun's website for more information on JCE at http://java.sun.com/products/jce/.

Overview of JCE

JCE is composed of many classes, which you can review when you want to use them. However, there are a few core classes you should know.

The Cipher class

This is the core class that is required in every cryptographic program. The Cipher object defines what cipher will be used, the mode that will be used, and what padding method will be used when one is required. You have to include an initiation, which is used to specify whether the cipher is for encryption or decryption and what parameters are required. For example, it is required to specify the Initial Vector (IV) when you want to use it in Cipher Block Chaining (CBC) mode. If you use RC5 cipher, you also need to specify the key size, the input block size, and the operational rounds for encryption. The parameters are encapsulated in the AlgorithmParameters class. In some special cases, you will need to pass the parameters required for decryption so that the ciphertext can be correctly decrypted.

To do any cipher operation, you need to perform three. First, you need to initialize the cipher as described above. Then, you need to use update() to run the cipher. Finally, you need to use doFinal() to complete the cipher process. However, in JCE, you can use doFinal(plaintext) in most cases, which does not require the use of update().

The Cipher Stream classes

The cipher stream classes are CipherInputStream and CipherOutputStream. These classes are filter classes that are used in conjunction with FileInputStream and FileOutputStream classes. They encrypt the data stream providing confidentiality. This class can be used with file encryption or socket applications.

The KeyGenerator and KeyFactory Classes

The KeyGenerator class is used to generate a set of keys from a specific random number. However, to generate a random number that is secure, you ought to use SecureRandom class to generate a secure random number and use it to generate a key. The KeyFactory Class is used to store secret keys. It provides an abstract level for key storage.

The KeyAgreement Class

This class provides methods for key agreement protocol such as the Diffie-Hellman protocol. The agreement is composed of exchanging phases. Then, a shared secret or key can be generated after the exchanging phrases.

The Mac Class

This class is the core class for Message Authentication Code (MAC). Similar to Cipher class, the Mac class is initialized to specify what MAC algorithm and key that should be used. Then, it computes the MAC based on operations such as update(), doFinal() similar to Cipher class methods.

JCE Programming

This section will introduce you to some JCE APIs through the use of an example, which will be encrypting a "Hello World" program. You will be given sample code that will demonstrate how the JCE works, which can be found below.

First you will load some Java packages including Java security and Java crypto packages, which is done in line 1 - 4.

 1  import java.security.*;
 2  import javax.crypto.*;
 3  import javax.crypto.spec.*;
 4  import java.io.*;

On line 7, you need to specify the exception that will be thrown. On line 8-10 parameters are defined.

 5  public class hello {
 6  
 7     public static void main(String[] args) throws Exception {
 8          String plaintext = "Hello World!";
 9          String mykey = "1122334455667788"; // needed to be exactly 16 bytes
10     

On line 13 a key is being defined using the SecretKeySpec class along with the algorithm that the key will be used for. Line 15 the IV is being definede since AES is being used in CBC mode. The JCE requires the IV to be exactly 16 bytes long.

12        // define a key
13        SecretKeySpec keyspec = new SecretKeySpec(mykey.getBytes(), "AES");
14        // define the IV
15        IvParameterSpec ivspec = new IvParameterSpec(myiv.getBytes());

Next the cipher will be instantiated, where you have to specify the cipher type, cipher mode, and the padding mode used. This is done on line 17. The backslash (/) is being used to specify these arguments in one string. This example uses AES in CBC mode with a PKCS#5 padding mode. There are a number of ciphers that are available to be used along with modes and padding methods that can be reviewed at the end of this section.

16        // set the cipher to desired operations
17        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

The init() method is used to set the mode for encryption or decryption, key, and the IV, which can be seen in line 19.

18        // initiate the cipher
19        cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);

In line 21 the plaintext is being encrypted using the doFinal() method. If you want to handle multiple encryptions you should use the update() method to encrypt one block of data, and then use the doFinal() method to encrypt the remaining data. The doFinal() method will pad the data it is is less than the specified block size. The encryption process requires input and output to be in the form of a byte.

20        // Encrypt
21        byte [] encrypted = cipher.doFinal(plaintext.getBytes());
22  

To make encrypted text readable, you will use Base64 encoding, which is done in line 24. This process is done by using the Base64Encoder class to encode the encrypted bytes. In line 25 the encoded bytes are being printed out to the screen.

23        // Encode
24        String encoded = new sun.misc.BASE64Encoder().encode(encrypted);
25        System.out.println(encoded);
26  

After encrypting and encoding the data it must be decoded and decrypted. Line 28 decodes the data, where the Base64Decoder class is being used and returns the bytes it decodes.

27        // Decode
28        byte [] decoded = new sun.misc.BASE64Decoder().decodeBuffer(encoded);
29  

Now you can decrypt the data, which requires you to have the same algorithm parameters that were used for the encryption. You can use the getParameters() method to retrieve the parameters from the AlgorithmParameters class that holds them. This is done in line 31. Line 32 the parameters are printed out to verify their correctness. In this example CBC is being used so the only parameter that is used is the IV

30        // get algorithm parameters for decryption
31        AlgorithmParameters aparam = cipher.getParameters();
32        System.out.println("Params " + aparam.toString());
33  

After you have gotten the parameters the cipher can be instantiated, which is done in line 35. The ciphertext can now be decrypted using the doFinal() method as you can see in line 36. Line 37 the plaintext is being printed out.

34        // Decrypt using the same key
35        cipher.init(Cipher.DECRYPT_MODE, keyspec, aparam);
36        byte [] decrypted = cipher.doFinal(decoded);
37        System.out.println(new String(decrypted));
38     } // end of main
39  } // end of class

Available Ciphers and their Defaults

The following is a list of available ciphers and their default key size and block size.

CipherDefault Key SizeDefault Block Size
AES128 bits128 bits
Blowfish56 bits64 bits
DES56 bits64 bits
DESede112 bits64 bits
PBEWith <digest> and <encryption>Variable due to encryption typeVariable due to encryption type
RC2, RC4, and RC5128 bits64 bits
RSA1024 bitsVariable

Available Modes

The following is a list of available modes that are available.

ModeDescription
NONENo mode is used
CBCCipher block chaining mode
ECBElectronic code book mode
CFBCipher feedback mode
OFBOutput feedback mode
PCBCPropagating CBC mode defined by Kerberos v4

Available Padding Methods

The following is a list of available padding methods.

Pad MethodDescription
NoPaddingNo padding is used, requiring the data's length to be the size of multiple blocks
OAEPWith <digest> and <mgf> PaddingUse RSA OAEP padding
PKCS5 PaddingPKCS # 5 standard padding
SSL3 PaddingUse SSL v 3 padding (not available with J2SE v1.4)

For more Java programming libraries, there are plenty of on-line resources and books. Please see the Resources section at the end of the document.

Exercises

From the previous sections, you have learned to write a cryptographic program using the OpenSSL library, and how to compile your program. In this section, you will be presented with a series of exercises requiring you to write programs using the knowledge you have learned from previous sections. You need to solve each problem using both Java and C.

If you are submitting your work include your name in the header of each program. You also need to include a printout of your program's result as seen on the screen. Use the "script" program on Unix to capture your screen typing. Zip all source code into a single folder where your file name is lab1-<your name>.zip. It is not necessary to submit the Worksheet Solutions document as long as you include a printout of the following answers.

Problem 1

Given a Base64 encoded ciphertext, key and IV that has been encrypted using AES in CBC mode, find the plaintext.

Based64-encoded ciphertext:
   hTpVHO39rnpFyThzbcI+gg0rdBcbHL+5OqWFFY8QDF6T/nX4+O1lXFgJnDbRFaC1lL5hFY3uVsbQ8mP14yeSDNnD2dFnhBZLbkjqriE8IwJfcA3yL1Q3LhKQVUWPgPrZVvL98RtKl9ZEYCW/Sb7egw==
Key: Have you failed?
IV: This is your IV!

Hints:

Problem 2

Given a partial secret key (the first 13 bytes) and the IV, try breaking an AES encryption in CBC mode by searching for the last 3 bytes of the key to find the associated plaintext.

Partial key (the first 13 bytes): {0x01,0x23,0x45,0x67,0x89,0x1a,0xbc,0xde,0xf0,0x01,0x23,0x45,0x67}
IV: {0x10,0x20,0x30,0x40,0x50,0x60,0x70,0x80,0x90,0xa0,0xb0,0xc0,0xd0,0xe0,0xf0,0x00}
Known beginning text: "The unknown message is:"
Base64-encoded ciphertext:
   A8K+2+60yXYmEBQHOW4BN/2f/ubS5JMHy/B4hpGiaHDbR4qGLBL0AiwvUKi/th+lHt2meNQ82Zmfmnk2+rqd6dBERgBe82v7Smvri2T3VNuhu00h42l6CWHfPguguX5Ya1MNvmBxvMWygk21q+t0nA==

Hints:

Problem 3

Implement AES encryption using the Counter Mode Encryption (CTR) or AES-CTR, and use your own key, IV, and message. Submit your key, IV, plaintext, and the Base64 encoded ciphertext for grading. Do not forget to encode your ciphertext using Base64 encoding so it can be readable for grading.

Problem 4

Use the AES-CTR mode to decrypt the given ciphertext using a given key and IV. Find and submit the associated plaintext. You will use a CTR cipher, a stream mode cipher, to encrypt a counter to produce a stream of pseudorandom numbers that are used to encrypt plaintext, which is simply an XOR encryption operation.

Key: What do you see?
IV: Who would ya be?
Ciphertext: (Encoded by Base64):
   dIR1uyU0YhU9s3+jLwgzLhXQbbt2I2IeMqlo9jAZL35cyiW7ICJ5AXSve/MzHyIqW81xp21nahZ0r3v3NQA/K0GEdrszNCsMPKUr7CwdOStB0Wu3Ij4rETrgbvU5Hy96Uc1juD8kfhQguSWjcU0FMkeEUrc4NH8XOuBI6ykfNTxcyGn+fnYzT2DtOrpqWH8=
You MUST use AES in CFB mode to encrypt the counter, which starts from zero.
Ciphertext should be on one line or one string to avoid the newline character (\n) in the string.

Here is the pseudocode for the CTR program.

 1  encrypted_counter = AES_Encrypt(counter);
 2  for (the number of plaintext bytes)
 3     if (we don't have enough encrypted counter bytes) {
 4        increase the counter;
 5        encrypt the counter;
 6     }
 7  ciphertext = pseudorandom plaintext;

On line 1, the first block of random bytes are generated by encrypting a counter number. Using AES you will have 16 random bytes from one encryption. This means you will need 6 AES encryptions for plaintext with a length between 81 - 96 bytes. Lines 3 -6 will check whether there are enough encrypted bytes for a XOR operation. If not the counter should be increased. Line 7 a XOR operation is performed on the plaintext using the random bytes.

CTR's decryption mode is similar to the process of encrypting the counter in the previous step. To find the associated plaintext use XOR operations on the ciphertext using the random bytes generated by the counter. For more information about the CTR mode visit http://csrc.nist.gov/CryptoToolkit/modes/workshop1/papers/lipmaa-ctr.pdf.

Hints:

Worksheet Solutions

The following questions you are required to submit.

Problem 1. Plaintext ____________________________________________________________________

Problem 2. The last three bytes of the key are ______________________________________________
   Plaintext ____________________________________________________________________

Problem 3: Message ____________________________________________________________________
   Key ________________________________________________________________________
   IV __________________________________________________________________________
   Ciphertext ___________________________________________________________________

Problem 4: The plaintext is _______________________________________________________________