0% found this document useful (0 votes)
23 views

Ins Lab File

Uploaded by

sanskar ojha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
23 views

Ins Lab File

Uploaded by

sanskar ojha
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 30

DELHI TECHNOLOGICAL UNIVERSITY

DEPARTMENT OF COMPUTER SCIENCE AND


ENGINEERING

Information and Network Security Laboratory


Subject Code: CO-425

Submitted To: Submitted By:


Ms. Shanu Bhardwaj. Sanskar Ojha
2K21/CO/418

1
Index

S. No Experiment Date Signature


1 To implement Caesar cipher encryption and
decryption. 13/08/24

2 To implement Monoalphabetic Cipher


decryption. 20/08/24

3 To implement PlayFair cipher using encryption


27/08/24
decryption.

4 To implement Polyalphabetic cipher encryption


decryption.
03/09/24

5 To implement Hill Cipher encryption


10/09/24
decryption.

6 To implement the subkey generation for


08/10/24
Simplified DES (S-DES).

7 To implement Diffie Hallman key exchange


15/10/24
algorithm.

8 To implement RSA encryption decryption.


15/10/24

9 Write a program to generate SHA-1 hash.


22/10/24

10 Implement a digital signature algorithm.


22/10/24

2
Experiment-1
Aim - To implement Caesar cipher encryption and decryption.

Theory - The Caesar cipher is one of the simplest and oldest encryption techniques. It is a substitution
cipher where each letter in the plaintext is "shifted" a certain number of places down or up the alphabet.
For example, with a shift of 3, 'A' would be replaced by 'D', 'B' by 'E', and so on. If the end of the alphabet
is reached, it wraps around (e.g., 'Z' with a shift of 3 would become 'C').

Code -
#include <iostream>
#include <string>
using namespace std;

// Function to encrypt the plaintext


string encryptCaesarCipher(string text, int shift) {
string result = "";
for (char c : text) {
if (isupper(c)) {
result += char(int(c + shift - 'A') % 26 + 'A');
} else if (islower(c)) {
result += char(int(c + shift - 'a') % 26 + 'a');
} else {
result += c; // Non-alphabet characters are added as-is
}
}
return result;
}

// Function to decrypt the ciphertext


string decryptCaesarCipher(string text, int shift) {
string result = "";
for (char c : text) {
if (isupper(c)) {
result += char(int(c - shift - 'A' + 26) % 26 + 'A');
} else if (islower(c)) {
result += char(int(c - shift - 'a' + 26) % 26 + 'a');
} else {
result += c; // Non-alphabet characters are added as-is
}
}
return result;

3
}

int main() {
string text;
int shift;

cout << "Enter text to encrypt: ";


getline(cin, text);
cout << "Enter shift value: ";
cin >> shift;

string encryptedText = encryptCaesarCipher(text, shift);


cout << "Encrypted Text: " << encryptedText << endl;

string decryptedText = decryptCaesarCipher(encryptedText, shift);


cout << "Decrypted Text: " << decryptedText << endl;

return 0;
}

Output :

4
Experiment-2
Aim - To implement Monoalphabetic Cipher decryption, where each letter in the alphabet is substituted by
exactly one other letter.

Theory - The Monoalphabetic Cipher is a substitution cipher where each character in the plaintext is
replaced by a corresponding character from a substitution alphabet (key). This substitution remains
constant throughout the encryption or decryption process. For decryption, each letter in the ciphertext is
replaced with the corresponding letter from the reverse mapping of the substitution alphabet.

Code -
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;

// Function to build the decryption map from a given key


unordered_map<char, char> createDecryptionMap(string key) {
unordered_map<char, char> decryptMap;
string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";

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


decryptMap[key[i]] = alphabet[i];
}

return decryptMap;
}

// Function to decrypt a monoalphabetic cipher text


string decryptMonoalphabetic(string text, unordered_map<char, char> decryptMap) {
string result = "";
for (char c : text) {
if (isupper(c)) {
result += decryptMap[c];
} else if (islower(c)) {
result += tolower(decryptMap[toupper(c)]);
} else {
result += c; // Non-alphabet characters are added as-is
}
}
return result;
}

