0% found this document useful (0 votes)
33 views33 pages

INS Lab File

Uploaded by

homijbhabha1966
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)
33 views33 pages

INS Lab File

Uploaded by

homijbhabha1966
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/ 33

DELHI TECHNOLOGICAL UNIVERSITY

(FORMERELY Delhi College of Engineering)


Bawana Road, Delhi – 110042

INFORMATION & NETWORK SECURITY


CO 425 (E8)
Lab File

Maneesh kumar
2K21/CO/268

Submitted to :
Prof. Shailender Kumar
INDEX

S.NO. Title Page No. Date

1. To implement Caesar cipher encryption.

2. To implement Monoalphabetic decryption. Encrypting and


Decrypting works exactly the same for all monoalphabetic
ciphers.

3. To implement Play fair cipher encryption-decryption.

4. To implement Polyalphabetic cipher encryption


decryption.

5. To implement Hill- cipher encryption decryption.

6. To implement S-DES sub key Generation.

7. To implement Diffie-hallman key exchange algorithm.

8. To implement RSA encryption-decryption.

9.
Write a program to generate SHA-1 hash.

10. Implement a digital signature algorithm.


EXPERIMENT : 1

AIM : To implement Caesar cipher encryption and decryption in C++, where each letter in the
plaintext is shifted by a fixed number of places down the alphabet for encryption, and each letter
in the ciphertext is shifted up by the same number for decryption.

CODE:
#include <iostream>
#include <string>
using namespace std;

// Function to encrypt the text using Caesar Cipher


string encrypt(string text, int shift) {
string result = "";
for (int i = 0; i < text.length(); i++) {
char ch = text[i];
// Encrypt uppercase letters
if (isupper(ch))
result += char(int(ch + shift - 'A') % 26 + 'A');
// Encrypt lowercase letters
else if (islower(ch))
result += char(int(ch + shift - 'a') % 26 + 'a');
// Non-alphabet characters remain the same
else
result += ch; }
return result;
}
// Function to decrypt the text using Caesar Cipher
string decrypt(string text, int shift) {
string result = "";
for (int i = 0; i < text.length(); i++) {
char ch = text[i];
// Decrypt uppercase letters
if (isupper(ch))
result += char(int(ch - shift - 'A' + 26) % 26 + 'A');
// Decrypt lowercase letters
else if (islower(ch))
result += char(int(ch - shift - 'a' + 26) % 26 + 'a');
// Non-alphabet characters remain the same
else
result += ch; }
return result; }

int main() {
string text;
int shift;
cout << "Enter text: ";
getline(cin, text);
cout << "Enter shift (key): ";
cin >> shift;
string encryptedText = encrypt(text, shift);
cout << "Encrypted Text: " << encryptedText << endl;
string decryptedText = decrypt(encryptedText, shift);
cout << "Decrypted Text: " << decryptedText << endl;
return 0;
}
OUTPUT:

EXPERIMENT : 2

AIM : To implement encryption and decryption using a monoalphabetic substitution cipher in


C++, where each letter in the alphabet is represented by exactly one other letter in a fixed key for
both encryption and decryption.

CODE:
#include <iostream>
#include <unordered_map>
#include <string>
using namespace std;

// Function to generate the decryption key from the encryption key


