You are on page 1of 85

A Laboratory Manual for

Information Security
(3170720)

B.E. Semester 7
(Computer Engineering)

Directorate of Technical
Education,Gandhinagar,Gujarat
Government Engineering College, Modasa
CERTIFICATE

This is to certify that Mr. Sonagara Jigna Jayanatibhai Enrollment No. 200160107075
of B.E. Semester 7th Computer Engineering Department of this Institute (GTU Code:
016) has satisfactorily completed the Practical / Tutorial work for the subject Artificial
Intelligence (3170716) for the academic year 2023-24.

Date:

Sign of Faculty Coordinator Head of Department


S A Chauhan H R Patel
Preface

Main motto of any laboratory/practical/field work is for enhancing required skills as well as creating
ability amongst students to solve real time problem by developing relevant competencies in
psychomotor domain.By keeping in view, GTU has designed competency focused outcome-based
curriculum for engineering degree programs where sufficient weightage is given to practical work. It
shows importance of enhancement of skills amongst the students and it pays attention to utilize every
second of time allotted for practical amongst students, instructors and faculty members to achieve
relevant outcomes by performing the experiments rather than having merely study type experiments.
It is must for effective implementation of competency focused outcome-basedcurriculum that every
practical is keenly designed to serve as a tool to develop and enhance relevant competency required
by the various industry among every student. These psychomotor skills are very difficult to develop
through traditional chalk and board content delivery method in the classroom. Accordingly, this lab
manual is designed to focus on the industry defined relevant outcomes, rather than old practice of
conducting practical to prove concept and theory.

By using this lab manual students can go through the relevant theory and procedure in advance before
the actual performance which creates an interest and students can have basic idea prior to performance.
This in turn enhances pre-determined outcomes amongst students. Each experiment in this manual
begins with competency, industry relevant skills, course outcomes as well as practical outcomes
(objectives). The students will also achieve safety and necessary precautions to be taken while
performing practical.

This manual also provides guidelines to faculty members to facilitate student centric lab activities
through each experiment by arranging and managing necessary resources in order that the students
follow the procedures with required safety and necessary precautions to achieve the outcomes. It also
gives an idea that how students will be assessed by providing rubrics.

Information security is the subject that helps students to understand various aspects of data security. It
provides a way to know various kinds of breaches that happen with data and how to eliminate them
using various techniques. The student is also able to learn various methodologies which used by current
used by developers to achieve the security of information.
Practical – Course Outcome matrix

Course Outcomes (COs):


1. Explore the basic principles of the symmetric cryptography and techniques with
their strengths and weaknesses from perspective of cryptanalysis
2. Implement and analyze various symmetric key cryptography algorithms and their
application in different context
3. Compare public key cryptography with private key cryptography and Implement
various asymmetric key cryptography algorithms
4. Explore the concept of hashing and implement various hashing algorithms for
message integrity
5. Explore and use the techniques and standards of digital signature, key management
and authentication
Sr. CO CO CO CO CO
Objective(s) of Experiment
No. 1 2 3 4 5

1. Implement Caesar cipher encryption-decryption. √

2. Implement Playfair cipher encryption-decryption. √

3. Implement Hill cipher encryption-decryption √

4. Implement Vigenere Cipher encryption-decryption √

Implement Rail Fence Transposition cipher


5. √
technique.

6. To implement Simple DES encryption-decryption. √

7. To implement Simple AES encryption-decryption. √

8. Implement RSA encryption-decryption algorithm. √

9. Implement Diffi-Hellman Key exchange Method √

10. Write a program to generate MD-5 hash. √

11. Write a program to generate SHA-1 hash √

12. Implement a digital signature algorithm. √

13. Demonstrate how to work with JCrypTool

14. Demonstrate how to work with Wireshark


Industry Relevant Skills

The following industry relevant competency are expected to be developed in the student by
undertaking the practical work of this laboratory.
1. Able to think about information security scenario and make solution
2. Able to develop and algorithms which helps to secure data

Guidelines for Faculty members


1. Teacher should provide the guideline with demonstration of practical to the students with
all features.
2. Teacher shall explain basic concepts/theory related to the experiment to the students before
starting of each practical
3. Involve all the students in performance of each experiment.
4. Teacher is expected to share the skills and competencies to be developed in the students
and ensure that the respective skills and competencies are developed in the students after
the completion of the experimentation.
5. Teachers should give opportunity to students for hands-on experience after the
demonstration.
6. Teacher may provide additional knowledge and skills to the students even though not
covered in the manual but are expected from the students by concerned industry.
7. Give practical assignment and assess the performance of students based on task assigned
to check whether it is as per the instructions or not.
8. Teacher is expected to refer complete curriculum of the course and follow the guidelines
for implementation.

Instructions for Students


1. Students are expected to carefully listen to all the theory classes delivered by the faculty
members and understand the COs, content of the course, teaching and examination
scheme, skill set to be developed etc.
2. Students shall organize the work in the group and make record of all observations.
3. Students shall develop maintenance skill as expected by industries.
4. Student shall attempt to develop related hand-on skills and build confidence.
5. Student shall develop the habits of evolving more ideas, innovations, skills etc. apart from
those included in scope of manual.
6. Student shall refer technical magazines and data books.
7. Student should develop a habit of submitting the experimentation work as per the schedule
and s/he should be well prepared for the same.

Common Safety Instructions


Students are expected to carefully
Index
(Progressive Assessment Sheet)

Sr. Objective(s) of Experiment Page Date of Date of Assessme Sign. of Remar


No. No. perform submiss nt Teacher ks
ance ion Marks with date
Implement Caesar cipher encryption-
1
decryption.
Implement Playfair cipher encryption-
2
decryption.
Implement Hill cipher encryption-
3
decryption
Implement Vigenere Cipher encryption-
4
decryption
Implement Rail Fence Transposition cipher
5
technique.
To implement Simple DES encryption-
6
decryption.
To implement Simple AES encryption-
7
decryption.
Implement RSA encryption-decryption
8
algorithm.
Implement Diffi-Hellman Key exchange
9
Method

10 Write a program to generate MD-5 hash.

11 Write a program to generate SHA-1 hash

12 Implement a digital signature algorithm.

13 Demonstrate how to work with JCrypTool

14 Demonstrate how to work with Wireshark

Total
OBJECTIVES:
The student should be made to:

➢ Learn to implement the algorithms DES, RSA,MD5,SHA-1 Etc.


➢ Learn to use network security tools like crypto, Wireshark

OUTCOMES:
At the end of the course, the student should be able to:

➢ Implement various cipher techniques


➢ Develop various security algorithms
➢ Use different open source tools for network security and analysis

LIST OF HARDWARE REQUIREMENTS & SOFTWARE REQUIREMENTS

SOFTWARE REQUIREMENTS

➢ C/ C++, JDK Etc. (As per requirement)

HARDWARE REQUIREMENTS

➢ Standalone desktops
Information Security (3170720)

Experiment No: 1
Implementation of caesar cipher
Date:
Relevant CO: Explore the basic principles of the symmetric cryptography and techniques with their
strengths and weaknesses from perspective of cryptanalysis

Objectives: (a) to understand working fundamental of Caeser Cipher


(b) to carry out Implementation of Caesar cipher encryption-decryption.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
To encrypt a message with a Caesar cipher, each letter in the message is changed using
a simple rule: shift by three. Each letter is replaced by the letter three letters ahead in the
alphabet. A becomes D, B becomes E, and so on. For the last letters, we can think of the
alphabet as a circle and "wrap around". W becomes Z, X becomes A, Y bec omes B, and Z
becomes C. To change a message back, each letter is replaced by the one three before it.

Example:

Algorithm:

STEP-1: Read the plain text from the user.


STEP-2: Read the key value from the user.
STEP-3: If the key is positive then encrypt the text by adding the key with each
character in the plain text.
STEP-4: Else subtract the key from the plain text.
STEP-5: Display the cipher text obtained above.

1
Information Security (3170720)

Program:

#include <stdio.h>
#include <string.h>

void encrypt_text(char *plain_text, int key) {


int length = strlen(plain_text);
for (int i = 0; i < length; i++) {
plain_text[i] = ((plain_text[i] - 97 + key) % 26) + 97;
}
}

void decrypt_text(char *plain_text, int key) {


int length = strlen(plain_text);
for (int i = 0; i < length; i++) {
plain_text[i] = ((plain_text[i] - 97 - key) % 26) + 97;
}
}

int main(void) {
char plain_text[] = "helloworld";
printf("plaintext : %s\n", plain_text);
encrypt_text(plain_text, 1);
printf("encrypted : %s\n", plain_text);
decrypt_text(plain_text, 1);
printf("decrypted : %s\n", plain_text);
return 0;
}

Output:

Conclusion:
Caesar cipher algorithm can be implemented in many encryption projects to make data secure and
better. Security is one of the important aspects in computing.

Quiz:

1. Is Ceaser Cipher Symmetric or Asymmetrci algorithm ?


Symmetric

2. Encrypt the word alphabet using a Caesar cipher with a shift of 3


doskdehw

2
Information Security (3170720)

Suggested Reference:
1. https://www.geeksforgeeks.org/caesar-cipher-in-cryptography/

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

3
Information Security (3170720)

Experiment No: 2
Implementation of Playfair cipher
Date:
Relevant CO: Explore the basic principles of the symmetric cryptography and techniques with their
strengths and weaknesses from perspective of cryptanalysis

Objectives: (a) to understand working fundamental of Playfair cipher


(b) to carry out Implementation of Playfair cipher encryption-decryption.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
The Playfair cipher starts with creating a key table. The key table is a 5×5 grid of
letters that will act as the key for encrypting your plaintext. Each of the 25 letters must be unique
and one letter of the alphabet is omitted from the table (as there are 25 spots and 26 letters in the
alphabet). To encrypt a message, one would break the message into digrams (groups of 2 letters)
such that, for example, "HelloWorld" becomes "HE LL OW OR LD", and map them out on the
key table. The two letters of the diagram are considered as the opposite corners of a rectangle in
the key table. Note the relative position of the corners of this rectangle. Thenapply the
following 4 rules, in order, to each pair of letters in the plaintext:

1. If both letters are the same (or only one letter is left), add an "X" after the first letter
2. If the letters appear on the same row of your table, replace them with the letters to
their immediate right respectively
3. If the letters appear on the same column of your table, replace them with the letters
immediately below respectively

If the letters are not on the same row or column, replace them with the letters on the same row
respectively but at the other pair of corners of the rectangle defined by the original pair.

Example:

4
Information Security (3170720)

Algorithm:

STEP-1: Read the plain text from the user.


STEP-2: Read the keyword from the user.
STEP-3: Arrange the keyword without duplicates in a 5*5 matrix in the row order and fill
the remaining cells with missed out letters in alphabetical order. Note that ‘i’ and
‘j’ takes the same cell.
STEP-4: Group the plain text in pairs and match the corresponding corner letters by forming
a rectangular grid.

STEP-5: Display the obtained cipher text.

Program:

// C program to implement Playfair Cipher

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define SIZE 30

// Function to convert the string to lowercase


void toLowerCase(char plain[], int ps) {
int i;
for (i = 0; i < ps; i++) {
if (plain[i] > 64 && plain[i] < 91)
plain[i] += 32;
}
}

// Function to remove all spaces in a string


