You are on page 1of 91

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. Goswami Rahul Dineshgiri Enrollment No. 200160107074 of
B.E. Semester 7th Computer Engineering Department of this Institute (GTU Code:
016) has satisfactorily completed the Practical / Tutorial work for the subject Information
Security (3170720) 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- 8
1
decryption.
Implement Playfair cipher encryption- 11
2
decryption.
Implement Hill cipher encryption- 16
3
decryption
Implement Vigenere Cipher encryption- 19
4
decryption
Implement Rail Fence Transposition cipher 23
5
technique.
To implement Simple DES encryption- 27
6
decryption.
To implement Simple AES encryption- 33
7
decryption.
Implement RSA encryption-decryption 42
8
algorithm.
Implement Diffi-Hellman Key exchange 46
9
Method
49
10 Write a program to generate MD-5 hash.

55
11 Write a program to generate SHA-1 hash

63
12 Implement a digital signature algorithm.

67
13 Demonstrate how to work with JCrypTool

71
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[] = "somestring";
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:
The Caesar cipher, named after Julius Caesar, is a basic substitution cipher. It involves shifting each
letter in the plaintext by a fixed number of positions in the alphabet. For instance, with a shift of 3,
'A' becomes 'D', 'B' becomes 'E', and so on. While simple to implement, its security is weak due to
the limited key space of 25 possible shifts, making it susceptible to brute-force attacks. Despite its
vulnerabilities, the Caesar cipher holds historical significance in the field of cryptography and serves
as a fundamental concept in more advanced encryption methods.
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. Then apply 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] != ' ')

5
Information Security(3170720)

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;
}

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++) {

6
Information Security(3170720)

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) {
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);

7
Information Security(3170720)

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, "securekey");
printf("Key text: %s\n", key);

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

// encrypt using Playfair Cipher


encryptByPlayfairCipher(str, key);

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

return 0;
}

Output:

Conclusion:
The Playfair cipher, devised in the 19th century, is a grid-based encryption technique that operates
on pairs of letters. Its strength lies in the complexity of the key, determined by a chosen keyword that
shapes the 5x5 grid. This provides higher security compared to simpler ciphers like the Caesar
cipher. However, it is not invulnerable, as it can still be susceptible to frequency analysis and
requires special handling for double letters. While an advancement in its time, the Playfair cipher is
considered relatively weak by today's cryptographic standards.

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:

8
Information Security(3170720)

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

9
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;
10
Information Security(3170720)

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


for (j = 0; j < 1; j++) {
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 = "RUN";
cout << "Entered message : \t" << message << endl;

// Get the key


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

HillCipher(message, key);

return 0;
}

11
Information Security(3170720)

Output:

Conclusion:
The Hill cipher, invented by Lester S. Hill in 1929, revolutionized classical cryptography with its
matrix-based approach. It operates on blocks of letters, making it more secure than traditional
substitution ciphers. The strength of the Hill cipher depends on the size and properties of the
encryption matrix, which serves as the key. However, it is not impervious to certain attacks,
particularly if the matrix is poorly chosen or if the length of the key is not carefully managed.
Despite this, the Hill cipher remains a crucial milestone in the history of encryption, showcasing the
potential of mathematical techniques in securing communication.

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

12
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:

13
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')
14
Information Security(3170720)

continue;

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


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

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 = "Don’t come here";

string encrypted = cipher.encrypt(original);


string decrypted = cipher.decrypt(encrypted);

cout << original << endl;


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

Output:

Conclusion:
The Vigenère cipher, developed by Blaise de Vigenère in the 16th century, significantly bolstered
classical cryptography by introducing a polyalphabetic substitution method. It uses a keyword to
determine a series of shifts for each letter in the plaintext, making it substantially more secure than
simpler ciphers. The Vigenère cipher offers robust protection against frequency analysis, a
vulnerability in many classical ciphers. Nevertheless, it can be susceptible to key length guessing if
not used correctly. The Vigenère cipher stands as a pivotal advancement in the history of encryption,
showcasing the effectiveness of polyalphabetic techniques in enhancing security for sensitive
communication.

15
Information Security(3170720)

Quiz:

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

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

16
Information Security(3170720)

17
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 plaintext is 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.

18
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';

19
Information Security(3170720)

// to find the direction


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 = "don’t come here";
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;
20
Information Security(3170720)

return 0;
}
Output:

Conclusion:
The Rail Fence cipher, also known as the zigzag cipher, is a basic transposition cipher that arranges
letters in a zigzag pattern before encryption. This technique, while simple to implement, offers
limited security compared to more complex ciphers. It can be susceptible to cryptanalysis,
particularly with longer messages. Consequently, the Rail Fence cipher is considered relatively weak
by modern cryptographic standards. Despite its simplicity, it serves as an essential introduction to the
concept of transposition ciphers and lays the groundwork for more sophisticated encryption methods.

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

21
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 are
used for parity checks. The key therefore has a "useful" length of 56 bits, which means that
only 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 on
64 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:

22
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;
23
Information Security(3170720)

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) {
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];

24
Information Security(3170720)

}
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() {
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},