5
int main() {
string key = "QWERTYUIOPLKJHGFDSAZXCVBNM"; // Example substitution
key string ciphertext;

cout << "Enter ciphertext to decrypt: ";


getline(cin, ciphertext);

unordered_map<char, char> decryptMap = createDecryptionMap(key);


string decryptedText = decryptMonoalphabetic(ciphertext, decryptMap);

cout << "Decrypted Text: " << decryptedText << endl;

return 0;
}
Output:

6
Experiment-3
Aim - To implement PlayFair cipher using encryption decryption.

Theory - Each letter pair (digraph) in the plaintext is substituted based on rules derived from their
positions in the key square:
Same Row: Replace each letter with the letter to its immediate right (wrapping to the beginning of the
row if necessary).
Same Column: Replace each letter with the letter immediately below it (wrapping to the top if
necessary).
Rectangle: If the letters form a rectangle, replace each with the letter on the same row but in the column
of the other letter in the digraph.

Code -
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;

class PlayfairCipher {
char matrix[5][5];
unordered_map<char, pair<int, int>> pos;

void createMatrix(const string & key) {


bool used[26] = {false};
used['J' - 'A'] = true; // Treat 'J' as 'I'
int r = 0, c = 0;

for (char ch : key +


"ABCDEFGHIJKLMNOPQRSTUVWXYZ") { ch = (ch
== 'J') ? 'I' : ch;
if (!used[ch - 'A']) {
matrix[r][c] = ch;
pos[ch] = {r, c};
used[ch - 'A'] = true;
if (++c == 5) { c = 0; ++r; }
}
}
}

7
string processDigraph(char a, char b, int dir) {
int r1 = pos[a].first, c1 = pos[a].second;
int r2 = pos[b].first, c2 = pos[b].second;

if (r1 == r2) return {matrix[r1][(c1 + dir + 5) % 5], matrix[r2][(c2 + dir + 5) %


5]}; if (c1 == c2) return {matrix[(r1 + dir + 5) % 5][c1], matrix[(r2 + dir + 5) %
5][c2]}; return {matrix[r1][c2], matrix[r2][c1]};
}
public:
PlayfairCipher(const string & key) { createMatrix(key); }

string encrypt(const string &text) {


string processed = prepareText(text), cipher;
for (size_t i = 0; i < processed.length(); i += 2) cipher += processDigraph(processed[i], processed[i +
1], 1);
return cipher;
}

string decrypt(const string & cipher) {


string plain;
for (size_t i = 0; i < cipher.length(); i += 2) plain += processDigraph(cipher[i], cipher[i + 1], -1);
return plain;
}
};

Output:

8
EXPERIMENT-4
Aim - To implement Polyalphabetic cipher encryption decryption. Encryption/Decryption: Based on
substitution, using multiple substitution Alphabets

Theory - The Polyalphabetic Cipher, represented here by the Vigenère Cipher, uses multiple substitution
alphabets to encrypt plaintext. The key is repeated to match the length of the plaintext, and each letter in
the plaintext is shifted according to the corresponding letter in the key. For example, if the key is "KEY"
and the plaintext is "HELLO", the key repeats to "KEYKE" to match the length of "HELLO".

Code :

#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char msg[30],key[30],k[20],ct[20],pt[20];
int lenm,lenk,i,j;
clrscr();

printf("Enter Message : ");


gets(msg);
printf("Enter Key : ");
gets(key);
lenm=strlen(msg);
lenk=strlen(key);
for(i=0;i<lenm;i++,j++)
{
if(j==lenk)
{
j=0;
}
k[i]=key[j];
}
for(i=0;i<lenm;i++)
{
ct[i]=((msg[i]+k[i])%26)+'A';
}
ct[i]='\0';
for(i=0;i<lenm;i++)
{
pt[i]=(((ct[i]-k[i])+26)%26)+'A';
}
pt[i]='\0';

9
printf("\nEncrypted Message : %s", ct);
printf("\nDecrypted Message : %s", pt);