int removeSpaces(char *plain, int ps) {
int i, count = 0;
for (i = 0; i < ps; i++)
if (plain[i] != ' ')
plain[count++] = plain[i];
plain[count] = '\0';
return count;
}

// Function to generate the 5x5 key square


void generateKeyTable(char key[], int ks, char keyT[5][5]) {
int i, j, k, flag = 0, *dicty;

// a 26 character hashmap
// to store count of the alphabet
dicty = (int *)calloc(26, sizeof(int));
for (i = 0; i < ks; i++) {
if (key[i] != 'j')
dicty[key[i] - 97] = 2;
}

5
Information Security (3170720)

dicty['j' - 97] = 1;

i = 0;
j = 0;

for (k = 0; k < ks; k++) {


if (dicty[key[k] - 97] == 2) {
dicty[key[k] - 97] -= 1;
keyT[i][j] = key[k];
j++;
if (j == 5) {
i++;
j = 0;
}
}
}

for (k = 0; k < 26; k++) {


if (dicty[k] == 0) {
keyT[i][j] = (char)(k + 97);
j++;
if (j == 5) {
i++;
j = 0;
}
}
}
}

// Function to search for the characters of a digraph


// in the key square and return their position
void search(char keyT[5][5], char a, char b, int arr[]) {
int i, j;

if (a == 'j')
a = 'i';
else if (b == 'j')
b = 'i';

for (i = 0; i < 5; i++) {

for (j = 0; j < 5; j++) {

if (keyT[i][j] == a) {
arr[0] = i;
arr[1] = j;
} else if (keyT[i][j] == b) {
arr[2] = i;
arr[3] = j;
}
}
}
}

// Function to find the modulus with 5


int mod5(int a) { return (a % 5); }

// Function to make the plain text length to be even


int prepare(char str[], int ptrs) {
if (ptrs % 2 != 0) {

6
Information Security (3170720)

str[ptrs++] = 'z';
str[ptrs] = '\0';
}
return ptrs;
}

// Function for performing the encryption


void encrypt(char str[], char keyT[5][5], int ps) {
int i, a[4];

for (i = 0; i < ps; i += 2) {

search(keyT, str[i], str[i + 1], a);

if (a[0] == a[2]) {
str[i] = keyT[a[0]][mod5(a[1] + 1)];
str[i + 1] = keyT[a[0]][mod5(a[3] + 1)];
} else if (a[1] == a[3]) {
str[i] = keyT[mod5(a[0] + 1)][a[1]];
str[i + 1] = keyT[mod5(a[2] + 1)][a[1]];
} else {
str[i] = keyT[a[0]][a[3]];
str[i + 1] = keyT[a[2]][a[1]];
}
}
}

// Function to encrypt using Playfair Cipher


void encryptByPlayfairCipher(char str[], char key[]) {
char ps, ks, keyT[5][5];

// Key
ks = strlen(key);
ks = removeSpaces(key, ks);
toLowerCase(key, ks);

// Plaintext
ps = strlen(str);
toLowerCase(str, ps);
ps = removeSpaces(str, ps);

ps = prepare(str, ps);

generateKeyTable(key, ks, keyT);

encrypt(str, keyT, ps);


}

// Driver code
int main() {
char str[SIZE], key[SIZE];

// Key to be encrypted
strcpy(key, "monarchy");
printf("Key text: %s\n", key);

// Plaintext to be encrypted
strcpy(str, "helloworld");
printf("Plain text: %s\n", str);

7
Information Security (3170720)

// encrypt using Playfair Cipher


encryptByPlayfairCipher(str, key);

printf("Cipher text: %s\n", str);

return 0;
}

Output:

Conclusion:
The Playfair cipher is relatively fast and doesn't require special equipment and can be used to encrpyt
data to pass securely in an unsecure channel.

Quiz:

1. Playfair cipher is harder to crack than keyword cipher? True/False


True

Suggested Reference:
1. https://www.geeksforgeeks.org/playfair-cipher-with-examples/

References used by the students:

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

8
Information Security (3170720)

Experiment No: 3
Implementation of Hill cipher
Date:
Relevant CO: Explore the basic principles of the symmetric cryptography and techniques with their
strengths and weaknesses from perspective of cryptanalysis

Objectives: (a) to understand working fundamental of Hill Cipher


(b) to carry out Implementation of Hill cipher encryption-decryption.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
Each letter is represented by a number modulo 26. Often the simple scheme A = 0, B = 1... Z = 25, is
used, but this is not an essential feature of the cipher. To encrypt a message, each block of n letters is
multiplied by an invertible n × n matrix, against modulus 26. To decrypt the message, each block is
multiplied by the inverse of the m trix used for encryption. The matrix used for encryption is the cipher
key, and it sho ld be chosen randomly from the set of invertible n × n matrices (modulo 26).

Algorithm:

STEP-1: Read the plain text and key from the user.
STEP-2: Split the plain text into groups of length three.
STEP-3: Arrange the keyword in a 3*3 matrix.
STEP-4: Multiply the two matrices to obtain the cipher text of length three.
STEP-5: Combine all these groups to get the complete cipher text.

Program:

// C++ code to implement Hill Cipher


#include <iostream>
using namespace std;

// Following function generates the


// key matrix for the key string
void getKeyMatrix(string key, int keyMatrix[][3]) {
int k = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
keyMatrix[i][j] = (key[k]) % 65;
k++;
}
}
}

// Following function encrypts the message


void encrypt(int cipherMatrix[][1], int keyMatrix[][3],
int messageVector[][1]) {
int x, i, j;
for (i = 0; i < 3; i++) {
for (j = 0; j < 1; j++) {
9
Information Security (3170720)

cipherMatrix[i][j] = 0;

for (x = 0; x < 3; x++) {


cipherMatrix[i][j] += keyMatrix[i][x] * messageVector[x][j];
}

cipherMatrix[i][j] = cipherMatrix[i][j] % 26;


}
}
}

// Function to implement Hill Cipher


void HillCipher(string message, string key) {
// Get key matrix from the key string
int keyMatrix[3][3];
getKeyMatrix(key, keyMatrix);

int messageVector[3][1];

// Generate vector for the message


for (int i = 0; i < 3; i++)
messageVector[i][0] = (message[i]) % 65;

int cipherMatrix[3][1];

// Following function generates


// the encrypted vector
encrypt(cipherMatrix, keyMatrix, messageVector);

string CipherText;

// Generate the encrypted text from


// the encrypted vector
for (int i = 0; i < 3; i++)
CipherText += cipherMatrix[i][0] + 65;

// Finally print the ciphertext


cout << "Computed Ciphertext : \t" << CipherText << endl;
}

// Driver function for above code


int main() {
// Get the message to be encrypted
string message = "ACT";
cout << "Entered message : \t" << message << endl;

// Get the key


string key = "GYBNQKURP";
cout << "Entered key : \t\t" << key << endl;

HillCipher(message, key);

return 0;
}

Output:

10
Information Security (3170720)

Conclusion:
Hill cipher is a matrix multiplication based block cipher and is used to encrypt data mathematically. It
is harder to crack compared to traditional stream ciphers or monoalphabetic ciphers.

Quiz:

1. What preliminary knowledge required for Hill cipher ?


Hill cipher uses matrix multiplication in order to encrypt the given plain text. So it requires
prerequisite knowledge of matrix algebra

2. Hill cipher is example of which type of cipher technique?


The Hill cipher is a polygraphic substitution cipher based on linear algebra

Suggested Reference:
1. https://crypto.interactive-maths.com/hill-cipher.html

References used by the students:

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

11
Information Security (3170720)

Experiment No: 4
Implementation of Vigenere cipher
Date:
Relevant CO: Explore the basic principles of the symmetric cryptography and techniques with their
strengths and weaknesses from perspective of cryptanalysis

Objectives: (a) to understand working fundamental of Vigenere Cipher


(b) to carry out Implementation of Vigenere cipher encryption-decryption.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
To encrypt, a table of alphabets can be used, termed a tabula recta, Vigenère square, or Vigenère table.
It consists f the alphabet written out 26 times in differ nt rows, each alphabet shifted cyclically to the
left compared to the previous alphabet, corresponding to the 26 possible Caesar ciphers. At different
points in the encryption process, the cipher uses a different alphabet from one of the rows.
The alphabet used at each point repeating keyword depends on a Each row starts with a key letter. The
remainder of the row holds the letters A to Z. Although there are 26 key rows shown, you will only
use as many keys as there are unique letters in the key string, here just 5 keys, {L, E, M, O, N}. For
successive letters of the message, we are going to take successive letters of the key string, and encipher
each message letter using its corresponding key row. Choose the next letter of the key, go al ng that
row to find the column heading that atches the message character; the letter at the intersection of
[key-row, msg-col] is the enciphered letter.

Example:

12
Information Security (3170720)

Algorithm:

STEP-1: Arrange the alphabets in row and column of a 26*26 matrix.


STEP-2: Circulate the alphabets in each row to position left such that the first letter is
attached to last.
STEP-3: Repeat this process for all 26 rows and construct the final key matrix.
STEP-4: The keyword and the plain text is read from the user.
STEP-5: The characters in the keyword are repeated sequentially so as to match with
that of the plain text.
STEP-6: Pick the first letter of the plain text and that of the keyword as the row indices
and column indices respectively.
STEP-7: The junction character where these two meet forms the cipher character.
STEP-8: Repeat the above steps to generate the entire cipher text.

Program:

#include <iostream>
#include <string>

using namespace std;

