Xiao Qin's Research

Auburn University

QoSec Project

A Middleware Approach to Teaching Computer Security (2009 - )

Project 6: A Simple Cryptographic Tool


Process – 30 points:

Create a text, doc, or .pdf file named “_3p” (for example, mine might read “xzq0001_3p.txt, xzq0001_3p.doc, or xzq0001_3p.pdf”) and provide each of the following. Please submit a text file, .doc file, or .pdf file (if you want to use diagrams or pictures, use .doc or .pdf). Steps that you are responsible for in the process document are bolded (i.e., items 1, 2, and 3 below). You are free to use tools like Word or Visio to help you, but the final output needs to be .txt or .pdf.

1. Analysis (1 artifact): Prepare use cases. Remember, these use cases describe how the user interacts with the cryptographic tool via command lines (what does the tool do, what the tool does in response, etc.). Your use cases should have enough basic details such that someone unfamiliar with the cryptographic tool can have an understanding of what is happening in the tool after a command is issued. They should not include internal technical details that the user is not (and should not be) aware of. Check out the following link for a use case example:
Note: You have to follow the format of this use case example.

2. Design (2 artifacts):
a. Create a Class Diagram (as in Lab 2). The diagram is not optional. Be sure to include:

  1. The name and purpose of the classes
  2. The member variables and the functions of the class
  3. Show the interactions between classes (for example, ownership or dependency)
  4. Any relevant notes that don’t fit into the previous categories can be added
  5. Numbering in relationships

b. For the “Perform Encryption Using an Encryption algorithm” and “Perform Decryption using a Decryption Algorithm” features, create System Sequence Diagrams. Make sure to include function names, data types, and ordering information. Feel free to add explanatory notes. To get extra help, check out the following links for some additional examples:

c. You must implement TranspositionCipher and the SubstitutionCipher as classes. Hint: Inheritance could be very useful in order to create a generic parent class that both ciphers inherit from!

3. Testing (2 artifacts): Develop a driver and show the driver:

  1. For the system at large. In other words, describe inputs for “nominal” usage. You may need several scenarios. Also, suggest scenarios for abnormal usage and show what your program should do (for example, entering a negative number for a menu might ask the user to try again).
  2. For each object. (Later, these tests can be automated easily using a simple driver function in the object)

4. Implement your solution

5. Test Results: After developing your solution, actually try all of your test cases (both system and unit testing). Actually show the results of your testing (a copy and paste from your program output is fine – don’t stress too much about formatting as long as the results are clear). You should have test results for every test case you described. If your system doesn’t behave as intended, you should note this. Note: Driver output will substitute for this phase.

Program + Testing Results – 70 points:

Description :

Write a program called sectool_username.cpp (for example, mine would read “sectool_xzq0001.cpp”).

Use comments to provide a heading at the top of your code containing your name, Auburn Userid, and filename. Please describe any help or sources that you used (as per the syllabus).

You will lose points if you: do not use the specific program file name, or do not have a comment block on EVERY program you hand in.

Problem Statement:

Cryptography: There are various threats to the security of computer systems. There are factors that threaten the confidentiality of security sensitive files.

Your aim is to build a simple cryptographic tool that can encrypt and decrypt files storage in a Linux file system. You need to implement two functionalities, namely, encryption and decryption. You have to use an encryption algorithm to encipher (a.k.a., encode) a plain text file and save the corresponding cipher text in another file. Note that the enciphered text is called “cipher text”. The goal of encryption is to protect plain text files from being accessed and viewed by unauthorized users. Authorized users can use a decryption tool to decrypt cipher text files and get plaintext files.


You have to use two encryption algorithms:

Transposition Cipher: Columnar transposition:

In a columnar transposition, the message is written out in rows of a fixed length, and then read out again column by column, and the columns are chosen in some scrambled order. Both the width of the rows and the permutation of the columns are usually defined by a keyword. For example, the word ZEBRAS is of length 6 (so the rows are of length 6), and the permutation is defined by the alphabetical order of the letters in the keyword. In this case, the order would be "6 3 2 4 1 5".

In a regular columnar transposition cipher, any spare spaces are filled with nulls; in an irregular columnar transposition cipher, the spaces are left blank. Finally, the message is read off in columns, in the order specified by the keyword. For example, suppose we use the keyword ZEBRAS and the message WE ARE DISCOVERED. FLEE AT ONCE. In a regular columnar transposition, we write this into the grid as:

6 3 2 4 1 5
V E R E D .
E . * * * *

Providing four nulls (* * * *) at the end. The ciphertext is then read off as:


Note: _ in the above ciphertex is a space.

Substitution Cipher

The second algorithm is a “substitution cipher”. It changes the characters in the plaintext to produce the ciphertext. It changes the plaintext according to a key. You have to implement a Vigenere cipher which uses a sequence of keys, represented by a string. You can find about the Vigenere cipher here.


Here is an example of encryption using the Vigenere cipher.

Plaintext B ENCHBENC
Ciphertext B PVOLSMPM

The encrypting user uses the key and the plaintext to form the ciphertext from the table. This is a very secure method because it is very tough for a hacker to crack the plaintext from the ciphertext.

Here is another example for encryption using Vigenere tableau. The person sending the message chooses a keyword and repeats it until it matches the length of the plaintext, for example, the keyword "LEMON":


The key for Vigenere cipher and the permutation function for transposition cipher should be input as parameters to the encryption and decryption algorithms. They must not be got from the command line.


Program Execution:
Your tool must be named sectool_username. You need to run the program from the command line. The command line should look like,

$./sectool_username -f -n filename