25
Information Security(3170720)

{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);
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++) {

26
Information Security(3170720)

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:

27
Information Security(3170720)

Conclusion:
The Data Encryption Standard (DES), developed in the 1970s, marked a significant leap forward in
modern cryptography. It is a symmetric-key block cipher that operates on 64-bit blocks of data, using
a 56-bit key for encryption and decryption. DES employs a complex series of permutations and
substitutions, known as the Feistel network, which provides robust security against various types of
attacks. However, due to advances in computing power, DES's 56-bit key length became vulnerable
to brute-force attacks, prompting its replacement by more secure algorithms like AES (Advanced
Encryption Standard) with longer key lengths. Despite its eventual obsolescence, DES remains a
landmark in the history of cryptography, serving as a foundation for subsequent encryption
standards.

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

28
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:
29
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,

30
Information Security(3170720)

0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e,
0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, 0x42, 0x44, 0x46,
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,

31
Information Security(3170720)

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, 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

32
Information Security(3170720)

*/
void SubBytes(unsigned char *state) {
for (int i = 0; i < 16; i++) {
state[i] = s[state[i]];
}
}

// 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]];

33
Information Security(3170720)

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] =
(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];
}

34
Information Security(3170720)

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) {


/* 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];
}

35
Information Security(3170720)

int numberOfRounds = 9;

AddRoundKey(state, expandedKey); // Initial round

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


Round(state, expandedKey + (16 * (i + 1)));
}

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;

36
Information Security(3170720)

unsigned int c;
while (hex_chars_stream >> hex >> c) {
key[i] = c;
i++;
}

unsigned char expandedKey[176];

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 Advanced Encryption Standard (AES) is a highly secure symmetric-key encryption algorithm
established by the U.S. National Institute of Standards and Technology (NIST) in 2001. It operates
on fixed-size blocks of data, using key lengths of 128, 192, or 256 bits. AES employs a series of
complex mathematical operations including substitution, permutation, and mixing, making it
exceptionally resistant to modern cryptographic attacks, even with substantial computational
resources. Its widespread adoption and rigorous security standards have solidified AES as a
cornerstone in contemporary encryption, utilized in a multitude of applications, from securing
communications to safeguarding sensitive data in various industries.
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:

37
Information Security(3170720)

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

38
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 to
everyone. A basic principle behind RSA is the observation that it is practical to find three
very 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:

39
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.
40
Information Security(3170720)

if (gcd(e, phi) == 1)
break;
else
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, named after its inventors Ron Rivest, Adi Shamir, and Leonard Adleman, is a public-key
cryptosystem introduced in 1977. It relies on the mathematical complexity of factoring large
composite numbers. RSA employs two keys: a public key for encryption and a private key for
decryption. The security of RSA is rooted in the difficulty of factoring the product of two large
prime numbers, which forms the basis of the public key. As of my last knowledge update in January
2022, RSA remains widely used for secure communications, particularly in securing online
transactions and digital signatures. However, its security relies on the assumption that factoring large
numbers is a computationally infeasible task, and with advances in quantum computing, the security
of RSA may need to be reevaluated in the future. Nevertheless, RSA stands as a monumental
achievement in modern cryptography, revolutionizing secure communication through the use of
public and private keys.

41
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

42
Information Security(3170720)

43
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 B and
sends the same back to Alice.

44
Information Security(3170720)

STEP-6: Now both of them compute their common secret key as the other one’s secret key
power of a mod p.

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 = 11; // A prime number P is taken
cout << "The value of P : " << P << endl;

G = 5; // 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;
45
Information Security(3170720)

Output:

Conclusion:
The Diffie-Hellman key exchange, introduced in 1976, is a groundbreaking method for securely
establishing a shared secret key between two parties over an insecure channel. It relies on
mathematical operations that make it extremely difficult for eavesdroppers to determine the shared
key. Diffie-Hellman is widely used in secure communication protocols, providing a crucial
foundation for many modern encryption methods. However, it doesn't offer authentication on its
own, which necessitates additional measures to prevent "man-in-the-middle" attacks. Despite this
limitation, Diffie-Hellman remains an integral part of contemporary secure communication
protocols.

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

46
Information Security(3170720)

47
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 length
of 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 are initialized to
certain fixed constants. The main algorithm then uses each 512-bit message block in turn
to modify the stat ..

Example:

48
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 combined together
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,
49
Information Security(3170720)

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};

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;
}

50
Information Security(3170720)

/*
* Add some amount of input to the context
*
* 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);

51
Information Security(3170720)

md5Step(ctx->buffer, input);

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


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;
}

/*

52
Information Security(3170720)

* 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;
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 = "ineedvacation";
uint8_t result[16];
md5String(plaintext, result);
printf("MD5 hash of %s : ", plaintext);
printArrayBuffer(result, 16);
return 0;
}

Output:

Conclusion:
MD5 (Message Digest Algorithm 5) is a widely used cryptographic hash function developed by
Ronald Rivest in 1991. It takes an input (or message) and produces a fixed-size 128-bit hash value,
commonly represented as a 32-character hexadecimal number. MD5 is known for its speed and
efficiency, making it popular for tasks like checksumming and data integrity verification. However,
due to vulnerabilities discovered over time, such as collision attacks, MD5 is no longer considered
secure for cryptographic purposes. It has been largely replaced by more robust hash functions like
SHA-256 in applications where security is paramount. Despite its historical significance, MD5 is
now generally discouraged for security-sensitive tasks.
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:

53
Information Security(3170720)

Rubric wise marks obtained:

Rubrics 1 2 3 4 5 Total
Marks

54
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 way this 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 practically infeasible 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.

55
Information Security(3170720)

STEP-3: The blocks B, C and D are passed to the function F.


STEP-4: The resultant value is permuted with block E.
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;
}

56
Information Security(3170720)

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,


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);
}

/*

57
Information Security(3170720)

* 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);
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);

58
Information Security(3170720)

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);
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) */

59
Information Security(3170720)

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());
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;
}
}