class Vigenere{
public:
string key;
Vigenere(string key){
for (int i = 0; i < key.size(); ++i){
if (key[i] >= 'A' && key[i] <= 'Z')
this->key += key[i];
else if (key[i] >= 'a' && key[i] <= 'z')
this->key += key[i] + 'A' - 'a';
}
}

string encrypt(string text){


string out;
for (int i = 0, j = 0; i < text.length(); ++i){
char c = text[i];
if (c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if (c < 'A' || c > 'Z')
continue;

out += (c + key[j] - 2 * 'A') % 26 + 'A';


j = (j + 1) % key.length();
}
return out;
}

13
Information Security (3170720)

string decrypt(string text){


string out;
for (int i = 0, j = 0; i < text.length(); ++i){
char c = text[i];
if (c >= 'a' && c <= 'z')
c += 'A' - 'a';
else if (c < 'A' || c > 'Z')
continue;

out += (c - key[j] + 26) % 26 + 'A';


j = (j + 1) % key.length();
}

return out;
}
};

int main(){

Vigenere cipher("VIGENERECIPHER");
string original = "We will meet at the east wall";

string encrypted = cipher.encrypt(original);


string decrypted = cipher.decrypt(encrypted);

cout << original << endl;


cout << "Encrypted: " << encrypted << endl;
cout << "Decrypted: " << decrypted << endl;
}

Output:

Conclusion:
Vigenere Cipher is a simple polyalphabetic substitution method that goes from a simple to advanced
method. The Vigenere Square or Table is an important tool used in this Cipher. You can use this cipher
in three different ways as per your needs.

Quiz:

1. Encryption in Vigenere cipher is done using matrix lookup and substitution

14
Information Security (3170720)

Suggested Reference:
1. https://intellipaat.com/blog/vigenere-cipher/

References used by the students:

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

15
Information Security (3170720)

Experiment No: 5
Implementation of Rail Fence Transposition
Date:
Relevant CO: Explore the basic principles of the symmetric cryptography and techniques with their
strengths and weaknesses from perspective of cryptanalysis

Objectives: (a) to understand working fundamental of Rail Fence Transposition Cipher


(b) to carry out Implementation of Rail Fence Transposition Cipher encryption-
decryption.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
In the rail fence cipher, the plain text is written downwards and diagonally on successive "rails" of
an imaginary fence, then moving up when we reach the bottom rail.When we reach the top rail,
the message is written downwards again until the whole plaintextis written out. The message is then
read off in rows.

Example:

Algorithm:

STEP-1: Read the Plain text.


STEP-2: Arrange the plain text in row columnar matrix format.
STEP-3: Now read the keyword depending on the number of columns of the plain text.
STEP-4: Arrange the characters of the keyword in sorted order and the corresponding
columns of the plain text.

STEP-5: Read the characters row wise or column wise in the former order to get the
cipher text.

16
Information Security (3170720)

Program:
// C++ program to illustrate Rail Fence Cipher
// Encryption and Decryption
#include <bits/stdc++.h>
using namespace std;

// function to encrypt a message


string encryptRailFence(string text, int key) {
// create the matrix to cipher plain text
// key = rows , length(text) = columns
char rail[key][(text.length())];

// filling the rail matrix to distinguish filled


// spaces from blank ones
for (int i = 0; i < key; i++)
for (int j = 0; j < text.length(); j++)
rail[i][j] = '\n';

// to find the direction


bool dir_down = false;
int row = 0, col = 0;

for (int i = 0; i < text.length(); i++) {


// check the direction of flow
// reverse the direction if we've just
// filled the top or bottom rail
if (row == 0 || row == key - 1)
dir_down = !dir_down;

// fill the corresponding alphabet


rail[row][col++] = text[i];

// find the next row using direction flag


dir_down ? row++ : row--;
}

// now we can construct the cipher using the rail matrix


string result;
for (int i = 0; i < key; i++)
for (int j = 0; j < text.length(); j++)
if (rail[i][j] != '\n')
result.push_back(rail[i][j]);

return result;
}

// This function receives cipher-text and key


// and returns the original text after decryption
string decryptRailFence(string cipher, int key) {
// create the matrix to cipher plain text
// key = rows , length(text) = columns
char rail[key][cipher.length()];

// filling the rail matrix to distinguish filled


// spaces from blank ones
for (int i = 0; i < key; i++)
for (int j = 0; j < cipher.length(); j++)
rail[i][j] = '\n';

// to find the direction


17
Information Security (3170720)

bool dir_down;

int row = 0, col = 0;

// mark the places with '*'


for (int i = 0; i < cipher.length(); i++) {
// check the direction of flow
if (row == 0)
dir_down = true;
if (row == key - 1)
dir_down = false;

// place the marker


rail[row][col++] = '*';

// find the next row using direction flag


dir_down ? row++ : row--;
}

// now we can construct the fill the rail matrix


int index = 0;
for (int i = 0; i < key; i++)
for (int j = 0; j < cipher.length(); j++)
if (rail[i][j] == '*' && index < cipher.length())
rail[i][j] = cipher[index++];

// now read the matrix in zig-zag manner to construct


// the resultant text
string result;

row = 0, col = 0;
for (int i = 0; i < cipher.length(); i++) {
// check the direction of flow
if (row == 0)
dir_down = true;
if (row == key - 1)
dir_down = false;

// place the marker


if (rail[row][col] != '*')
result.push_back(rail[row][col++]);

// find the next row using direction flag


dir_down ? row++ : row--;
}
return result;
}

// driver program to check the above functions


int main() {
string plainText = "defend the east wall";
int fences = 3;
string encrypted = encryptRailFence(plainText, fences);
string decrypted = decryptRailFence(encrypted, fences);

cout << "Plain text : " << plainText << endl;


cout << "Encrypted : " << encrypted << endl;
cout << "Decrypted : " << decrypted << endl;

return 0;
18
Information Security (3170720)

}
Output:

Conclusion:
The Rail Fence algorithm is a simple cryptography algorithm. However, it is not secure. The key is
how many rows is implemented. It can be guessed by making a brute-force attack

Quiz:

1. Encryption in Rail fence cipher is done using _____________


a) by arranging the letters in a zig zag fashion in a table
b) by randomly arranging letters
c) by arranging letters in vigenere table
d) by swapping adjacent letters

2. Rail fence cipher is more secure than one time pad cipher? True/False
True

Suggested Reference:
1. https://crypto.interactive-maths.com/rail-fence-cipher.html

References used by the students:

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

19
Information Security (3170720)

Experiment No: 6
Implementation of Simple DES
Date:
Relevant CO: Implement and analyze various symmetric key cryptography algorithms
and their application in different context

Objectives: (a) to understand working fundamental of DES Algorithm


(b) to carry out Implementation of DES encryption-decryption.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
DES is a symmetric encryption system that uses 64-bit blocks, 8 bits of which areused
for parity checks. The key therefore has a "useful" length of 56 bits, which means thatonly
56 bits are actually used in the algorithm. The algorithm involves carrying out combinations,
substitutions and permutations between the text to be encrypted and the key, while making sure
the operations can be performed in both directions. The key is ciphered on64 bits and made of
16 blocks of 4 bits, generally denoted k1 to k16. Given that "only" 56 bits are actually used for
encrypting, there can be 256 different keys.

The main parts of the algorithm are as follows:


Ø Fractioning of the text into 64-bit blocks
Ø Initial permutation of blocks
Ø Breakdown of the blocks into two parts: left and right, named L and R
Ø Permutation and substitution steps repeated 16 times
Ø Re-joining of the left and right parts then inverse initial permutation.

Example:

20
Information Security (3170720)

Algorithm:

STEP-1: Read the 64-bit plain text.


STEP-2: Split it into two 32-bit blocks and store it in two different arrays.
STEP-3: Perform XOR operation between these two arrays.
STEP-4: The output obtained is stored as the second 32-bit sequence and the original
second 32-bit sequence forms the first part.

STEP-5: Thus the encrypted 64-bit cipher text is obtained in this way. Repeat the same
process for the remaining plain text characters.

Program:

#include <cmath>
#include <iostream>
#include <string>
using namespace std;
string round_keys[16];
string pt;
string convertDecimalToBinary(int decimal) {
string binary;
while (decimal != 0) {
binary = (decimal % 2 == 0 ? "0" : "1") + binary;
decimal = decimal / 2;
}
while (binary.length() < 4) {
binary = "0" + binary;
}
return binary;
}
int convertBinaryToDecimal(string binary) {
int decimal = 0;
int counter = 0;
int size = binary.length();
for (int i = size - 1; i >= 0; i--) {
if (binary[i] == '1') {
decimal += pow(2, counter);
}
counter++;
}
return decimal;
}
string shift_left_once(string key_chunk) {
string shifted = "";
for (int i = 1; i < 28; i++) {
shifted += key_chunk[i];
}
shifted += key_chunk[0];
return shifted;
}
string shift_left_twice(string key_chunk) {
21
Information Security (3170720)

string shifted = "";


for (int i = 0; i < 2; i++) {
for (int j = 1; j < 28; j++) {
shifted += key_chunk[j];
}
shifted += key_chunk[0];
key_chunk = shifted;
shifted = "";
}
return key_chunk;
}
string Xor(string a, string b) {
string result = "";
int size = b.size();
for (int i = 0; i < size; i++) {
if (a[i] != b[i]) {
result += "1";
} else {
result += "0";
}
}
return result;
}
void generate_keys(string key) {
int pc1[56] = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4};
int pc2[48] = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32};
string perm_key = "";
for (int i = 0; i < 56; i++) {
perm_key += key[pc1[i] - 1];
}
string left = perm_key.substr(0, 28);
string right = perm_key.substr(28, 28);
for (int i = 0; i < 16; i++) {
if (i == 0 || i == 1 || i == 8 || i == 15) {
left = shift_left_once(left);
right = shift_left_once(right);
} else {
left = shift_left_twice(left);
right = shift_left_twice(right);
}
string combined_key = left + right;
string round_key = "";
for (int i = 0; i < 48; i++) {
round_key += combined_key[pc2[i] - 1];
}
round_keys[i] = round_key;
}
}
string DES() {
22
Information Security (3170720)

int initial_permutation[64] = {
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7};
int expansion_table[48] = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1};
int substition_boxes[8][4][16] = {
{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13},
{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9},
{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12},
{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14},
{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3},
{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13},
{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12},
{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}};
int permutation_tab[32] = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23,
26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27,
3, 9, 19, 13, 30, 6, 22, 11, 4, 25};
int inverse_permutation[64] = {
40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25};
string perm = "";
for (int i = 0; i < 64; i++) {
perm += pt[initial_permutation[i] - 1];
}
string left = perm.substr(0, 32);
23
Information Security (3170720)

string right = perm.substr(32, 32);


for (int i = 0; i < 16; i++) {
string right_expanded = "";
for (int i = 0; i < 48; i++) {
right_expanded += right[expansion_table[i] - 1];
};
string xored = Xor(round_keys[i], right_expanded);
string res = "";
for (int i = 0; i < 8; i++) {
string row1 = xored.substr(i * 6, 1) + xored.substr(i * 6 + 5, 1);
int row = convertBinaryToDecimal(row1);
string col1 = xored.substr(i * 6 + 1, 1) + xored.substr(i * 6 + 2, 1) +
xored.substr(i * 6 + 3, 1) + xored.substr(i * 6 + 4, 1);
;
int col = convertBinaryToDecimal(col1);
int val = substition_boxes[i][row][col];
res += convertDecimalToBinary(val);
}
string perm2 = "";
for (int i = 0; i < 32; i++) {
perm2 += res[permutation_tab[i] - 1];
}
xored = Xor(perm2, left);
left = xored;
if (i < 15) {
string temp = right;
right = xored;
left = temp;
}
}
string combined_text = left + right;
string ciphertext = "";
for (int i = 0; i < 64; i++) {
ciphertext += combined_text[inverse_permutation[i] - 1];
}
return ciphertext;
}
int main() {
string key =
"1010101010111011000010010001100000100111001101101100110011011101";
pt = "1010101111001101111001101010101111001101000100110010010100110110";
generate_keys(key);
cout << "Plain text: " << pt << endl;
string ct = DES();
cout << "Ciphertext: " << ct << endl;
}

Output:

24
Information Security (3170720)

Conclusion:
DES is a symmetric block cipher that can be used to encrypt 64-bits of plaintext into 64-bits of
ciphertext. The algorithm is the same for the process of encryption as well as decryption. The only
difference is that the decryption procedure is the opposite of the encryption procedure

Quiz:

1. DES works on 64 bits size of blocks.

2. How many steps DES consists?


Steps in DES :
1. Key transformation
2. Expansion permutation
3. S-Box permutation
4. P-Box permutation
5. XOR and swap

Suggested Reference:
1. https://www.tutorialspoint.com/cryptography/data_encryption_standard.htm

References used by the students:

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

25
Information Security (3170720)

Experiment No: 7
Implementation of AES
Date:
Relevant CO: Implement and analyze various symmetric key cryptography algorithms
and their application in different context

Objectives: (a) to understand working fundamental of AES Algorithm


(b) to carry out Implementation of AES encryption-decryption.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
AES is a symmetric encryption system that uses 128 bit blocks, The key length is
128/192/256. The algorithm involves carrying out combinations, substitutions and permutations
between the text to be encrypted and the key, while making sure the operations can be performed
in both directions.
The main parts of the algorithm are as follows:
• AES is a block cipher.
• The key size can be 128/192/256 bits.
• Encrypts data in blocks of 128 bits each
.