where, sectool_username – The name of your cryptographic tool.
f – flag to specify technique. It is –e for encryption and –d for decryption.
n – flag to specify which algorithm. It is 1 for transposition and 2 for substitution.
Filename – specify a file that contains either plain text (if f = e) or cipher text (if f = d).

You need to read the plaintext from the file and encrypt it using the specified algorithm and write it back to the file so that it can be exchanged with the other user. You can specify the key in another file or give it to the receiver in any mode.

Sample usage for the transposition cipher:

./sectool_xzq0001 -e -1 testinput
Enter a ciphertext file name: testinput-cipher
Enter Your Key: ZEBRAS
Reading the plaintext file …
Encrypting …
Writing the ciphertext file: testinput-cipher …

./sectool_xzq0001 -d -1 testinput-cipher
Enter a plaintext file name: testinput-new
Enter Your Key: ZEBRAS
Reading the cipher file ...
Decrypting …
Writing the plaintext file: testinput-new …

Note: After the testinput-new file was created, you can compare testinput-new with the original testinput file. These two files should be identical.

Sample usage for the substitution cipher:

./sectool_xzq0001 -e -2 testinput
Enter Your Key: VIG
Enter a ciphertext file name: testinput-cipher
Reading the plaintext file …
Encrypting …
Writing the ciphertext file: testinput-cipher …

./sectool_xzq0001 -d -2 testinput-cipher
Enter Your Key: VIG
Enter a plaintext file name: testinput-new
Reading the cipher file ...
Decrypting …
Writing the plaintext file: testinput-new …

Help Information:

You also need to implement a help link in your program that tells about your implementation to the end users. It should be like,

$./sectool –help

It should give basic help information about your cryptographic tool, so that users do not have any problem in understanding how to use your command-line tool.

C++ Command-Line Arguments:

Reading input from the command line is a bit mysterious to beginners, and hard to extract from reference manuals. The declarations and commands will eventually make sense to you. But at first you may want to treat them as magic, and copy them with minor adjustments.

The main function takes two arguments. Well, actually it takes three, but only insane hackers know about the third one. The main function can be written as if it took two arguments. Or you can pretend it takes no inputs, if you don't intend to use them.

main () // version ignoring the inputs
{ ....

main(int argc,char *argv[]) // version including the inputs

The input argc is the number of items on the command line. C++ divides the command line into items by breaking it at whitespace (e.g. spaces). The items include the command name itself, so

test --> argc is 1
weave 4 --> argc is 2
encode 4.2 3 foo --> argc is 4

The input argv is an array of strings, one string per item. So argv[0] is the command name, argv[1] is the first input, etc.

Numbers on the command line appear in argv as strings, not as numbers. That is, they are still raw sequences of characters: digits, decimal points, etc. To translate them into numbers, use the functions atoi and atof.

atoi (char *str)
Returns the integer corresponding to the string.

atof (char *str)
Returns the floating point number corresponding to the string.

If you use atoi and atof, your program must include the stdlib header file: #include <stdlib.h>

A Command-Line Example:

The following program demonstrates how command-line arguments are passed:


// comman
// compile with: g++ in Linux
// Sample usage: ./command_line -e -1 testinput.txt
#include <iostream>

using namespace std;d_line.cpp

int main( int argc, // Number of strings in array argv
char *argv[], // Array of command-line argument strings
char *envp[] ) // Array of environment variable strings
int count;

// Display each command-line argument.
cout << "\nCommand-line arguments:\n"

for( count = 0; count < argc; count++ )
cout << " argv[" << count << "] "
<< argv[count] << "\n"


You can download the command_line.cpp source code from

Separate Compilation:

You must use separate compilation and create a makefile for this project.

What is Make?

Make is a program that looks for a file called "makefile" or "Makefile", within the makefile are variables and things called dependencies. There are many things you can do with makefiles, if all you've ever done with makefiles is compile C or C++ then you are missing out. Pretty much anything that needs to be compiled (postscript, java, Fortran), can utilize makefiles.

Format of Makefiles -- Variables

First, lets talk about the simpler of the two ideas in makefiles, variables. Variable definitions are in the following format:


So lets say I want to use a variable to set what compiler i'm going to use. This is helpful b/c you may want to switch from cc to gcc or to g++. We would have the following line in our makefile

CC = g++


This assigns the variable CC to the string "gcc". To expand variables, use the following form:


So to expand our CC variable we would say:


Format of Makefiles -- Dependencies

Dependencies are the heart of makefiles. Without them nothing would work. Dependencies have the following form:

dependecy1: dependencyA dependencyB ... dependencyN

command for dependency1

Check out the following links for more information on makefiles:

Additional Details:

You will use classes in this assignment. You must have the concept of an Individual class which is SHARED by both the TranspositionCipher class and the SubstitutionCipher class.You will lose points if you do not do this.

You must implement TranspositionCipher and the SubstitutionCipher as classes. Hint: Inheritance could be very useful in order to create a generic parent class that both ciphers inherit from!

In our implementation, you will have to use the assert() macro to make it easier to test your tool. You will lose points if you do not do this.

You must conduct testing with the implementation of a test driver. You will lose points if you do not do this.

You are free to implement more classes as you see fit, but a functional decomposition will not be sufficient to meet the basic requirements of this assignment.

You are welcome to reuse well-written classes from earlier COMP 2710 projects (but indicate where they came from).


Follow the comment standard posted on the web or some alternate, approved standard.

Please submit your program through Blackboard (e-mail submission only as a fallback).

You should upload at least five files:

  1. Makefile (this should make your project)
  2. sectool_username.cpp (this should be your application file)
  3. sectool_username.h (header file)
  4. <username>_3p.txt or <username>_3p.pdf or <username>_3p.doc
  5. <username>_3p-original.txt or <username>_3p-original.pdf or <username>_3p-original.doc