60
Information Security(3170720)

/* 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) {


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:
SHA-1, or Secure Hash Algorithm 1, is a cryptographic hash function developed in 1995. It creates a
fixed-size 160-bit hash value from input data. Initially widely used for security applications,
vulnerabilities were discovered over time, making it vulnerable to collision attacks. Due to these
weaknesses, SHA-1 is now considered insecure for cryptographic purposes. It has been largely
replaced by more robust hash functions like SHA-256 in applications where security is paramount.
Quiz:

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


64 rounds
61
Information Security(3170720)

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

62
Information Security(3170720)

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

63
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.

64
Information Security(3170720)

Program:
// Imports
import java.nio.charset.StandardCharsets;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.util.Scanner;

public class Digital_Signature {

// Signing Algorithm
private static final String SIGNING_ALGORITHM = "SHA256withRSA";
private static final String RSA = "RSA";
private static Scanner sc;

// Function to implement Digital signature


// using SHA256 and RSA algorithm
// by passing private key.
public static byte[] Create_Digital_Signature(
byte[] input,
PrivateKey Key)
throws Exception {
Signature signature = Signature.getInstance(
SIGNING_ALGORITHM);
signature.initSign(Key);
signature.update(input);
return signature.sign();
}

// Generating the asymmetric key pair


// using SecureRandom class
// functions and RSA algorithm.
public static KeyPair Generate_RSA_KeyPair()
throws Exception {
SecureRandom secureRandom = new SecureRandom();
KeyPairGenerator keyPairGenerator = KeyPairGenerator
.getInstance(RSA);
keyPairGenerator
.initialize(
2048, secureRandom);
return keyPairGenerator
.generateKeyPair();
}

// Function for Verification of the


// digital signature by using the public key
public static boolean Verify_Digital_Signature(
byte[] input,
byte[] signatureToVerify,
PublicKey key)
throws Exception {
Signature signature = Signature.getInstance(
SIGNING_ALGORITHM);
signature.initVerify(key);
signature.update(input);
return signature
65
Information Security(3170720)

.verify(signatureToVerify);
}

private static final byte[] HEX_ARRAY = "0123456789ABCDEF".getBytes(StandardCharsets.US_ASCII);

public static String bytesToHex(byte[] bytes) {


byte[] hexChars = new byte[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = HEX_ARRAY[v >>> 4];
hexChars[j * 2 + 1] = HEX_ARRAY[v & 0x0F];
}
return new String(hexChars, StandardCharsets.UTF_8);
}

// Driver Code
public static void main(String args[])
throws Exception {

String input = "GEEKSFORGEEKS IS A"


+ " COMPUTER SCIENCE PORTAL";
KeyPair keyPair = Generate_RSA_KeyPair();

// Function Call
byte[] signature = Create_Digital_Signature(
input.getBytes(),
keyPair.getPrivate());

System.out.println(
"Signature Value:\n "
+ bytesToHex(signature));

System.out.println(
"Verification: "
+ Verify_Digital_Signature(
input.getBytes(),
signature, keyPair.getPublic()));
}
}

Output:

Conclusion:
A signature algorithm is a cryptographic process used to create and verify digital signatures,
providing authentication, integrity, and non-repudiation in electronic communications. It involves
using a private key to generate a unique digital signature from a piece of data, which can be verified
using the corresponding public key. This process ensures that the signature was created by the
possessor of the private key and that the data has not been tampered with. Widely used signature
algorithms include RSA, ECDSA (Elliptic Curve Digital Signature Algorithm), and DSA (Digital
Signature Algorithm). It's crucial for secure transactions, digital certificates, and various
authentication mechanisms in modern digital communication.

66
Information Security(3170720)

67
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

68
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

69
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.”

70
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.

71
Information Security(3170720)

Conclusion:

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

72
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.

73
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.

74
Information Security(3170720)

Step 5: It will prompt confirmation to make changes to your system. Click on Yes.

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

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

75
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.

76
Information Security(3170720)

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.

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.

77
Information Security(3170720)

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.

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.

78
Information Security(3170720)

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

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

79
Information Security(3170720)

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

80
Information Security(3170720)

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

81
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.
82
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.

83
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:

84

You might also like