unordered_map<char, char> generateDecryptionKey(const string &encryptionKey) {
unordered_map<char, char> decryptionKey;
for (char ch = 'A'; ch <= 'Z'; ch++) {
decryptionKey[encryptionKey[ch - 'A']] = ch;
}
return decryptionKey;
}
// Function to encrypt the text using monoalphabetic substitution cipherstring encrypt(string text,
const string &encryptionKey) {
string result = "";
for (char ch : text) {
if (isupper(ch))
result += encryptionKey[ch - 'A'];
else if (islower(ch))
result += tolower(encryptionKey[ch - 'a']);
else
result += ch; // Non-alphabet characters remain the same }
return result;
}
// Function to decrypt the text using monoalphabetic substitution cipher
string decrypt(string text, unordered_map<char, char> &decryptionKey) {
string result = "";
for (char ch : text) {
if (isupper(ch))
result += decryptionKey[ch];
else if (islower(ch))
result += tolower(decryptionKey[toupper(ch)]);
else
result += ch; // Non-alphabet characters remain the same }
return result; }

int main() {
string text;
string encryptionKey = "QWERTYUIOPASDFGHJKLZXCVBNM"; // Monoalphabetic
encryption key
unordered_map<char, char> decryptionKey = generateDecryptionKey(encryptionKey);
cout << "Enter text: ";
getline(cin, text);
string encryptedText = encrypt(text, encryptionKey);
cout << "Encrypted Text: " << encryptedText << endl;
string decryptedText = decrypt(encryptedText, decryptionKey);
cout << "Decrypted Text: " << decryptedText << endl;
return 0;
}

OUTPUT:
EXPERIMENT : 3

AIM : To implement encryption and decryption using the Playfair cipher in C++. The Playfair
cipher uses a 5x5 matrix of letters for encryption, where each pair of letters in the plaintext is
encrypted by locating them in the matrix and replacing them according to specific rules.

CODE:
#include <iostream>
#include <vector>
#include <string>
#include <unordered_map>
using namespace std;

// Function to create the Playfair cipher matrix


vector<vector<char>> generateMatrix(string key) {
vector<vector<char>> matrix(5, vector<char>(5));
unordered_map<char, bool> used;
key += "ABCDEFGHIKLMNOPQRSTUVWXYZ"; // Include all letters (J is replaced by I)
int idx = 0;
for (char ch : key) {
if (ch == 'J') ch = 'I'; // Treat J as I
if (!used[ch]) {
matrix[idx / 5][idx % 5] = ch;
used[ch] = true;
idx++; } }
return matrix;
}
// Function to find the position of a character in the matrix
pair<int, int> findPosition(const vector<vector<char>>& matrix, char ch) {
if (ch == 'J') ch = 'I'; // Treat J as I
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 5; col++) {
if (matrix[row][col] == ch)
return {row, col}; } }
return {-1, -1}; // Not found }
// Helper function to process the text into digraphs
string processText(string text) {
string result;
for (int i = 0; i < text.length(); i++) {
if (text[i] == 'J') text[i] = 'I'; // Replace J with I
result += text[i];
if (i < text.length() - 1 && text[i] == text[i + 1]) result += 'X'; // Insert X if letters are the
same
}
if (result.length() % 2 != 0) result += 'X'; // Pad with X if necessary
return result; }
// Function to encrypt using the Playfair cipher
string encrypt(string text, const vector<vector<char>>& matrix) {
string result;
text = processText(text);
for (int i = 0; i < text.length(); i += 2) {
char a = text[i];
char b = text[i + 1];
auto posA = findPosition(matrix, a);
auto posB = findPosition(matrix, b);
// Same row
if (posA.first == posB.first) {
result += matrix[posA.first][(posA.second + 1) % 5];
result += matrix[posB.first][(posB.second + 1) % 5]; }
// Same column
else if (posA.second == posB.second) {
result += matrix[(posA.first + 1) % 5][posA.second];
result += matrix[(posB.first + 1) % 5][posB.second]; }
// Rectangle
else {
result += matrix[posA.first][posB.second];
result += matrix[posB.first][posA.second]; } }
return result; }
// Function to decrypt using the Playfair cipher
string decrypt(string text, const vector<vector<char>>& matrix) {
string result;
for (int i = 0; i < text.length(); i += 2) {
char a = text[i];
char b = text[i + 1];
auto posA = findPosition(matrix, a);
auto posB = findPosition(matrix, b);
// Same row
if (posA.first == posB.first) {
result += matrix[posA.first][(posA.second + 4) % 5];
result += matrix[posB.first][(posB.second + 4) % 5]; }
// Same column
else if (posA.second == posB.second) {
result += matrix[(posA.first + 4) % 5][posA.second];
result += matrix[(posB.first + 4) % 5][posB.second]; }
// Rectangle
else {
result += matrix[posA.first][posB.second];
result += matrix[posB.first][posA.second]; } }
return result; }
int main() {
string key, text;
cout << "Enter keyword: ";
getline(cin, key);
cout << "Enter text: ";
getline(cin, text);
// Generate Playfair cipher matrix
vector<vector<char>> matrix = generateMatrix(key);
string encryptedText = encrypt(text, matrix);
cout << "Encrypted Text: " << encryptedText << endl;
string decryptedText = decrypt(encryptedText, matrix);
cout << "Decrypted Text: " << decryptedText << endl;
return 0; }

OUTPUT:
EXPERIMENT : 4

AIM : To implement encryption and decryption using the Polyalphabetic cipher (specifically
the Vigenère cipher) in C++, which is based on substitution and uses multiple substitution
alphabets based on a keyword.

CODE:
#include <iostream>
#include <string>
using namespace std;
// Function to generate the key by repeating it to match the length of the plaintext
string generateKey(string text, string key) {
int textLen = text.length();
int keyLen = key.length();
string extendedKey = key;
for (int i = 0; i < textLen - keyLen; i++) {
extendedKey += key[i % keyLen]; }
return extendedKey; }
// Function to encrypt the text using the Vigenère cipher
string encrypt(string text, string key) {
string result = "";
key = generateKey(text, key);
for (int i = 0; i < text.length(); i++) {
if (isupper(text[i])) {
result += char(((text[i] - 'A') + (key[i] - 'A')) % 26 + 'A'); }
else if (islower(text[i])) {
result += char(((text[i] - 'a') + (key[i] - 'a')) % 26 + 'a'); }
else {
result += text[i]; // Non-alphabet characters remain the same } }
return result; }
// Function to decrypt the text using the Vigenère cipher
string decrypt(string text, string key) {
string result = "";
key = generateKey(text, key);
for (int i = 0; i < text.length(); i++) {
if (isupper(text[i])) {
result += char(((text[i] - 'A') - (key[i] - 'A') + 26) % 26 + 'A'); }
else if (islower(text[i])) {
result += char(((text[i] - 'a') - (key[i] - 'a') + 26) % 26 + 'a'); }
else {
result += text[i]; // Non-alphabet characters remain the same } }
return result; }
int main() {
string text, keyword;
cout << "Enter text: ";
getline(cin, text);
cout << "Enter keyword: ";
getline(cin, keyword);
string encryptedText = encrypt(text, keyword);
cout << "Encrypted Text: " << encryptedText << endl;
string decryptedText = decrypt(encryptedText, keyword);
cout << "Decrypted Text: " << decryptedText << endl;
return 0;
}
OUTPUT:

EXPERIMENT : 5

AIM : To implement encryption and decryption using the Hill cipher in C++. The Hill cipher is a
polygraphic substitution cipher that uses linear algebra and matrix multiplication for encryption and
decryption.

CODE:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
const int MOD = 26;

// Function to calculate the determinant of a 2x2 matrix


int determinant(const vector<vector<int>>& matrix) {
return (matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]) % MOD; }
// Function to calculate the modular inverse of a number under modulo 26
int modInverse(int n) {
n = n % MOD;
for (int x = 1; x < MOD; x++) {
if ((n * x) % MOD == 1)
return x; }
return -1; // Inverse doesn't exist }
// Function to find the inverse of a 2x2 matrix under modulo 26
vector<vector<int>> inverseMatrix(const vector<vector<int>>& matrix) {
int det = determinant(matrix);
int invDet = modInverse(det);
if (invDet == -1) {
cout << "Inverse matrix doesn't exist." << endl;
exit(1); }
vector<vector<int>> invMatrix(2, vector<int>(2));
invMatrix[0][0] = (matrix[1][1] * invDet) % MOD;
invMatrix[1][1] = (matrix[0][0] * invDet) % MOD;
invMatrix[0][1] = (-matrix[0][1] * invDet + MOD) % MOD;
invMatrix[1][0] = (-matrix[1][0] * invDet + MOD) % MOD;
return invMatrix; }
// Function to encrypt a pair of characters using Hill cipher
string encrypt(const string& text, const vector<vector<int>>& keyMatrix) {
string result;
for (int i = 0; i < text.length(); i += 2) {
int x = text[i] - 'A';
int y = text[i + 1] - 'A';
int encX = (keyMatrix[0][0] * x + keyMatrix[0][1] * y) % MOD;
int encY = (keyMatrix[1][0] * x + keyMatrix[1][1] * y) % MOD;
result += (encX + 'A');
result += (encY + 'A'); }
return result;
}
// Function to decrypt a pair of characters using Hill cipher
string decrypt(const string& text, const vector<vector<int>>& invKeyMatrix) {
string result;
for (int i = 0; i < text.length(); i += 2) {
int x = text[i] - 'A';
int y = text[i + 1] - 'A';
int decX = (invKeyMatrix[0][0] * x + invKeyMatrix[0][1] * y) % MOD;
int decY = (invKeyMatrix[1][0] * x + invKeyMatrix[1][1] * y) % MOD;
result += (decX + 'A');
result += (decY + 'A'); }
return result;
}

int main() {
string text;
vector<vector<int>> keyMatrix = {{3, 3}, {2, 5}}; // Example 2x2 key matrix
cout << "Enter text (in pairs, uppercase): ";
cin >> text;
// Ensure input has even length by adding 'X' if needed
if (text.length() % 2 != 0) {
text += 'X'; }
// Encrypt the text
string encryptedText = encrypt(text, keyMatrix);
cout << "Encrypted Text: " << encryptedText << endl;
// Generate inverse matrix for decryption
vector<vector<int>> invKeyMatrix = inverseMatrix(keyMatrix);
// Decrypt the text
string decryptedText = decrypt(encryptedText, invKeyMatrix);
cout << "Decrypted Text: " << decryptedText << endl;
return 0;
}

OUTPUT:
EXPERIMENT : 6

AIM : To implement the subkey generation process for Simplified Data Encryption Standard (S-DES),
which is a smaller and simpler version of the DES algorithm. This involves generating two 8-bit subkeys
from a 10-bit key using specific permutation and shifting operations.

CODE:
#include <iostream>
#include <vector>
using namespace std;

// Function to apply permutation on input key based on the specified positions


vector<int> permute(const vector<int>& key, const vector<int>& positions) {
vector<int> permutedKey;
for (int pos : positions) {
permutedKey.push_back(key[pos - 1]); }
return permutedKey; }
// Function to perform a left circular shift on a 5-bit half
vector<int> leftShift(const vector<int>& half, int shifts) {
vector<int> shiftedHalf = half;
for (int i = 0; i < shifts; i++) {
int temp = shiftedHalf[0];
for (int j = 0; j < 4; j++) {
shiftedHalf[j] = shiftedHalf[j + 1]; }
shiftedHalf[4] = temp; }
return shiftedHalf; }
// Function to generate S-DES subkeys K1 and K2 from a 10-bit key
pair<vector<int>, vector<int>> generateSubkeys(const vector<int>& key) {
// P10 permutation positions
vector<int> P10 = {3, 5, 2, 7, 4, 10, 1, 9, 8, 6};
// P8 permutation positions
vector<int> P8 = {6, 3, 7, 4, 8, 5, 10, 9};
// Apply P10 to the 10-bit key
vector<int> permutedKey = permute(key, P10);
// Split the permuted key into two 5-bit halves
vector<int> leftHalf(permutedKey.begin(), permutedKey.begin() + 5);
vector<int> rightHalf(permutedKey.begin() + 5, permutedKey.end());
// Left Shift 1 for K1 generation
leftHalf = leftShift(leftHalf, 1);
rightHalf = leftShift(rightHalf, 1);
// Combine left and right halves after LS-1
vector<int> combinedKey1 = leftHalf;
combinedKey1.insert(combinedKey1.end(), rightHalf.begin(), rightHalf.end());
// Apply P8 to create K1
vector<int> K1 = permute(combinedKey1, P8);
// Left Shift 2 for K2 generation
leftHalf = leftShift(leftHalf, 2);
rightHalf = leftShift(rightHalf, 2);
// Combine left and right halves after LS-2
vector<int> combinedKey2 = leftHalf;
combinedKey2.insert(combinedKey2.end(), rightHalf.begin(), rightHalf.end());
// Apply P8 to create K2
vector<int> K2 = permute(combinedKey2, P8);
return {K1, K2}; }
// Function to print the generated subkeys
void printKey(const vector<int>& key) {
for (int bit : key) {
cout << bit; }
cout << endl; }

int main() {
// Input 10-bit key (example: 1010000010)
vector<int> key = {1, 0, 1, 0, 0, 0, 0, 0, 1, 0};
// Generate subkeys K1 and K2
auto [K1, K2] = generateSubkeys(key);
cout << "Subkey K1: ";
printKey(K1);
cout << "Subkey K2: ";
printKey(K2);
return 0;
}

OUTPUT:
EXPERIMENT : 7

AIM : To implement the Diffie-Hellman Key Exchange algorithm in C++. This algorithm allows two
parties to securely share a secret key over a public channel.

CODE:
#include <iostream>
#include <cmath>
using namespace std;

// Function to perform modular exponentiation


// It returns (base^exp) % mod
long long modExp(long long base, long long exp, long long mod) {
long long result = 1;
base = base % mod;
while (exp > 0) {
// If exp is odd, multiply base with result
if (exp % 2 == 1) {
result = (result * base) % mod; }
// Now exp must be even, so divide it by 2 and square the base
exp = exp >> 1;
base = (base * base) % mod; }
return result; }
int main() {
// Shared prime number and base
long long p, g;
cout << "Enter a large prime number (p): ";
cin >> p;
cout << "Enter a primitive root modulo p (g): ";
cin >> g;
// Alice's private key
long long a;
cout << "Alice, enter your private key (a): ";
cin >> a;
// Bob's private key
long long b;
cout << "Bob, enter your private key (b): ";
cin >> b;
// Compute Alice's public key
long long A = modExp(g, a, p);
cout << "Alice's public key (A): " << A << endl;
// Compute Bob's public key
long long B = modExp(g, b, p);
cout << "Bob's public key (B): " << B << endl;
// Compute the shared secret key
long long secretKeyAlice = modExp(B, a, p); // Alice's computation
long long secretKeyBob = modExp(A, b, p); // Bob's computation
cout << "Secret key computed by Alice: " << secretKeyAlice << endl;
cout << "Secret key computed by Bob: " << secretKeyBob << endl;
// Verify if both computed secret keys are the same
if (secretKeyAlice == secretKeyBob) {
cout << "Diffie-Hellman Key Exchange Successful! Shared Secret Key: " <<
secretKeyAlice << endl;
} else {
cout << "Error: Shared keys do not match!" << endl; }
return 0;
}
OUTPUT:

EXPERIMENT : 8

AIM : To implement RSA (Rivest-Shamir-Adleman) encryption and decryption algorithm in C++. This
algorithm is used in public-key cryptography to securely transmit data by encrypting messages with a
public key and decrypting them with a private key.

CODE:
#include <iostream>
#include <cmath>
#include <cstdlib>
using namespace std;
// Function to compute the greatest common divisor
int gcd(int a, int b) {
while (b != 0) {
int temp = b;
b = a % b;
a = temp; }
return a; }
// Function to perform modular exponentiation
long long modExp(long long base, long long exp, long long mod) {
long long result = 1;
base = base % mod;
while (exp > 0) {
if (exp % 2 == 1) {
result = (result * base) % mod; }
exp = exp >> 1;
base = (base * base) % mod; }
return result; }
// Function to compute modular inverse of e mod phi(n)
int modInverse(int e, int phi) {
for (int x = 1; x < phi; x++) {
if ((e * x) % phi == 1) {
return x; } }
return -1; // No modular inverse found
}

int main() {
// Step 1: Generate keys
int p, q;
cout << "Enter two prime numbers (p and q): ";
cin >> p >> q;
// Compute n and phi(n)
int n = p * q;
int phi = (p - 1) * (q - 1);
// Choose e such that 1 < e < phi and e is coprime to phi
int e;
cout << "Enter a value for public exponent (e) such that 1 < e < " << phi << " and gcd(e, " <<
phi << ") = 1: ";
cin >> e;
if (gcd(e, phi) != 1) {
cout << "Invalid value for e. It must be coprime with phi(n)." << endl;
return -1; }
// Compute the private key d
int d = modInverse(e, phi);
if (d == -1) {
cout << "No modular inverse found for e. Try another e." << endl;
return -1; }
cout << "Public key (e, n): (" << e << ", " << n << ")" << endl;
cout << "Private key (d, n): (" << d << ", " << n << ")" << endl;
// Step 2: Encryption
int message;
cout << "Enter the message to encrypt (as an integer): ";
cin >> message;
if (message < 0 || message >= n) {
cout << "Message must be in range 0 to " << n - 1 << "." << endl;
return -1;
}
// Encrypt message
int ciphertext = modExp(message, e, n);
cout << "Encrypted message (ciphertext): " << ciphertext << endl;
// Step 3: Decryption
int decryptedMessage = modExp(ciphertext, d, n);
cout << "Decrypted message: " << decryptedMessage << endl;
return 0;
}

OUTPUT:
EXPERIMENT : 9

AIM : To implement a program that generates the SHA-1 (Secure Hash Algorithm 1) hash of a given
input string. SHA-1 is a cryptographic hash function that takes an input and produces a 160-bit (20-byte)
hash value, typically rendered as a 40-character hexadecimal number.

CODE:
#include <iostream>
#include <openssl/sha.h>
#include <iomanip>
#include <sstream>
using namespace std;

// Function to generate SHA-1 hash


string sha1Hash(const string& input) {
unsigned char hash[SHA_DIGEST_LENGTH];
SHA1(reinterpret_cast<const unsigned char*>(input.c_str()), input.size(), hash);
// Convert the hash to a hex string
stringstream ss;
for (int i = 0; i < SHA_DIGEST_LENGTH; ++i) {
ss << hex << setw(2) << setfill('0') << static_cast<int>(hash[i]); }
return ss.str(); }

int main() {
string input;
cout << "Enter the input string: ";
getline(cin, input);
string sha1HashValue = sha1Hash(input);
cout << "SHA-1 hash: " << sha1HashValue << endl;

return 0;
}

OUTPUT:

EXPERIMENT : 10

AIM : To implement the Digital Signature Algorithm (DSA) in C++ to securely sign a message and
verify its authenticity using public and private keys.

CODE:
#include <iostream>
#include <openssl/dsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <cstring>
using namespace std;

// Function to generate DSA keys and save them to files


bool generateDSAKeys() {
DSA* dsa = DSA_new();
if (!dsa) {
cerr << "Error creating DSA structure." << endl;
return false; }
// Generate DSA parameters
if (DSA_generate_parameters_ex(dsa, 1024, NULL, 0, NULL, NULL, NULL) != 1) {
cerr << "Error generating DSA parameters." << endl;
DSA_free(dsa);
return false; }
// Generate DSA key pair
if (DSA_generate_key(dsa) != 1) {
cerr << "Error generating DSA key pair." << endl;
DSA_free(dsa);
return false; }
// Save private key to file
FILE* pkeyFile = fopen("private_key.pem", "wb");
if (!PEM_write_DSAPrivateKey(pkeyFile, dsa, NULL, NULL, 0, NULL, NULL)) {
cerr << "Error saving private key." << endl;
fclose(pkeyFile);
DSA_free(dsa);
return false;
}
fclose(pkeyFile);
// Save public key to file
FILE* pubKeyFile = fopen("public_key.pem", "wb");
if (!PEM_write_DSA_PUBKEY(pubKeyFile, dsa)) {
cerr << "Error saving public key." << endl;
fclose(pubKeyFile);
DSA_free(dsa);
return false;
}
fclose(pubKeyFile);
DSA_free(dsa);
return true;
}
// Function to sign a message using the private key
bool signMessage(const string& message, unsigned char* &signature, unsigned int
&signatureLen) {
FILE* pkeyFile = fopen("private_key.pem", "rb");
if (!pkeyFile) {
cerr << "Error opening private key file." << endl;
return false; }
DSA* dsa = PEM_read_DSAPrivateKey(pkeyFile, NULL, NULL, NULL);
fclose(pkeyFile);
if (!dsa) {
cerr << "Error reading private key." << endl;
return false; }
signature = new unsigned char[DSA_size(dsa)];
// Sign the message
if (DSA_sign(0, (unsigned char*)message.c_str(), message.size(), signature, &signatureLen,
dsa) != 1) {
cerr << "Error signing message." << endl;
DSA_free(dsa);
delete[] signature;
return false; }
DSA_free(dsa);
return true;}
// Function to verify the message using the public key
bool verifySignature(const string& message, unsigned char* signature, unsigned int
signatureLen) {
FILE* pubKeyFile = fopen("public_key.pem", "rb");
if (!pubKeyFile) {
cerr << "Error opening public key file." << endl;
return false; }
DSA* dsa = PEM_read_DSA_PUBKEY(pubKeyFile, NULL, NULL, NULL);
fclose(pubKeyFile);
if (!dsa) {
cerr << "Error reading public key." << endl;
return false; }
// Verify the signature
bool isValid = DSA_verify(0, (unsigned char*)message.c_str(), message.size(), signature,
signatureLen, dsa) == 1;
DSA_free(dsa);
return isValid;}
int main() {
// Generate keys
if (!generateDSAKeys()) {
cerr << "Key generation failed." << endl;
return 1; }
cout << "Keys generated and saved to files." << endl;
// Message to sign
string message = "Hello, this is a test message!";
unsigned char* signature = nullptr;
unsigned int signatureLen;
// Sign the message
if (!signMessage(message, signature, signatureLen)) {
cerr << "Message signing failed." << endl;
delete[] signature;
return 1; }
cout << "Message signed successfully." << endl;
// Verify the signature
if (verifySignature(message, signature, signatureLen)) {
cout << "Signature verification successful. The message is authentic." << endl;
} else {
cout << "Signature verification failed. The message is not authentic." << endl; }
delete[] signature;
return 0;
}

OUTPUT:

You might also like