getch();
}

Output:

10
Experiment-5
Aim - To implement Hill Cipher encryption decryption.

Theory - Hill cipher is a polygraphic substitution cipher based on linear algebra.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 (considered as an n-
component vector) is multiplied by an invertible n × n matrix, against modulus 26. To decrypt the message,
each block is multiplied by the inverse of the matrix used for encryption.

Code -

#include<iostream>
#include<math.h>
using namespace std;
float encrypt[3][1], decrypt[3][1], a[3][3], b[3][3], mes[3][1], c[3][3];
void encryption(); //encrypts the message
void decryption(); //decrypts the message
void getKeyMessage(); //gets key and message from user
void inverse(); //finds inverse of key matrix
int main() {
getKeyMessage();
encryption();
decryption();
}
void encryption() {
int i, j, k;
for(i = 0; i< 3; i++)
for(j = 0; j < 1; j++)
for(k = 0; k < 3; k++)
encrypt[i][j] = encrypt[i][j] + a[i][k] * mes[k][j];
cout<<"\n Encrypted string is: ";
for(i = 0; i< 3; i++)
cout<<(char)(fmod(encrypt[i][0], 26) + 97);
}
void decryption() {
int i, j, k;
inverse();
for(i = 0; i< 3; i++)
for(j = 0; j < 1; j++)
for(k = 0; k < 3; k++)
decrypt[i][j] = decrypt[i][j] + b[i][k] * encrypt[k][j];
cout<<"\nDecrypted string is: ";
for(i = 0; i< 3; i++)
cout<<(char)(fmod(decrypt[i][0], 26) + 97);
cout<<"\n";
11
void getKeyMessage() {
int i, j;
char msg[3];
cout<<"Enter 3x3 matrix for key (It should be inversible):\n";
for(i = 0; i< 3; i++)
for(j = 0; j < 3; j++) {
cin>>a[i][j];
c[i][j] = a[i][j];
}
cout<<"\nEnter a 3 letter string: ";
cin>>msg;
for(i = 0; i< 3; i++)
mes[i][0] = msg[i] - 97;
}
void inverse() {
int i, j, k;
float p, q;
for(i = 0; i< 3; i++)
for(j = 0; j < 3; j++) {
if(i == j)
b[i][j]=1;
else
b[i][j]=0;
}
for(k = 0; k < 3; k++) {
for(i = 0; i< 3; i++) {
p = c[i][k];
q = c[k][k];
for(j = 0; j < 3; j++) {
if(i != k) {
c[i][j] = c[i][j]*q - p*c[k][j];
b[i][j] = b[i][j]*q - p*b[k][j];
}
}
}
}
for(i = 0; i< 3; i++)
for(j = 0; j < 3; j++)
b[i][j] = b[i][j] / c[i][i];
cout<<"\n\nInverse Matrix is:\n";
for(i = 0; i< 3; i++) {
for(j = 0; j < 3; j++)
cout<<b[i][j]<<" ";
cout<<"\n";
}
}

12
OUTPUT

13
Experiment-6
Aim - To implement the subkey generation for Simplified DES (S-DES).

Theory - Simplified Data Encryption Standard (S-DES) is a simple version of the DES Algorithm. It is
similar to the DES algorithm but is a smaller algorithm and has fewer parameters than DES. It was made
for educational purposes so that understanding DES would become simpler. It is a block cipher that
takes a block of plain text and converts it into ciphertext. It takes a block of 8bit.
It is a symmetric key cipher i.e. they use the same key for both encryption and decryption. In this article,
we are going to demonstrate key generation for s-des encryption and decryption algorithm. We take a
random 10-bit key and produce two 8-bit keys which will be used for encryption and decryption.

Code -
#include <iostream>
#include <vector>
using namespace std;

// P10 and P8 Permutation tables for S-DES


int P10[] = {3, 5, 2, 7, 4, 10, 1, 9, 8, 6};
int P8[] = {6, 3, 7, 4, 8, 5, 10, 9};

// Function to apply permutation


vector<int> permute(const vector<int> &key, const int *perm, int permSize) {
vector<int> permutedKey(permSize);
for (int i = 0; i < permSize; i++) {
permutedKey[i] = key[perm[i] - 1];
}
return permutedKey;
}

// Function to perform a left shift on a 5-bit half


vector<int> leftShift(const vector<int> &half, int shiftCount) {
vector<int> shifted(5);
for (int i = 0; i < 5; i++) {
shifted[i] = half[(i + shiftCount) % 5];
}
return shifted;
}

// Function to generate K1 and K2 subkeys


pair<vector<int>, vector<int>> generateSubkeys(const vector<int> &key) {
// Step 1: P10 Permutation
vector<int> permutedKey = permute(key, P10, 10);

14
// Step 2: Split into two 5-bit halves
vector<int> leftHalf(permutedKey.begin(), permutedKey.begin() + 5);
vector<int> rightHalf(permutedKey.begin() + 5, permutedKey.end());

// Step 3: Left shift each half by 1


leftHalf = leftShift(leftHalf, 1);
rightHalf = leftShift(rightHalf, 1);

// Step 4: Combine halves and apply P8 to get K1


vector<int> combinedKey1 = leftHalf;
combinedKey1.insert(combinedKey1.end(), rightHalf.begin(), rightHalf.end());
vector<int> K1 = permute(combinedKey1, P8, 8);

// Step 5: Left shift each half by 2 for second subkey K2


leftHalf = leftShift(leftHalf, 2);
rightHalf = leftShift(rightHalf, 2);

// Step 6: Combine halves and apply P8 to get K2


vector<int> combinedKey2 = leftHalf;
combinedKey2.insert(combinedKey2.end(), rightHalf.begin(), rightHalf.end());
vector<int> K2 = permute(combinedKey2, P8, 8);

return {K1, K2};


}

int main() {
// Input 10-bit key for S-DES (e.g., 1010000010)
vector<int> key = {1, 0, 1, 0, 0, 0, 0, 0, 1, 0};

// Generate subkeys K1 and K2


auto [K1, K2] = generateSubkeys(key);

// Display subkeys
displayKey(K1,
"K1");
displayKey(K2,
"K2");

return 0;
}
Output:

15
Experiment-7
Aim - To implement Diffie Hallman key exchange algorithm.

Theory - The Diffie–Hellman (DH) Algorithm is a key-exchange protocol that enables two parties
communicating over public channel to establish a mutual secret without it being transmitted over the
Internet. DH enables the two to use a public key to encrypt and decrypt their conversation or data using
symmetric cryptography.
Diffie-Hallman is generally explained by two sample parties, Alice and Bob, initiating a dialogue. Each has
a piece of information they want to share, while preserving its secrecy. To do that they agree on a public
piece of benign information that will be mixed with their privileged information as it travels over an
insecure channel.

Code –
#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
(longint)pow(a, b)) % P);
}