Example:

Algorithm:

26
Information Security (3170720)

STEP-1:Derive the set of round keys from the cipher key.


STEP-2:Initialize the state array with the block data (plaintext).
STEP-3:Add the initial round key to the starting state array.
STEP-4:Perform nine rounds of state manipulation.
STEP-5:Perform the tenth and final round of state manipulation.
STEP-6:Copy the final state array out as the encrypted data (ciphertext).

Program:

/* encrypt.cpp
* Performs encryption using AES 128-bit
* @author Cecelia Wisniewska
*/

#include <cstring>
#include <fstream>
#include <iostream>
#include <sstream>

using namespace std;

// Encryption: Forward Rijndael S-box


unsigned char s[256] = {
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26,
0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED,
0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC,
0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D,
0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11,
0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
0xB0, 0x54, 0xBB, 0x16};

// Encryption: Multiply by 2 for MixColumns


unsigned char mul2[] = {
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16,
0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46,
27
Information Security (3170720)

0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76,
0x78, 0x7a, 0x7c, 0x7e, 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e,
0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa4, 0xa6,
0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6,
0xd8, 0xda, 0xdc, 0xde, 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee,
0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe, 0x1b, 0x19, 0x1f, 0x1d,
0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d,
0x23, 0x21, 0x27, 0x25, 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55,
0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45, 0x7b, 0x79, 0x7f, 0x7d,
0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d,
0x83, 0x81, 0x87, 0x85, 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5,
0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5, 0xdb, 0xd9, 0xdf, 0xdd,
0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed,
0xe3, 0xe1, 0xe7, 0xe5};

// Encryption: Multiply by 3 for MixColumns


unsigned char mul3[] = {
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d,
0x14, 0x17, 0x12, 0x11, 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39,
0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21, 0x60, 0x63, 0x66, 0x65,
0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d,
0x44, 0x47, 0x42, 0x41, 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9,
0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1, 0xf0, 0xf3, 0xf6, 0xf5,
0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd,
0xb4, 0xb7, 0xb2, 0xb1, 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99,
0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81, 0x9b, 0x98, 0x9d, 0x9e,
0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6,
0xbf, 0xbc, 0xb9, 0xba, 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2,
0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea, 0xcb, 0xc8, 0xcd, 0xce,
0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46,
0x4f, 0x4c, 0x49, 0x4a, 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62,
0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a, 0x3b, 0x38, 0x3d, 0x3e,
0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16,
0x1f, 0x1c, 0x19, 0x1a};

// Used in KeyExpansion
unsigned char rcon[256] = {
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a,
0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6,
0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72,
0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc,
28
Information Security (3170720)

0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10,
0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e,
0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5,
0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94,
0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb, 0x8d, 0x01, 0x02,
0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d,
0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a, 0xd4, 0xb3, 0x7d,
0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd, 0x61, 0xc2, 0x9f,
0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a, 0x74, 0xe8, 0xcb,
0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35, 0x6a,
0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91, 0x39, 0x72, 0xe4, 0xd3, 0xbd,
0x61, 0xc2, 0x9f, 0x25, 0x4a, 0x94, 0x33, 0x66, 0xcc, 0x83, 0x1d, 0x3a,
0x74, 0xe8, 0xcb, 0x8d};

// Decryption: Inverse Rijndael S-box


unsigned char inv_s[256] = {
0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38, 0xBF, 0x40, 0xA3, 0x9E,
0x81, 0xF3, 0xD7, 0xFB, 0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB, 0x54, 0x7B, 0x94, 0x32,
0xA6, 0xC2, 0x23, 0x3D, 0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2, 0x76, 0x5B, 0xA2, 0x49,
0x6D, 0x8B, 0xD1, 0x25, 0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92, 0x6C, 0x70, 0x48, 0x50,
0xFD, 0xED, 0xB9, 0xDA, 0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A, 0xF7, 0xE4, 0x58, 0x05,
0xB8, 0xB3, 0x45, 0x06, 0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B, 0x3A, 0x91, 0x11, 0x41,
0x4F, 0x67, 0xDC, 0xEA, 0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85, 0xE2, 0xF9, 0x37, 0xE8,
0x1C, 0x75, 0xDF, 0x6E, 0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B, 0xFC, 0x56, 0x3E, 0x4B,
0xC6, 0xD2, 0x79, 0x20, 0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31, 0xB1, 0x12, 0x10, 0x59,
0x27, 0x80, 0xEC, 0x5F, 0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF, 0xA0, 0xE0, 0x3B, 0x4D,
0xAE, 0x2A, 0xF5, 0xB0, 0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26, 0xE1, 0x69, 0x14, 0x63,
0x55, 0x21, 0x0C, 0x7D};

/* Serves as the initial round during encryption


* AddRoundKey is simply an XOR of a 128-bit block with the 128-bit key.
*/
void AddRoundKey(unsigned char *state, unsigned char *roundKey) {
for (int i = 0; i < 16; i++) {
state[i] ^= roundKey[i];
}
}

/* Perform substitution to each of the 16 bytes


* Uses S-box as lookup table
*/
void SubBytes(unsigned char *state) {
for (int i = 0; i < 16; i++) {
state[i] = s[state[i]];
29
Information Security (3170720)

}
}

// Shift left, adds diffusion


void ShiftRows(unsigned char *state) {
unsigned char tmp[16];

/* Column 1 */
tmp[0] = state[0];
tmp[1] = state[5];
tmp[2] = state[10];
tmp[3] = state[15];

/* Column 2 */
tmp[4] = state[4];
tmp[5] = state[9];
tmp[6] = state[14];
tmp[7] = state[3];

/* Column 3 */
tmp[8] = state[8];
tmp[9] = state[13];
tmp[10] = state[2];
tmp[11] = state[7];

/* Column 4 */
tmp[12] = state[12];
tmp[13] = state[1];
tmp[14] = state[6];
tmp[15] = state[11];

for (int i = 0; i < 16; i++) {


state[i] = tmp[i];
}
}

/* MixColumns uses mul2, mul3 look-up tables


* Source of diffusion
*/
void MixColumns(unsigned char *state) {
unsigned char tmp[16];

tmp[0] = (unsigned char)mul2[state[0]] ^ mul3[state[1]] ^ state[2] ^ state[3];


tmp[1] = (unsigned char)state[0] ^ mul2[state[1]] ^ mul3[state[2]] ^ state[3];
tmp[2] = (unsigned char)state[0] ^ state[1] ^ mul2[state[2]] ^ mul3[state[3]];
tmp[3] = (unsigned char)mul3[state[0]] ^ state[1] ^ state[2] ^ mul2[state[3]];

tmp[4] = (unsigned char)mul2[state[4]] ^ mul3[state[5]] ^ state[6] ^ state[7];


tmp[5] = (unsigned char)state[4] ^ mul2[state[5]] ^ mul3[state[6]] ^ state[7];
tmp[6] = (unsigned char)state[4] ^ state[5] ^ mul2[state[6]] ^ mul3[state[7]];
tmp[7] = (unsigned char)mul3[state[4]] ^ state[5] ^ state[6] ^ mul2[state[7]];

tmp[8] =
(unsigned char)mul2[state[8]] ^ mul3[state[9]] ^ state[10] ^ state[11];
tmp[9] =
30
Information Security (3170720)

(unsigned char)state[8] ^ mul2[state[9]] ^ mul3[state[10]] ^ state[11];


tmp[10] =
(unsigned char)state[8] ^ state[9] ^ mul2[state[10]] ^ mul3[state[11]];
tmp[11] =
(unsigned char)mul3[state[8]] ^ state[9] ^ state[10] ^ mul2[state[11]];

tmp[12] =
(unsigned char)mul2[state[12]] ^ mul3[state[13]] ^ state[14] ^ state[15];
tmp[13] =
(unsigned char)state[12] ^ mul2[state[13]] ^ mul3[state[14]] ^ state[15];
tmp[14] =
(unsigned char)state[12] ^ state[13] ^ mul2[state[14]] ^ mul3[state[15]];
tmp[15] =
(unsigned char)mul3[state[12]] ^ state[13] ^ state[14] ^ mul2[state[15]];

for (int i = 0; i < 16; i++) {


state[i] = tmp[i];
}
}

// Auxiliary function for KeyExpansion


void KeyExpansionCore(unsigned char *in, unsigned char i) {
// Rotate left by one byte: shift left
unsigned char t = in[0];
in[0] = in[1];
in[1] = in[2];
in[2] = in[3];
in[3] = t;

// S-box 4 bytes
in[0] = s[in[0]];
in[1] = s[in[1]];
in[2] = s[in[2]];
in[3] = s[in[3]];

// RCon
in[0] ^= rcon[i];
}

/* The main KeyExpansion function


* Generates additional keys using the original key
* Total of 11 128-bit keys generated, including the original
* Keys are stored one after the other in expandedKeys
*/
void KeyExpansion(unsigned char inputKey[16], unsigned char expandedKeys[176]) {
// The first 128 bits are the original key
for (int i = 0; i < 16; i++) {
expandedKeys[i] = inputKey[i];
}

int bytesGenerated = 16; // Bytes we've generated so far


int rconIteration = 1; // Keeps track of rcon value
unsigned char tmpCore[4]; // Temp storage for core

while (bytesGenerated < 176) {


31
Information Security (3170720)

/* Read 4 bytes for the core


* They are the previously generated 4 bytes
* Initially, these will be the final 4 bytes of the original key
*/
for (int i = 0; i < 4; i++) {
tmpCore[i] = expandedKeys[i + bytesGenerated - 4];
}

// Perform the core once for each 16 byte key


if (bytesGenerated % 16 == 0) {
KeyExpansionCore(tmpCore, rconIteration++);
}

for (unsigned char a = 0; a < 4; a++) {


expandedKeys[bytesGenerated] =
expandedKeys[bytesGenerated - 16] ^ tmpCore[a];
bytesGenerated++;
}
}
}

/* Each round operates on 128 bits at a time


* The number of rounds is defined in AESEncrypt()
*/
void Round(unsigned char *state, unsigned char *key) {
SubBytes(state);
ShiftRows(state);
MixColumns(state);
AddRoundKey(state, key);
}

// Same as Round() except it doesn't mix columns


void FinalRound(unsigned char *state, unsigned char *key) {
SubBytes(state);
ShiftRows(state);
AddRoundKey(state, key);
}