return (((long

16
Output:

17
Experiment-8
Aim - To implement RSA encryption decryption

Theory - RSA algorithm is an asymmetric cryptography algorithm. Asymmetric actually means that it
works on two different keys i.e. Public Key and Private Key. As the name describes that the Public Key
is given to everyone and the Private key is kept private.

An example of asymmetric cryptography :

A client (for example browser) sends its public key to the server and requests some data. The server
encrypts the data using the client’s public key and sends the encrypted data. The client receives this
data and decrypts it.
Since this is asymmetric, nobody else except the browser can decrypt the data even if a third party has
the public key of the browser.

The idea! The idea of RSA is based on the fact that it is difficult to factorize a large integer. The public
key consists of two numbers where one number is a multiplication of two large prime numbers. And
private key is also derived from the same two prime numbers. So if somebody can factorize the large
number, the private key is compromised. Therefore encryption strength totally lies on the key size and
if we double or triple the key size, the strength of encryption increases exponentially. RSA keys can be
typically 1024 or 2048 bits long, but experts believe that 1024- bit keys could be broken in the near
future. But till now it seems to be an infeasible task.

ALGORITHM:
Begin
1. Choose two prime numbers p and q.
2. Compute n = p*q.
3. Calculate phi = (p-1) * (q-1).
4. Choose an integer e such that 1 < e < phi(n) and gcd(e, phi(n)) = 1; i.e., e and phi(n)
arecoprime.
5. Calculate d as d ≡ e−1 (mod phi(n)); here, d is the modular multiplicative inverse of e
modulo phi(n).
6. For encryption, c = me mod n, where m = original message.
7. For decryption, m = c d mod
n.End

18
Code -
#include<iostream>
#include<math.h> using
namespace std;
// find gcd
int gcd(int a, int b) {
int t;

while(1) {
t= a%b;
if(t==0)
return b;
a = b; b=
t;
}
}

int main() {
//2 random prime numbers
double p = 13;
double q = 11;
double n=p*q;//calculate n
double track;
double phi= (p-1)*(q-1);//calculate phi
//public key
//e stands for encrypt
double e=7;
//for checking that 1 < e < phi(n) and gcd(e, phi(n)) = 1; i.e., e and phi(n) are coprime.
while(e<phi) {
track = gcd(e,phi);
if(track==1)
break;
else
e++;
}
//private key
//d stands for decrypt
//choosing d such that it satisfies d*e = 1 mod phi
double d1=1/e;
double d=fmod(d1,phi);
double message = 9;
double c = pow(message,e); //encrypt the message
double m = pow(c,d);
c=fmod(c,n);
m=fmod(m,n);
cout<<"Original Message = "<<message;
cout<<"\n"<<"p = "<<p;
cout<<"\n"<<"q = "<<q;
cout<<"\n"<<"n = pq = "<<n;
cout<<"\n"<<"phi = "<<phi;

cout<<"\n"<<"e = "<<e;
cout<<"\n"<<"d = "<<d;
cout<<"\n"<<"Encrypted message = "<<c;
19
cout<<"\n"<<"Decrypted message = "<<m;
return 0;

Output:

20
Experiment-9
Aim - Write a program to generate SHA-1 hash.

Theory - SHA-1 or Secure Hash Algorithm 1 is a cryptographic hash function which takes an input
and produces a 160-bit (20-byte) hash value. This hash value is known as a message digest. This
message digest is usually then rendered as a hexadecimal number which is 40 digits long. It is a
U.S. Federal Information Processing Standard and was designed by the United States National
Security Agency. In cryptography, SHA-1 (Secure Hash Algorithm 1) is a cryptographic hash
function which takes an input and produces a 160-bit (20-byte) hash value known as a message
digest – typically rendered as a hexadecimal number, 40 digits long. It was designed by the United
States National Security Agency, and is a U.S. Federal Information Processing Standard.
Since 2005, SHA-1 has not been considered secure against well-funded opponents; as of 2010
many organizations have recommended its replacement. NIST formally deprecated use of SHA-1
in 2011 and disallowed its use for digital signatures in 2013. As of 2020, chosen-prefix attacks
against SHA-1 are practical. As such, it is recommended to remove SHA-1 from products as soon
as possible and instead use SHA-2 or SHA-3. Replacing SHA-1 is urgent where it is used for
digital signatures.

All major web browser vendors ceased acceptance of SHA-1 SSL certificates in 2017. In February
2017, CWI Amsterdam and Google announced they had performed a collision attack against SHA-
1, publishing two dissimilar PDF files which produced the same SHA-1 hash. But SHA-1 is still
secure for HMAC.

Code -
#include <iostream>
#include <vector>
#include <string>
#include <iomanip>
#include <sstream>

// SHA-1 main function to process each 512-bit block


vector<unsigned int> sha1Process(const vector<unsigned int>& w) {
unsigned int h0 = 0x67452301, h1 = 0xEFCDAB89, h2 = 0x98BADCFE, h3 = 0x10325476;
unsigned int h4 = 0xC3D2E1F0;

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


w[i] = leftRotate(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1);
}

unsigned int a = h0, b = h1, c = h2, d = h3, e = h4;

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


unsigned int f, k;
if (i < 20) {
21
f = (b & c) | ((~b) &
d); k = 0x5A827999;
} else if (i < 40)
{f=b^c^
d;
k = 0x6ED9EBA1;
} else if (i < 60) {
f = (b & c) | (b & d) | (c & d);
k = 0x8F1BBCDC;
} else {
f = b ^ c ^ d;
k = 0xCA62C1D6;
}
unsigned int temp = leftRotate(a, 5) + f + e + k + w[i];
e = d;
d = c;
c = leftRotate(b, 30); b
= a;
a = temp;
}

h0 += a; h1 += b; h2 += c; h3 += d; h4 += e;
return {h0, h1, h2, h3, h4};
}

// SHA-1 function to hash an input message


string sha1(const string& input) {
vector<unsigned int> w(80);
unsigned long long bitLen = input.size() * 8;

for (size_t i = 0; i < input.size(); i++) {


w[i / 4] |= (input[i] << (24 - (i % 4) * 8));
}

w[input.size() / 4] |= 0x80 << (24 - (input.size() % 4) * 8);


w[15] = bitLen;

vector<unsigned int> hash = sha1Process(w);

ostringstream result;
for (unsigned int h : hash) {
result << hex << setw(8) << setfill('0') << h;
}

22
return result.str();
}

Output:

23
Experiment-10
Aim - Implement a digital signature algorithm

Theory - Digital Signature Algorithm (DSA) is one of the Federal Information Processing Standard
for making digital signatures depends on the mathematical concept or we can say the formulas of
modular exponentiation and the discrete logarithm problem to cryptograph the signature digitally in
this algorithm.

It is Digital signatures are the public-key primitives of message authentication in cryptography. In


fact, in the physical world, it is common to use handwritten signatures on handwritten or typed
messages at this time. Mainly, they are used to bind signatory to the message to secure the message.

Therefore, a digital signature is a technique that binds a person or entity to the digital data of the
signature. Now, this will binding can be independently verified by the receiver as well as any third
party to access that data.

Here, Digital signature is a cryptographic value that is calculated from the data and a secret key
known only by the signer or the person whose signature is that.

In fact, in the real world, the receiver of message needs assurance that the message belongs to the
sender and he should not be able to hack the origination of that message for misuse or anything.
Their requirement is very crucial in business applications or any other things since the likelihood of
a dispute over exchanged data is very high to secure that data.

Code -
#include <iostream>
#include <cmath>
#include <random>
#include <tuple>
#include <string>
#include <iomanip>
#include <sstream>

using namespace std;

// Hash function (SHA-1 simplified version)


long long simpleHash(const string& message) {
long long hash = 0;
for (char c : message) {
hash = (hash * 31 + c) % 1000000007; // Simplified hash calculation
}
return hash;
}

24
// DSA Key Generation
tuple<long long, long long, long long> generateKeys(long long p, long long q, long long g) {
random_device rd;
mt19937 gen(rd()); uniform_int_distribution<long
long> dist(1, q - 1);

long long x = dist(gen); // Private key


long long y = modExp(g, x, p); // Public key
return {x, y, p};
}

// DSA Signature Generation


pair<long long, long
long>
signMessage(const
string& message,
long long p, long
long q, long long g,
long long x) {
random_device rd;
mt19937 gen(rd());
uniform_int_distribution<long long> dist(1, q - 1);

long long k = dist(gen); // Random integer k


long long r = modExp(g, k, p) % q;
long long s = (modInverse(k, q) * (simpleHash(message) + x * r)) % q;
return {r, s};
}

// DSA Signature Verification


bool verifySignature(const string& message, long long r, long long s, long long p, long long q, long long g,
long long y) {
if (r <= 0 || r >= q || s <= 0 || s >= q) return false;

long long w = modInverse(s, q);


long long u1 = (simpleHash(message) * w) % q;
long long u2 = (r * w) % q;
long long v = ((modExp(g, u1, p) * modExp(y, u2, p)) % p) % q;

return v == r;
}

25
Output:

26
27
28
29
30

You might also like