/* The AES encryption function


* Organizes the confusion and diffusion steps into one function
*/
void AESEncrypt(unsigned char *message, unsigned char *expandedKey,
unsigned char *encryptedMessage) {
unsigned char state[16]; // Stores the first 16 bytes of original message

for (int i = 0; i < 16; i++) {


state[i] = message[i];
}

int numberOfRounds = 9;

AddRoundKey(state, expandedKey); // Initial round

for (int i = 0; i < numberOfRounds; i++) {


Round(state, expandedKey + (16 * (i + 1)));
32
Information Security (3170720)

FinalRound(state, expandedKey + 160);

// Copy encrypted state to buffer


for (int i = 0; i < 16; i++) {
encryptedMessage[i] = state[i];
}
}

int main() {

cout << "=============================" << endl;


cout << " 128-bit AES Encryption Tool " << endl;
cout << "=============================" << endl;

char message[1024];

cout << "Enter the message to encrypt: ";


cin.getline(message, sizeof(message));
cout << message << endl;

// Pad message to 16 bytes


int originalLen = strlen((const char *)message);

int paddedMessageLen = originalLen;

if ((paddedMessageLen % 16) != 0) {
paddedMessageLen = (paddedMessageLen / 16 + 1) * 16;
}

unsigned char *paddedMessage = new unsigned char[paddedMessageLen];


for (int i = 0; i < paddedMessageLen; i++) {
if (i >= originalLen) {
paddedMessage[i] = 0;
} else {
paddedMessage[i] = message[i];
}
}

unsigned char *encryptedMessage = new unsigned char[paddedMessageLen];

string str;

istringstream hex_chars_stream(str);
unsigned char key[16];
int i = 0;
unsigned int c;
while (hex_chars_stream >> hex >> c) {
key[i] = c;
i++;
}

unsigned char expandedKey[176];

33
Information Security (3170720)

KeyExpansion(key, expandedKey);

for (int i = 0; i < paddedMessageLen; i += 16) {


AESEncrypt(paddedMessage + i, expandedKey, encryptedMessage + i);
}

cout << "Encrypted message in hex:" << endl;


for (int i = 0; i < paddedMessageLen; i++) {
cout << hex << (int)encryptedMessage[i];
cout << " ";
}

cout << endl;


// Free memory
delete[] paddedMessage;
delete[] encryptedMessage;

return 0;
}

Output:

Conclusion:
the AES algorithm computes much faster than RSA in execution and implementation. RSA algorithm
is reliable for key exchange management, but it's not very efficient in terms of performance and cost
factor

Quiz:

1. How many rounds does the AES-192 perform?


There are 10 rounds for 128-bit keys, 12 rounds for 192-bit keys and 14 rounds for 256-bit keys

Suggested Reference:
1. https://www.geeksforgeeks.org/advanced-encryption-standard-aes/

References used by the students:

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

34
Information Security (3170720)

Experiment No: 8
Implementation of RSA Algorithm
Date:
Relevant CO: Compare public key cryptography with private key cryptography and
Implement various asymmetric key cryptography algorithms

Objectives: (a) to understand working fundamental of RSA Algorithm


(b) to carry out Implementation of RSA encryption-decryption.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
RSA is an algorithm used by modern computers to encrypt and decrypt messages. It
is an asymmetric cryptographic algorithm. Asymmetric means that there are two different keys.
This is also called public key cryptography, because one of them can be given toeveryone. A
basic principle behind RSA is the observation that it is practical to find threevery large positive
integers e, d and n such that with modular exponentiation for all integer m:

(me)d = m (mod n)

The public key is represented by the integers n and e; and, the private key, by the integer d. m represents
the message. RSA involves a public key and a private key. The public key can be known by everyone
and is used for encrypting messages. The intention is that messages encrypted with the public key can
only be decrypted in a reasonable amount of time using the private key.

Example:

35
Information Security (3170720)

Algorithm:

STEP-1: Select two co-prime numbers as p and q.


STEP-2: Compute n as the product of p and q.
STEP-3: Compute (p-1)*(q-1) and store it in z.
STEP-4: Select a random prime number e that is less than that of z.
STEP-5: Compute the private key, d as e * mod-1(z).
STEP-6: The cipher text is computed as messagee * mod n.STEP-7: Decryption is done as
cipherdmod n.

Program:

// C program for RSA asymmetric cryptographic


// algorithm. For demonstration values are
// relatively small compared to practical
// application
#include <bits/stdc++.h>
using namespace std;

// Returns gcd of a and b


int gcd(int a, int h) {
int temp;
while (1) {
temp = a % h;
if (temp == 0)
return h;
a = h;
h = temp;
}
}

// Code to demonstrate RSA algorithm


int main() {
// Two random prime numbers
int p = 3;
int q = 7;

// First part of public key:


int n = p * q;

// Finding other part of public key.


// e stands for encrypt
int e = 2;
int phi = (p - 1) * (q - 1);
while (e < phi) {
// e must be co-prime to phi and
// smaller than phi.
if (gcd(e, phi) == 1)
break;
else

36
Information Security (3170720)

e++;
}

// Private key (d stands for decrypt)


// choosing d such that it satisfies
// d*e = 1 + k * totient
int k = 2; // A constant value
double d = (1 + (double)(k * phi)) / e;

// Message to be encrypted
double msg = 12;

printf("Message data = %lf", msg);

// Encryption c = (msg ^ e) % n
double c = pow(msg, e);
c = fmod(c, n);
printf("\nEncrypted data = %lf", c);

// Decryption m = (c ^ d) % n
double m = pow(c, d);
m = fmod(m, n);
printf("\nOriginal Message Sent = %lf\n", m);

return 0;
}

Output:

Conclusion:
RSA is a type of asymmetric encryption, which uses two different but linked keys. In RSA
cryptography, both the public and the private keys can encrypt a message. The opposite key from the
one used to encrypt a message is used to decrypt it.

37
Information Security (3170720)

Quiz:

1. if p=7, q=1 and e=13 than what will be value of d?


Suggested Reference:
1. https://www.cemc.uwaterloo.ca/resources/real-world/RSA.pdf

References used by the students:

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

38
Information Security (3170720)

Experiment No: 9
Implementation of Diffie–Hellman Key Exchange
Date:
Relevant CO: Compare public key cryptography with private key cryptography and
Implement various asymmetric key cryptography algorithms

Objectives: (a) to understand working fundamental of Diffie–Hellman Key Exchange


(b) to carry out Implementation of Diffie–Hellman Key Exchange algorithm.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
Diffie–Hellman Key Exchange establishes a shared secret between two parties that can be used for
secret communication for exchanging data over a public network. It is primarily used as a method of
exchanging cryptography keys for use in symmetric encryption algorithms like AES. The algorithm in
itself is very simple. The process begins by having the two parties, Alice and Bob. Let's assume that
Alice wants to establish a shared secret with Bob.

Example:

Algorithm:

STEP-1: Both Alice and Bob shares the same public keys g and p.
STEP-2: Alice selects a random public key a.
STEP-3: Alice computes his secret key A as ga mod p.
STEP-4: Then Alice sends A to Bob.
STEP-5: Similarly Bob also selects a public key b and computes his secret key as Band
sends the same back to Alice.
STEP-6: Now both of them compute their common secret key as the other one’s secretkey
power of a mod p.
39
Information Security (3170720)

Program:

/* This program calculates the Key for two persons


using the Diffie-Hellman Key exchange algorithm using C++ */
#include <cmath>
#include <iostream>

using namespace std;

// Power function to return value of a ^ b mod P


long long int power(long long int a, long long int b, long long int P) {
if (b == 1)
return a;

else
return (((long long int)pow(a, b)) % P);
}

// Driver program
int main() {
long long int P, G, x, a, y, b, ka, kb;

// Both the persons will be agreed upon the


// public keys G and P
P = 23; // A prime number P is taken
cout << "The value of P : " << P << endl;

G = 9; // A primitive root for P, G is taken


cout << "The value of G : " << G << endl;

// Alice will choose the private key a


a = 4; // a is the chosen private key
cout << "The private key a for Alice : " << a << endl;

x = power(G, a, P); // gets the generated key

// Bob will choose the private key b


b = 3; // b is the chosen private key
cout << "The private key b for Bob : " << b << endl;

y = power(G, b, P); // gets the generated key

// Generating the secret key after the exchange


// of keys
ka = power(y, a, P); // Secret key for Alice
kb = power(x, b, P); // Secret key for Bob
cout << "Secret key for the Alice is : " << ka << endl;

cout << "Secret key for the Bob is : " << kb << endl;

return 0;
}

40
Information Security (3170720)

Output:

Conclusion:
With this algorithm of key exchange we can generate and share keys through an insecure channel,
securely without compromising and security and make use of symmetric cipher techniques

Quiz:

1. Suppose that two parties A and B wish to set up a common secret key (D-H key) between
themselves using the Diffie Hellman key exchange technique. They agree on 7 as the modulus and
3 as the primitive root. Party A chooses 2 and party B chooses 5 as their respective secrets. Their
D-H key is ?

Suggested Reference:
1. https://www.techtarget.com/searchsecurity/definition/Diffie-Hellman-key-exchange

References used by the students:

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

41
Information Security (3170720)

Experiment No: 10
Implementation of MD-5
Date:
Relevant CO: Explore the concept of hashing and implement various hashing
algorithms for message integrity

Objectives: (a) to understand working fundamental of MD5


(b) to carry out Implementation of MD5 techniques.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
MD5 processes a varia ble-length message into a fixed-length output of 128 bits. The
input message is broken up into chunks of 512-bit blocks. The message is pa dded so that its
e
length is divisible by 512. The padding works as follows: first a single bit, 1, is appended to
the end of the message. This is followed by as many zeros as are required to bring the lengthof
the message up to 64 bits less than a multiple of 512. The remaining bits are filled up with 64
bits representing the length of the original message, modulo 264.The main operates on a 128-
bit state, divided into four 32-bit words, denoted A, B, C, and D. These areinitialized to certain
fixed constants. The main algorithm then uses each 512-bit message block in turn to modify
the stat ..

Example:

42
Information Security (3170720)

Algorithm:

STEP-1: Read the 128-bit plain text.


STEP-2: Divide into four blocks of 32-bits named as A, B, C and D.

STEP-3: Compute the functions f, g, h and i with operations such as, rotations,
permutations, etc,.
STEP-4: The output of these functions are combined together as F and performed
circular shifting and then given to key round.

STEP-5: Finally, right shift of ‘s’ times are performed and the results are combinedtogether to
produce the final output.

Program:

/*
* Derived from the RSA Data Security, Inc. MD5 Message-Digest Algorithm
* and modified slightly to be functionally identical but condensed into control structures.
*/

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

typedef struct{
uint64_t size; // Size of input in bytes
uint32_t buffer[4]; // Current accumulation of hash
uint8_t input[64]; // Input to be used in the next step
uint8_t digest[16]; // Result of algorithm
}MD5Context;

void md5Init(MD5Context *ctx);


void md5Update(MD5Context *ctx, uint8_t *input, size_t input_len);
void md5Finalize(MD5Context *ctx);
void md5Step(uint32_t *buffer, uint32_t *input);

void md5String(char *input, uint8_t *result);


void md5File(FILE *file, uint8_t *result);

/*
* Constants defined by the MD5 algorithm
*/
#define A 0x67452301
#define B 0xefcdab89
#define C 0x98badcfe
#define D 0x10325476

static uint32_t S[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
43
Information Security (3170720)

static uint32_t K[] = {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,


0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};

/*
* Padding used to make the size (in bits) of the input congruent to 448 mod 512
*/
static uint8_t PADDING[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

/*
* Bit-manipulation functions defined by the MD5 algorithm
*/
#define F(X, Y, Z) ((X & Y) | (~X & Z))
#define G(X, Y, Z) ((X & Z) | (Y & ~Z))
#define H(X, Y, Z) (X ^ Y ^ Z)
#define I(X, Y, Z) (Y ^ (X | ~Z))

/*
* Rotates a 32-bit word left by n bits
*/
uint32_t rotateLeft(uint32_t x, uint32_t n){
return (x << n) | (x >> (32 - n));
}

/*
* Initialize a context
*/
void md5Init(MD5Context *ctx){
ctx->size = (uint64_t)0;

ctx->buffer[0] = (uint32_t)A;
ctx->buffer[1] = (uint32_t)B;
ctx->buffer[2] = (uint32_t)C;
ctx->buffer[3] = (uint32_t)D;
}

/*
* Add some amount of input to the context

44
Information Security (3170720)

*
* If the input fills out a block of 512 bits, apply the algorithm (md5Step)
* and save the result in the buffer. Also updates the overall size.
*/
void md5Update(MD5Context *ctx, uint8_t *input_buffer, size_t input_len){
uint32_t input[16];
unsigned int offset = ctx->size % 64;
ctx->size += (uint64_t)input_len;

// Copy each byte in input_buffer into the next space in our context input
for(unsigned int i = 0; i < input_len; ++i){
ctx->input[offset++] = (uint8_t)*(input_buffer + i);

// If we've filled our context input, copy it into our local array input
// then reset the offset to 0 and fill in a new buffer.
// Every time we fill out a chunk, we run it through the algorithm
// to enable some back and forth between cpu and i/o
if(offset % 64 == 0){
for(unsigned int j = 0; j < 16; ++j){
// Convert to little-endian
// The local variable `input` our 512-bit chunk separated into 32-bit words
// we can use in calculations
input[j] = (uint32_t)(ctx->input[(j * 4) + 3]) << 24 |
(uint32_t)(ctx->input[(j * 4) + 2]) << 16 |
(uint32_t)(ctx->input[(j * 4) + 1]) << 8 |
(uint32_t)(ctx->input[(j * 4)]);
}
md5Step(ctx->buffer, input);
offset = 0;
}
}
}

/*
* Pad the current input to get to 448 bytes, append the size in bits to the very end,
* and save the result of the final iteration into digest.
*/
void md5Finalize(MD5Context *ctx){
uint32_t input[16];
unsigned int offset = ctx->size % 64;
unsigned int padding_length = offset < 56 ? 56 - offset : (56 + 64) - offset;

// Fill in the padding and undo the changes to size that resulted from the update
md5Update(ctx, PADDING, padding_length);
ctx->size -= (uint64_t)padding_length;

// Do a final update (internal to this function)


// Last two 32-bit words are the two halves of the size (converted from bytes to bits)
for(unsigned int j = 0; j < 14; ++j){
input[j] = (uint32_t)(ctx->input[(j * 4) + 3]) << 24 |
(uint32_t)(ctx->input[(j * 4) + 2]) << 16 |
(uint32_t)(ctx->input[(j * 4) + 1]) << 8 |
(uint32_t)(ctx->input[(j * 4)]);
}
input[14] = (uint32_t)(ctx->size * 8);
input[15] = (uint32_t)((ctx->size * 8) >> 32);

md5Step(ctx->buffer, input);

// Move the result into digest (convert from little-endian)

45
Information Security (3170720)

for(unsigned int i = 0; i < 4; ++i){


ctx->digest[(i * 4) + 0] = (uint8_t)((ctx->buffer[i] & 0x000000FF));
ctx->digest[(i * 4) + 1] = (uint8_t)((ctx->buffer[i] & 0x0000FF00) >> 8);
ctx->digest[(i * 4) + 2] = (uint8_t)((ctx->buffer[i] & 0x00FF0000) >> 16);
ctx->digest[(i * 4) + 3] = (uint8_t)((ctx->buffer[i] & 0xFF000000) >> 24);
}
}

/*
* Step on 512 bits of input with the main MD5 algorithm.
*/
void md5Step(uint32_t *buffer, uint32_t *input){
uint32_t AA = buffer[0];
uint32_t BB = buffer[1];
uint32_t CC = buffer[2];
uint32_t DD = buffer[3];

uint32_t E;

unsigned int j;

for(unsigned int i = 0; i < 64; ++i){


switch(i / 16){
case 0:
E = F(BB, CC, DD);
j = i;
break;
case 1:
E = G(BB, CC, DD);
j = ((i * 5) + 1) % 16;
break;
case 2:
E = H(BB, CC, DD);
j = ((i * 3) + 5) % 16;
break;
default:
E = I(BB, CC, DD);
j = (i * 7) % 16;
break;
}

uint32_t temp = DD;


DD = CC;
CC = BB;
BB = BB + rotateLeft(AA + E + K[i] + input[j], S[i]);
AA = temp;
}

buffer[0] += AA;
buffer[1] += BB;
buffer[2] += CC;
buffer[3] += DD;
}

/*
* Functions that run the algorithm on the provided input and put the digest into result.
* result should be able to store 16 bytes.
*/
void md5String(char *input, uint8_t *result){
MD5Context ctx;

46
Information Security (3170720)

md5Init(&ctx);
md5Update(&ctx, (uint8_t *)input, strlen(input));
md5Finalize(&ctx);

memcpy(result, ctx.digest, 16);


}

void printArrayBuffer(uint8_t *input, int size){


for(int i = 0; i < size; i++){
printf("%X",input[i]);
}
printf("\n");
}

int main(void){
char *plaintext = "helloworld";
uint8_t result[16];
md5String(plaintext, result);
printf("MD5 hash of %s : ", plaintext);
printArrayBuffer(result, 16);
return 0;
}

Output:

Conclusion:
The MD5 hashing technique relies on a complex mathematical formula to compute the plain text cipher
hash value. As we've seen, the MD5 algorithm divides the plain text into blocks of varying sizes and
then performs various operations on them.

Quiz:

1. MD5 produce hash value of _16_ bits.

Suggested Reference:
1. https://www.simplilearn.com/tutorials/cyber-security-tutorial/md5-algorithm

References used by the students:

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

47
Information Security (3170720)

Experiment No: 11
Implementation of SHA-1
Date:
Relevant CO: Explore the concept of hashing and implement various hashing
algorithms for message integrity

Objectives: (a) to understand working fundamental of SHA-1


(b) to carry out Implementation of SHA-1.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
In cryptography, SHA-1 (Secure Hash Algorithm 1) is a cryptographic hash function. SHA-1
produces a 160-bit hash value known as a message digest. The waythis algorithm
works is that for a message of size < 264 bits it computes a 160-bit condensed output called a message
digest. The SHA-1 algorithm is designed so that it is practicallyinfeasible to find two input messages
that hash to the same output message. A hash function such as SHA-1 is used to calculate an
alphanumeric string that serves as the cryptographic representation of a file or a piece of data. This is
called a digest and can serve as a digital signature. It is supposed to be unique and non-reversible.

Example:

Algorithm:

STEP-1: Read the 256-bit key values.


STEP-2: Divide into five equal-sized blocks named A, B, C, D and E.
STEP-3: The blocks B, C and D are passed to the function F.
STEP-4: The resultant value is permuted with block E.
48
Information Security (3170720)

STEP-5: The block A is shifted right by ‘s’ times and permuted with the result of step-4.

STEP-6: Then it is permuted with a weight value and then with some other key pair and
taken as the first block.
STEP-7: Block A is taken as the second block and the block B is shifted by ‘s’ times and
taken as the third block.

STEP-8: The blocks C and D are taken as the block D and E for the final output.

Program:
#include <cstdint>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

class SHA1 {
public:
SHA1();
void update(const std::string &s);
void update(std::istream &is);
std::string final();
static std::string from_file(const std::string &filename);

private:
uint32_t digest[5];
std::string buffer;
uint64_t transforms;
};

static const size_t BLOCK_INTS =


16; /* number of 32bit integers per SHA1 block */
static const size_t BLOCK_BYTES = BLOCK_INTS * 4;

inline static void reset(uint32_t digest[], std::string &buffer,


uint64_t &transforms) {
/* SHA1 initialization constants */
digest[0] = 0x67452301;
digest[1] = 0xefcdab89;
digest[2] = 0x98badcfe;
digest[3] = 0x10325476;
digest[4] = 0xc3d2e1f0;

/* Reset counters */
buffer = "";
transforms = 0;
}

inline static uint32_t rol(const uint32_t value, const size_t bits) {


return (value << bits) | (value >> (32 - bits));
}

49
Information Security (3170720)

inline static uint32_t blk(const uint32_t block[BLOCK_INTS], const size_t i) {


return rol(block[(i + 13) & 15] ^ block[(i + 8) & 15] ^ block[(i + 2) & 15] ^
block[i],
1);
}

/*
* (R0+R1), R2, R3, R4 are the different operations used in SHA1
*/

inline static void R0(const uint32_t block[BLOCK_INTS], const uint32_t v,


uint32_t &w, const uint32_t x, const uint32_t y,
uint32_t &z, const size_t i) {
z += ((w & (x ^ y)) ^ y) + block[i] + 0x5a827999 + rol(v, 5);
w = rol(w, 30);
}

inline static void R1(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w,


const uint32_t x, const uint32_t y, uint32_t &z,
const size_t i) {
block[i] = blk(block, i);
z += ((w & (x ^ y)) ^ y) + block[i] + 0x5a827999 + rol(v, 5);
w = rol(w, 30);
}

inline static void R2(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w,


const uint32_t x, const uint32_t y, uint32_t &z,
const size_t i) {
block[i] = blk(block, i);
z += (w ^ x ^ y) + block[i] + 0x6ed9eba1 + rol(v, 5);
w = rol(w, 30);
}

inline static void R3(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w,


const uint32_t x, const uint32_t y, uint32_t &z,
const size_t i) {
block[i] = blk(block, i);
z += (((w | x) & y) | (w & x)) + block[i] + 0x8f1bbcdc + rol(v, 5);
w = rol(w, 30);
}

inline static void R4(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w,


const uint32_t x, const uint32_t y, uint32_t &z,
const size_t i) {
block[i] = blk(block, i);
z += (w ^ x ^ y) + block[i] + 0xca62c1d6 + rol(v, 5);
w = rol(w, 30);
}

/*
* Hash a single 512-bit block. This is the core of the algorithm.
*/

inline static void transform(uint32_t digest[], uint32_t block[BLOCK_INTS],


uint64_t &transforms) {
50
Information Security (3170720)

/* Copy digest[] to working vars */


uint32_t a = digest[0];
uint32_t b = digest[1];
uint32_t c = digest[2];
uint32_t d = digest[3];
uint32_t e = digest[4];

/* 4 rounds of 20 operations each. Loop unrolled. */


R0(block, a, b, c, d, e, 0);
R0(block, e, a, b, c, d, 1);
R0(block, d, e, a, b, c, 2);
R0(block, c, d, e, a, b, 3);
R0(block, b, c, d, e, a, 4);
R0(block, a, b, c, d, e, 5);
R0(block, e, a, b, c, d, 6);
R0(block, d, e, a, b, c, 7);
R0(block, c, d, e, a, b, 8);
R0(block, b, c, d, e, a, 9);
R0(block, a, b, c, d, e, 10);
R0(block, e, a, b, c, d, 11);
R0(block, d, e, a, b, c, 12);
R0(block, c, d, e, a, b, 13);
R0(block, b, c, d, e, a, 14);
R0(block, a, b, c, d, e, 15);
R1(block, e, a, b, c, d, 0);
R1(block, d, e, a, b, c, 1);
R1(block, c, d, e, a, b, 2);
R1(block, b, c, d, e, a, 3);
R2(block, a, b, c, d, e, 4);
R2(block, e, a, b, c, d, 5);
R2(block, d, e, a, b, c, 6);
R2(block, c, d, e, a, b, 7);
R2(block, b, c, d, e, a, 8);
R2(block, a, b, c, d, e, 9);
R2(block, e, a, b, c, d, 10);
R2(block, d, e, a, b, c, 11);
R2(block, c, d, e, a, b, 12);
R2(block, b, c, d, e, a, 13);
R2(block, a, b, c, d, e, 14);
R2(block, e, a, b, c, d, 15);
R2(block, d, e, a, b, c, 0);
R2(block, c, d, e, a, b, 1);
R2(block, b, c, d, e, a, 2);
R2(block, a, b, c, d, e, 3);
R2(block, e, a, b, c, d, 4);
R2(block, d, e, a, b, c, 5);
R2(block, c, d, e, a, b, 6);
R2(block, b, c, d, e, a, 7);
R3(block, a, b, c, d, e, 8);
R3(block, e, a, b, c, d, 9);
R3(block, d, e, a, b, c, 10);
R3(block, c, d, e, a, b, 11);
R3(block, b, c, d, e, a, 12);
R3(block, a, b, c, d, e, 13);
R3(block, e, a, b, c, d, 14);
51
Information Security (3170720)

R3(block, d, e, a, b, c, 15);
R3(block, c, d, e, a, b, 0);
R3(block, b, c, d, e, a, 1);
R3(block, a, b, c, d, e, 2);
R3(block, e, a, b, c, d, 3);
R3(block, d, e, a, b, c, 4);
R3(block, c, d, e, a, b, 5);
R3(block, b, c, d, e, a, 6);
R3(block, a, b, c, d, e, 7);
R3(block, e, a, b, c, d, 8);
R3(block, d, e, a, b, c, 9);
R3(block, c, d, e, a, b, 10);
R3(block, b, c, d, e, a, 11);
R4(block, a, b, c, d, e, 12);
R4(block, e, a, b, c, d, 13);
R4(block, d, e, a, b, c, 14);
R4(block, c, d, e, a, b, 15);
R4(block, b, c, d, e, a, 0);
R4(block, a, b, c, d, e, 1);
R4(block, e, a, b, c, d, 2);
R4(block, d, e, a, b, c, 3);
R4(block, c, d, e, a, b, 4);
R4(block, b, c, d, e, a, 5);
R4(block, a, b, c, d, e, 6);
R4(block, e, a, b, c, d, 7);
R4(block, d, e, a, b, c, 8);
R4(block, c, d, e, a, b, 9);
R4(block, b, c, d, e, a, 10);
R4(block, a, b, c, d, e, 11);
R4(block, e, a, b, c, d, 12);
R4(block, d, e, a, b, c, 13);
R4(block, c, d, e, a, b, 14);
R4(block, b, c, d, e, a, 15);

/* Add the working vars back into digest[] */


digest[0] += a;
digest[1] += b;
digest[2] += c;
digest[3] += d;
digest[4] += e;

/* Count the number of transformations */


transforms++;
}

inline static void buffer_to_block(const std::string &buffer,


uint32_t block[BLOCK_INTS]) {
/* Convert the std::string (byte buffer) to a uint32_t array (MSB) */
for (size_t i = 0; i < BLOCK_INTS; i++) {
block[i] = (buffer[4 * i + 3] & 0xff) | (buffer[4 * i + 2] & 0xff) << 8 |
(buffer[4 * i + 1] & 0xff) << 16 |
(buffer[4 * i + 0] & 0xff) << 24;
}
}

52
Information Security (3170720)

inline SHA1::SHA1() { reset(digest, buffer, transforms); }

inline void SHA1::update(const std::string &s) {


std::istringstream is(s);
update(is);
}

inline void SHA1::update(std::istream &is) {


while (true) {
char sbuf[BLOCK_BYTES];
is.read(sbuf, BLOCK_BYTES - buffer.size());
buffer.append(sbuf, (std::size_t)is.gcount());
if (buffer.size() != BLOCK_BYTES) {
return;
}
uint32_t block[BLOCK_INTS];
buffer_to_block(buffer, block);
transform(digest, block, transforms);
buffer.clear();
}
}

/*
* Add padding and return the message digest.
*/

inline std::string SHA1::final() {


/* Total number of hashed bits */
uint64_t total_bits = (transforms * BLOCK_BYTES + buffer.size()) * 8;

/* Padding */
buffer += (char)0x80;
size_t orig_size = buffer.size();
while (buffer.size() < BLOCK_BYTES) {
buffer += (char)0x00;
}

uint32_t block[BLOCK_INTS];
buffer_to_block(buffer, block);

if (orig_size > BLOCK_BYTES - 8) {


transform(digest, block, transforms);
for (size_t i = 0; i < BLOCK_INTS - 2; i++) {
block[i] = 0;
}
}

/* Append total_bits, split this uint64_t into two uint32_t */


block[BLOCK_INTS - 1] = (uint32_t)total_bits;
block[BLOCK_INTS - 2] = (uint32_t)(total_bits >> 32);
transform(digest, block, transforms);

/* Hex std::string */
std::ostringstream result;
for (size_t i = 0; i < sizeof(digest) / sizeof(digest[0]); i++) {
53
Information Security (3170720)

result << std::hex << std::setfill('0') << std::setw(8);


result << digest[i];
}

/* Reset for next run */


reset(digest, buffer, transforms);

return result.str();
}

inline std::string SHA1::from_file(const std::string &filename) {


std::ifstream stream(filename.c_str(), std::ios::binary);
SHA1 checksum;
checksum.update(stream);
return checksum.final();
}

int main() {

std::string plaintext = "helloworld";

SHA1 checksum;
std::cout << std::endl;
std::cout << "Test: \t" << plaintext << std::endl;
checksum.update(plaintext);
std::cout << "Hashed: " << checksum.final() << std::endl;
return 0;
}

Output:

Conclusion:
In conclusion, SHA-1 is a widely used hash function that has been in use for several decades.
While it was once considered secure, it is now vulnerable to various attacks due to its collision
resistance. It is recommended to use stronger hash functions such as SHA-2 and SHA-3 for new
applications and systems.

Quiz:

1. What is the number of round computation steps in the SHA-256 algorithm?


64 rounds

54
Information Security (3170720)

2. SHA-1 produces a hash value of 160 bits.

Suggested Reference:
1. https://www.geeksforgeeks.org/sha-1-hash-in-java/.

References used by the students:

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

55
Information Security (3170720)

Experiment No: 12
Implementation of digital signature standard
Date:
Relevant CO: Explore and use the techniques and standards of digital signature, key
management and authentication

Objectives: (a) to understand working fundamental of digital signature standard


(b) to carry out Implementation of digital signature standard.

Equipment/Instruments: Computer System, Turbo-c/ JDK


Theory:
Digital Signature Standard (DSS) is a Federal Information Processing Standard(FIPS) which defines
algorithms that are used to generate digital signatures with the help of Secure Hash Algorithm(SHA)
for the authentication of electronic documents. DSS only provides us with the digital signature function
and not with any encryption or key exchanging stretegy.

Example:

Algorithm:

STEP-1: Key Generation.


STEP-2: Signature Generation.
STEP-3: Key Distribution.
STEP-4: Signature Verification.

56
Information Security (3170720)

Program:
#include <cstdint>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <string>

class SHA1 {
public:
SHA1();
void update(const std::string &s);
void update(std::istream &is);
std::string final();
static std::string from_file(const std::string &filename);

private:
uint32_t digest[5];
std::string buffer;
uint64_t transforms;
};

static const size_t BLOCK_INTS =


16; /* number of 32bit integers per SHA1 block */
static const size_t BLOCK_BYTES = BLOCK_INTS * 4;

inline static void reset(uint32_t digest[], std::string &buffer,


uint64_t &transforms) {
/* SHA1 initialization constants */
digest[0] = 0x67452301;
digest[1] = 0xefcdab89;
digest[2] = 0x98badcfe;
digest[3] = 0x10325476;
digest[4] = 0xc3d2e1f0;

/* Reset counters */
buffer = "";
transforms = 0;
}

inline static uint32_t rol(const uint32_t value, const size_t bits) {


return (value << bits) | (value >> (32 - bits));
}

inline static uint32_t blk(const uint32_t block[BLOCK_INTS], const size_t i) {


return rol(block[(i + 13) & 15] ^ block[(i + 8) & 15] ^ block[(i + 2) & 15] ^
block[i],
1);
}

/*
* (R0+R1), R2, R3, R4 are the different operations used in SHA1
*/

inline static void R0(const uint32_t block[BLOCK_INTS], const uint32_t v,


57
Information Security (3170720)

uint32_t &w, const uint32_t x, const uint32_t y,


uint32_t &z, const size_t i) {
z += ((w & (x ^ y)) ^ y) + block[i] + 0x5a827999 + rol(v, 5);
w = rol(w, 30);
}

inline static void R1(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w,


const uint32_t x, const uint32_t y, uint32_t &z,
const size_t i) {
block[i] = blk(block, i);
z += ((w & (x ^ y)) ^ y) + block[i] + 0x5a827999 + rol(v, 5);
w = rol(w, 30);
}

inline static void R2(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w,


const uint32_t x, const uint32_t y, uint32_t &z,
const size_t i) {
block[i] = blk(block, i);
z += (w ^ x ^ y) + block[i] + 0x6ed9eba1 + rol(v, 5);
w = rol(w, 30);
}

inline static void R3(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w,


const uint32_t x, const uint32_t y, uint32_t &z,
const size_t i) {
block[i] = blk(block, i);
z += (((w | x) & y) | (w & x)) + block[i] + 0x8f1bbcdc + rol(v, 5);
w = rol(w, 30);
}

inline static void R4(uint32_t block[BLOCK_INTS], const uint32_t v, uint32_t &w,


const uint32_t x, const uint32_t y, uint32_t &z,
const size_t i) {
block[i] = blk(block, i);
z += (w ^ x ^ y) + block[i] + 0xca62c1d6 + rol(v, 5);
w = rol(w, 30);
}

/*
* Hash a single 512-bit block. This is the core of the algorithm.
*/

inline static void transform(uint32_t digest[], uint32_t block[BLOCK_INTS],


uint64_t &transforms) {
/* Copy digest[] to working vars */
uint32_t a = digest[0];
uint32_t b = digest[1];
uint32_t c = digest[2];
uint32_t d = digest[3];
uint32_t e = digest[4];

/* 4 rounds of 20 operations each. Loop unrolled. */


R0(block, a, b, c, d, e, 0);
R0(block, e, a, b, c, d, 1);
R0(block, d, e, a, b, c, 2);
58
Information Security (3170720)

R0(block, c, d, e, a, b, 3);
R0(block, b, c, d, e, a, 4);
R0(block, a, b, c, d, e, 5);
R0(block, e, a, b, c, d, 6);
R0(block, d, e, a, b, c, 7);
R0(block, c, d, e, a, b, 8);
R0(block, b, c, d, e, a, 9);
R0(block, a, b, c, d, e, 10);
R0(block, e, a, b, c, d, 11);
R0(block, d, e, a, b, c, 12);
R0(block, c, d, e, a, b, 13);
R0(block, b, c, d, e, a, 14);
R0(block, a, b, c, d, e, 15);
R1(block, e, a, b, c, d, 0);
R1(block, d, e, a, b, c, 1);
R1(block, c, d, e, a, b, 2);
R1(block, b, c, d, e, a, 3);
R2(block, a, b, c, d, e, 4);
R2(block, e, a, b, c, d, 5);
R2(block, d, e, a, b, c, 6);
R2(block, c, d, e, a, b, 7);
R2(block, b, c, d, e, a, 8);
R2(block, a, b, c, d, e, 9);
R2(block, e, a, b, c, d, 10);
R2(block, d, e, a, b, c, 11);
R2(block, c, d, e, a, b, 12);
R2(block, b, c, d, e, a, 13);
R2(block, a, b, c, d, e, 14);
R2(block, e, a, b, c, d, 15);
R2(block, d, e, a, b, c, 0);
R2(block, c, d, e, a, b, 1);
R2(block, b, c, d, e, a, 2);
R2(block, a, b, c, d, e, 3);
R2(block, e, a, b, c, d, 4);
R2(block, d, e, a, b, c, 5);
R2(block, c, d, e, a, b, 6);
R2(block, b, c, d, e, a, 7);
R3(block, a, b, c, d, e, 8);
R3(block, e, a, b, c, d, 9);
R3(block, d, e, a, b, c, 10);
R3(block, c, d, e, a, b, 11);
R3(block, b, c, d, e, a, 12);
R3(block, a, b, c, d, e, 13);
R3(block, e, a, b, c, d, 14);
R3(block, d, e, a, b, c, 15);
R3(block, c, d, e, a, b, 0);
R3(block, b, c, d, e, a, 1);
R3(block, a, b, c, d, e, 2);
R3(block, e, a, b, c, d, 3);
R3(block, d, e, a, b, c, 4);
R3(block, c, d, e, a, b, 5);
R3(block, b, c, d, e, a, 6);
R3(block, a, b, c, d, e, 7);
R3(block, e, a, b, c, d, 8);
R3(block, d, e, a, b, c, 9);
59
Information Security (3170720)

R3(block, c, d, e, a, b, 10);
R3(block, b, c, d, e, a, 11);
R4(block, a, b, c, d, e, 12);
R4(block, e, a, b, c, d, 13);
R4(block, d, e, a, b, c, 14);
R4(block, c, d, e, a, b, 15);
R4(block, b, c, d, e, a, 0);
R4(block, a, b, c, d, e, 1);
R4(block, e, a, b, c, d, 2);
R4(block, d, e, a, b, c, 3);
R4(block, c, d, e, a, b, 4);
R4(block, b, c, d, e, a, 5);
R4(block, a, b, c, d, e, 6);
R4(block, e, a, b, c, d, 7);
R4(block, d, e, a, b, c, 8);
R4(block, c, d, e, a, b, 9);
R4(block, b, c, d, e, a, 10);
R4(block, a, b, c, d, e, 11);
R4(block, e, a, b, c, d, 12);
R4(block, d, e, a, b, c, 13);
R4(block, c, d, e, a, b, 14);
R4(block, b, c, d, e, a, 15);

/* Add the working vars back into digest[] */


digest[0] += a;
digest[1] += b;
digest[2] += c;
digest[3] += d;
digest[4] += e;

/* Count the number of transformations */


transforms++;
}

inline static void buffer_to_block(const std::string &buffer,


uint32_t block[BLOCK_INTS]) {
/* Convert the std::string (byte buffer) to a uint32_t array (MSB) */
for (size_t i = 0; i < BLOCK_INTS; i++) {
block[i] = (buffer[4 * i + 3] & 0xff) | (buffer[4 * i + 2] & 0xff) << 8 |
(buffer[4 * i + 1] & 0xff) << 16 |
(buffer[4 * i + 0] & 0xff) << 24;
}
}

inline SHA1::SHA1() { reset(digest, buffer, transforms); }

inline void SHA1::update(const std::string &s) {


std::istringstream is(s);
update(is);
}

inline void SHA1::update(std::istream &is) {


while (true) {
char sbuf[BLOCK_BYTES];
is.read(sbuf, BLOCK_BYTES - buffer.size());
60
Information Security (3170720)

buffer.append(sbuf, (std::size_t)is.gcount());
if (buffer.size() != BLOCK_BYTES) {
return;
}
uint32_t block[BLOCK_INTS];
buffer_to_block(buffer, block);
transform(digest, block, transforms);
buffer.clear();
}
}

/*
* Add padding and return the message digest.
*/

inline std::string SHA1::final() {


/* Total number of hashed bits */
uint64_t total_bits = (transforms * BLOCK_BYTES + buffer.size()) * 8;

/* Padding */
buffer += (char)0x80;
size_t orig_size = buffer.size();
while (buffer.size() < BLOCK_BYTES) {
buffer += (char)0x00;
}

uint32_t block[BLOCK_INTS];
buffer_to_block(buffer, block);

if (orig_size > BLOCK_BYTES - 8) {


transform(digest, block, transforms);
for (size_t i = 0; i < BLOCK_INTS - 2; i++) {
block[i] = 0;
}
}

/* Append total_bits, split this uint64_t into two uint32_t */


block[BLOCK_INTS - 1] = (uint32_t)total_bits;
block[BLOCK_INTS - 2] = (uint32_t)(total_bits >> 32);
transform(digest, block, transforms);

/* Hex std::string */
std::ostringstream result;
for (size_t i = 0; i < sizeof(digest) / sizeof(digest[0]); i++) {
result << std::hex << std::setfill('0') << std::setw(8);
result << digest[i];
}

/* Reset for next run */


reset(digest, buffer, transforms);

return result.str();
}

inline std::string SHA1::from_file(const std::string &filename) {


61
Information Security (3170720)

std::ifstream stream(filename.c_str(), std::ios::binary);


SHA1 checksum;
checksum.update(stream);
return checksum.final();
}

int main() {

std::string plaintext = "ineedvacation";

SHA1 checksum;
std::cout << std::endl;
std::cout << "Test: \t" << plaintext << std::endl;
checksum.update(plaintext);
std::cout << "Hashed: " << checksum.final() << std::endl;
return 0;
}

Output:

Conclusion:
Signature algorithms can bee used to verify the indivual securely using the signature used with the
signing key.

62
Information Security (3170720)

Quiz:

1. How many sub-algorithms digital signature consists of?


A digital signature scheme consists of three algorithms - Key Generation Algorithm, Signing
Algorithm and Signature Verifying Algorithm.

Suggested Reference:
1. https://www.geeksforgeeks.org/digital-signature-standard-dss/

References used by the students:

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

63
Information Security (3170720)

Experiment No: 13
Demonstrate how to work with CrypTool
Date:
Relevant CO: -----

Objectives: (a) to understand working fundamental of CrypTool

Equipment/Instruments: Computer System, CrypTool.

Introduction:

The JCrypTool installation is very simple: download and extract the zip-archive, launch the
main program and get started.

Demonstration of Caesar Encryption using CrypTool


In this CrypTool demonstration, we will use Caesar, one of the oldest encryption algorithms.

Encryption
1. Open the Cryptool UI and the document that needs to be encrypted.

2. Click Encrypt/Decrypt > Symmetric (classic) > Caesar

64
Information Security (3170720)

3. Select Caesar mode and the “alphabet character” is “N.” That means that the text will have
characters replaced starting with N. So A >N, B>M, and so on. Click on “encrypt.”

65
Information Security (3170720)

4. The document is encrypted as per the configured policy. This is a very basic example of how
symmetric encryption works.

Decryption process

Perform the following steps to decrypt the encrypted document.

1. Open the encrypted document, and click on “Encrypt.Decrypt” >Symmetric >Caesar.


2. Enter “N” as the alphabet character. This is the shared secret that both parties must know in
order to encrypt and decrypt.
3. Click on decrypt.

Conclusion:
66
Information Security (3170720)

CrypTool is a powerful and comprehensive free software package with very approachable interface.
Along with its accompanying extensive support materials and programs, it provides substantial
assistance to individuals interested in security, student wanting to explore the field, and as a
teaching tool for instructors.

The variety of different algorithms implemented in CrypTool, from the earliest known to the most
modern, both sets the background for current cryptography, and also enables an understanding of the
most modern cryptographic principles and algorithms.

While tools like CrypTool do take class time to teach, the learning curve is not steep and the time that
would otherwise be used to discuss coding the different cryptography and cryptanalysis tools can be
used to cover additional cryptography concept

Suggested Reference:
1. https://www.c-sharpcorner.com/article/encryption-decryption-using-cryptool/

References used by the students:


1. https://www.cryptool.org/assets/ctp/documents/teachingcryptool.pdf

67
Information Security (3170720)

Experiment No: 14
Demonstrate Working of Wireshark
Date:
Relevant CO:

Objectives: (a) to understand Installation/working fundamental of Wireshark

Equipment/Instruments: Computer System, Wireshark

Introduction:
The Wireshark installation is very simple: download and extract the zip-archive, launch the main
program and get started.

Installation

Installing Wireshark on Windows: Follow the below steps to install Wireshark on Windows:

Step 1: Visit the official Wireshark website using any web browser.

Step 2: Click on Download, a new webpage will open with different installers of Wireshark.

68
Information Security (3170720)

Step 3: Downloading of the executable file will start shortly. It is a small 73.69 MB file that will
take some time.

Step 4: Now check for the executable file in downloads in your system and run it.

Step 5: It will prompt confirmation to make changes to your system. Click on Yes.
69
Information Security (3170720)

Step 6: Setup screen will appear, click on Next.

Step 7: The next screen will be of License Agreement, click on Noted.

70
Information Security (3170720)

Step 8: This screen is for choosing components, all components are already marked so don’t change
anything just click on the Next button.

Step 9: This screen is of choosing shortcuts like start menu or desktop icon along with file
extensions which can be intercepted by Wireshark, tick all boxes and click on Next button.

Step 10: The next screen will be of installing location so choose the drive which will have sufficient
memory space for installation. It needed only a memory space of 223.4 MB.

71
Information Security (3170720)

Step 11: Next screen has an option to install Npcap which is used with Wireshark to capture
packets pcap means packet capture so the install option is already checked don’t change anything
and click the next button.

Step 12: Next screen is about USB network capturing so it is one’s choice to use it or not, click on
Install.

Step 13: After this installation process will start.

72
Information Security (3170720)

Step 14: This installation will prompt for Npcap installation as already checked so the license
agreement of Npcap will appear to click on the I Agree button.

Step 15: Next screen is about different installing options of npcap, don’t do anything click on
Install.

73
Information Security (3170720)

Step 16: After this installation process will start which will take only a minute.

Step 17: After this installation process will complete click on the Next button.

74
Information Security (3170720)

Step 18: Click on Finish after the installation process is complete.

75
Information Security (3170720)

Step 19: After this installation process of Wireshark will complete click on the Next button.

Step 20: Click on Finish after the installation process of Wireshark is complete.
76
Information Security (3170720)

Wireshark is successfully installed on the system and an icon is created on the desktop as shown
below:

Now run the software and see the interface.

77
Information Security (3170720)

Now you can use wireshark for packet capturing and filtering

Conclusion:
Wireshark plays a crucial role in network security analysis. It allows security professionals to inspect
packets for signs of malicious activities, such as suspicious traffic patterns, unauthorized access
attempts, or data exfiltration

Suggested Reference:
1. https://www.javatpoint.com/wireshark
2. https://www.comptia.org/content/articles/what-is-wireshark-and-how-to-use-
it#:~:text=What%20Is%20Wireshark%20Used%20For,identify%20bursts%20of%20network
%20traffic.

References used by the students:

78

You might also like