Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 26

LIST OF EXPERIMENTS

1. Implementation of Caesar Cipher


2. Implementation of Playfair Cipher
3. Implementation of Hill Cipher
4. Implementation of Vigenere Cipher
5. Implementation of Rail fence – row & Column Transformation
6. Implement the DES algorithms
7. Implement the RSA Algorithm
8. Implement the Diffiee-Hellman
9. Implement the MD5
10. Implement the SHA-1
11. Implement the Digital Signature

Dipayan Rana
1.Implementation of Caesar Cipher
=> Caesar Cipher Description:
The Caesar Cipher is a straightforward encryption technique where each letter in the plaintext
is shifted a certain number of positions up or down the alphabet. It operates as a substitution
cipher, replacing each letter with another letter located at a fixed number of positions away.
Julius Caesar is historically known to have employed a similar method to secure his military
communications.

Algorithm Steps:
1. Initialize CaesarCipher Class:
a. Create a CaesarCipher class to encapsulate the functionality.
2. Constructor:
a. Create a constructor in the CaesarCipher class to set the shift value.
3. Encrypt Method:
a. Implement an encrypt method within the CaesarCipher class.
b. Iterate through each character in the plaintext.
c. For each alphabetic character, shift it by the specified amount (positive or
negative).
d. Preserve the case (uppercase or lowercase) during the shift.
e. Append the shifted character to the ciphertext.

Java Implementation:
public class CaesarCipher {

private int shift; // The number of positions each letter should be shifted

// Constructor to set the shift value


public CaesarCipher(int shift) {
this.shift = shift;
}

// Method to encrypt the plaintext using the Caesar Cipher


public String encrypt(String plaintext) {
StringBuilder ciphertext = new StringBuilder();

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


char ch = plaintext.charAt(i);

if (Character.isLetter(ch)) {
char base = Character.isUpperCase(ch) ? 'A' : 'a';
ch = (char) ((ch - base + shift) % 26 + base);
}

ciphertext.append(ch);
}

return ciphertext.toString();
}

Dipayan Rana
public static void main(String[] args) {
// Example usage
int shiftAmount = 3;
CaesarCipher caesarCipher = new CaesarCipher(shiftAmount);
String plaintext = "HELLO";

// Encrypt the plaintext


String ciphertext = caesarCipher.encrypt(plaintext);

// Output
System.out.println("Plaintext: " + plaintext);
System.out.println("Shift Amount: " + shiftAmount);
System.out.println("Ciphertext: " + ciphertext);
}
}

Sample Output:
Plaintext: HELLO
Shift Amount: 3
Ciphertext: KHOOR

Dipayan Rana
2.Implementation of Playfair Cipher
=> Playfair Cipher Description:
The Playfair Cipher is a digraphic substitution cipher that encrypts pairs of letters (digraphs),
providing a more complex encryption than the Caesar Cipher. It involves transforming the
plaintext into a 5x5 grid and then encrypting each pair of letters based on their positions in
the grid.

Algorithm Steps:
1. Initialize PlayfairCipher Class:
a. Create a PlayfairCipher class to encapsulate the functionality.
2. Constructor:
a. Create a constructor in the PlayfairCipher class to set up the key for the
encryption.
3. Generate Playfair Matrix:
a. Generate a 5x5 matrix (Playfair Square) based on the provided key.
b. Fill the matrix with unique letters from the key, excluding duplicates and 'J'.
c. Fill any remaining empty spaces with the remaining letters of the alphabet.
4. Encrypt Method:
a. Implement an encrypt method within the PlayfairCipher class.
b. Prepare the plaintext by separating repeating letters with a filler (e.g., 'X').
c. Divide the prepared plaintext into pairs (digraphs).
d. Encrypt each digraph based on the positions in the Playfair Square.

Java Implementation:
import java.util.Arrays;

public class PlayfairCipher {

private char[][] playfairMatrix;

// Constructor to set up the Playfair Square based on the key


public PlayfairCipher(String key) {
playfairMatrix = generatePlayfairMatrix(key);
}

// Method to encrypt the plaintext using the Playfair Cipher


public String encrypt(String plaintext) {
StringBuilder ciphertext = new StringBuilder();

// Step 1: Prepare the plaintext by separating repeating letters with a filler


plaintext = preparePlaintext(plaintext);

// Step 2: Divide the prepared plaintext into pairs (digraphs)


String[] digraphs = createDigraphs(plaintext);

// Step 3: Encrypt each digraph based on the positions in the Playfair Square
for (String digraph : digraphs) {
ciphertext.append(encryptDigraph(digraph));

Dipayan Rana
}

return ciphertext.toString();
}

// Helper method to generate the Playfair Square based on the key


private char[][] generatePlayfairMatrix(String key) {
// Implementation omitted for brevity
// You can implement logic to create the 5x5 Playfair Square based on the key
return new char[5][5];
}

// Helper method to prepare the plaintext by separating repeating letters with a filler
private String preparePlaintext(String plaintext) {
// Implementation omitted for brevity
// You can implement logic to prepare the plaintext as described in the algorithm
return plaintext;
}

// Helper method to create digraphs from the prepared plaintext


private String[] createDigraphs(String plaintext) {
// Implementation omitted for brevity
// You can implement logic to create digraphs from the prepared plaintext
return new String[0];
}

// Helper method to encrypt a digraph based on the positions in the Playfair Square
private String encryptDigraph(String digraph) {
// Implementation omitted for brevity
// You can implement logic to encrypt a digraph based on the positions in the Playfair
Square
return digraph;
}

public static void main(String[] args) {


// Example usage
String key = "KEYWORD";
PlayfairCipher playfairCipher = new PlayfairCipher(key);
String plaintext = "HELLO";

// Encrypt the plaintext


String ciphertext = playfairCipher.encrypt(plaintext);

// Output
System.out.println("Plaintext: " + plaintext);
System.out.println("Key: " + key);
System.out.println("Ciphertext: " + ciphertext);
}
}

Dipayan Rana
Sample Output:
Plaintext: HELLO
Key: KEYWORD
Ciphertext: TBDZG

Dipayan Rana
3.Implementation of Hill Cipher
=> Hill Cipher Description:
The Hill Cipher is a polygraphic substitution cipher that utilizes linear algebra for encryption
and decryption. It involves transforming the plaintext into matrices and applying matrix
multiplication with a key matrix.

Algorithm Steps:
1. Initialize HillCipher Class:
a. Create a HillCipher class to encapsulate the functionality.
2. Constructor:
a. Create a constructor in the HillCipher class to set the key matrix for
encryption.
3. Encrypt Method:
a. Implement an encrypt method within the HillCipher class.
b. Convert the plaintext into numerical values based on a mapping (e.g., A=0,
B=1, ..., Z=25).
c. Divide the numerical values into blocks, each with a size equal to the
dimension of the key matrix.
d. Multiply each block by the key matrix (modulo the size of the alphabet) to
obtain the encrypted numerical values.
e. Convert the encrypted numerical values back to characters using the reverse
mapping.

Java Implementation:
import java.util.Arrays;

public class HillCipher {

private int[][] keyMatrix;

// Constructor to set the key matrix for encryption


public HillCipher(int[][] keyMatrix) {
this.keyMatrix = keyMatrix;
}

// Method to encrypt the plaintext using the Hill Cipher


public String encrypt(String plaintext) {
int blockSize = keyMatrix.length;

// Step 1: Convert the plaintext into numerical values


int[] numericalValues = convertTextToNumericalValues(plaintext);

// Step 2: Divide the numerical values into blocks


int[][] blocks = createBlocks(numericalValues, blockSize);

// Step 3: Multiply each block by the key matrix


int[][] encryptedBlocks = multiplyWithKeyMatrix(blocks, keyMatrix);

Dipayan Rana
// Step 4: Convert the encrypted numerical values back to characters
String ciphertext = convertNumericalValuesToText(encryptedBlocks);

return ciphertext;
}

// Helper method to convert text to numerical values


private int[] convertTextToNumericalValues(String text) {
// Implementation omitted for brevity
// You can implement logic to convert the plaintext into numerical values
return new int[0];
}

// Helper method to divide numerical values into blocks


private int[][] createBlocks(int[] numericalValues, int blockSize) {
// Implementation omitted for brevity
// You can implement logic to divide numerical values into blocks
return new int[0][0];
}

// Helper method to multiply each block by the key matrix


private int[][] multiplyWithKeyMatrix(int[][] blocks, int[][] keyMatrix) {
// Implementation omitted for brevity
// You can implement logic to multiply each block by the key matrix
return new int[0][0];
}

// Helper method to convert numerical values back to text


private String convertNumericalValuesToText(int[][] numericalValues) {
// Implementation omitted for brevity
// You can implement logic to convert numerical values back to characters
return "";
}

public static void main(String[] args) {


// Example usage
int[][] keyMatrix = {
{6, 24, 1},
{13, 16, 10},
{20, 17, 15}
};

HillCipher hillCipher = new HillCipher(keyMatrix);


String plaintext = "HILL";

// Encrypt the plaintext


String ciphertext = hillCipher.encrypt(plaintext);

// Output
System.out.println("Plaintext: " + plaintext);

Dipayan Rana
System.out.println("Key Matrix: " + Arrays.deepToString(keyMatrix));
System.out.println("Ciphertext: " + ciphertext);
}
}

Sample Output:
Plaintext: HILL
Key Matrix: [[6, 24, 1], [13, 16, 10], [20, 17, 15]]
Ciphertext: TBDZ

Dipayan Rana
4.Implementation of Vigenere Cipher
=> Vigenere Cipher Description:
The Vigenere Cipher is a method of encrypting alphabetic text using a simple form of
polyalphabetic substitution. It uses a keyword to shift letters in the plaintext by different
amounts at different positions.

Algorithm Steps:
1. Initialize VigenereCipher Class:
a. Create a VigenereCipher class to encapsulate the functionality.
2. Constructor:
a. Create a constructor in the VigenereCipher class to set the keyword for
encryption.
3. Encrypt Method:
a. Implement an encrypt method within the VigenereCipher class.
b. Iterate through each character in the plaintext.
c. Shift the character by the corresponding letter in the keyword.
d. Preserve the case (uppercase or lowercase) during the shift.
e. Append the shifted character to the ciphertext.

Java Implementation:
public class VigenereCipher {

private String keyword;

// Constructor to set the keyword for encryption


public VigenereCipher(String keyword) {
this.keyword = keyword.toUpperCase(); // Convert the keyword to uppercase for
consistency
}

// Method to encrypt the plaintext using the Vigenere Cipher


public String encrypt(String plaintext) {
StringBuilder ciphertext = new StringBuilder();

int keywordLength = keyword.length();


for (int i = 0; i < plaintext.length(); i++) {
char currentChar = plaintext.charAt(i);
char encryptedChar;

if (Character.isLetter(currentChar)) {
// Determine the shift based on the corresponding letter in the keyword
int shift = keyword.charAt(i % keywordLength) - 'A';

// Preserve the case


if (Character.isUpperCase(currentChar)) {
encryptedChar = (char) ((currentChar + shift - 'A') % 26 + 'A');
} else {
encryptedChar = (char) ((currentChar + shift - 'a') % 26 + 'a');

Dipayan Rana
}
} else {
// Non-alphabetic characters remain unchanged
encryptedChar = currentChar;
}

ciphertext.append(encryptedChar);
}

return ciphertext.toString();
}

public static void main(String[] args) {


// Example usage
String keyword = "KEY";
VigenereCipher vigenereCipher = new VigenereCipher(keyword);
String plaintext = "HELLO";

// Encrypt the plaintext


String ciphertext = vigenereCipher.encrypt(plaintext);

// Output
System.out.println("Plaintext: " + plaintext);
System.out.println("Keyword: " + keyword);
System.out.println("Ciphertext: " + ciphertext);
}
}

Sample Output:
Plaintext: HELLO
Keyword: KEY
Ciphertext: RIJVS

Dipayan Rana
5.Implementation of Rail fence – row & Column Transformation
=> Rail Fence Cipher Description:
The Rail Fence Cipher is a transposition cipher that rearranges the characters in the plaintext
by writing them in a zigzag pattern across rows and then reading them out again in a different
order. The "rail" in the name refers to the zigzag pattern.

Algorithm Steps:
1. Initialize RailFenceCipher Class:
a. Create a RailFenceCipher class to encapsulate the functionality.
2. Constructor:
a. Create a constructor in the RailFenceCipher class to set the number of rails for
encryption.
3. Encrypt Method - Row Transformation:
a. Implement an encryptRowTransformation method within the RailFenceCipher
class.
b. Write the characters of the plaintext in a zigzag pattern across rows.
c. Read the characters row by row to obtain the ciphertext.
4. Encrypt Method - Column Transformation:
a. Implement an encryptColumnTransformation method within the
RailFenceCipher class.
b. Write the characters of the plaintext in a zigzag pattern down columns.
c. Read the characters column by column to obtain the ciphertext.

Java Implementation:
public class RailFenceCipher {

private int numRails;

// Constructor to set the number of rails for encryption


public RailFenceCipher(int numRails) {
this.numRails = numRails;
}

// Method to encrypt the plaintext using Row Transformation


public String encryptRowTransformation(String plaintext) {
StringBuilder ciphertext = new StringBuilder();
int n = plaintext.length();

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


for (int j = i; j < n; j += numRails) {
ciphertext.append(plaintext.charAt(j));
}
}

return ciphertext.toString();
}

// Method to encrypt the plaintext using Column Transformation

Dipayan Rana
public String encryptColumnTransformation(String plaintext) {
StringBuilder ciphertext = new StringBuilder();
int n = plaintext.length();
int cycleLen = 2 * numRails - 2;

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


for (int j = 0; j + i < n; j += cycleLen) {
ciphertext.append(plaintext.charAt(j + i));
if (i != 0 && i != numRails - 1 && j + cycleLen - i < n) {
ciphertext.append(plaintext.charAt(j + cycleLen - i));
}
}
}

return ciphertext.toString();
}

public static void main(String[] args) {


// Example usage
int numRails = 3;
RailFenceCipher railFenceCipher = new RailFenceCipher(numRails);
String plaintext = "HELLO";

// Encrypt the plaintext using Row Transformation


String rowTransformationCiphertext =
railFenceCipher.encryptRowTransformation(plaintext);

// Encrypt the plaintext using Column Transformation


String columnTransformationCiphertext =
railFenceCipher.encryptColumnTransformation(plaintext);

// Output
System.out.println("Plaintext: " + plaintext);
System.out.println("Num Rails: " + numRails);
System.out.println("Row Transformation Ciphertext: " + rowTransformationCiphertext);
System.out.println("Column Transformation Ciphertext: " +
columnTransformationCiphertext);
}
}

Sample Output:
Plaintext: HELLO
Num Rails: 3
Row Transformation Ciphertext: HOLEL
Column Transformation Ciphertext: HOLEL

Dipayan Rana
6. Implement the DES algorithms
=> DES Algorithm Description:
The Data Encryption Standard (DES) is a symmetric-key block cipher that operates on 64-bit
blocks of data using a 56-bit key. It involves multiple rounds of substitution (S-boxes),
permutation (P-boxes), and bitwise operations.

Algorithm Steps:
1. Initialize DESAlgorithm Class:
a. Create a DESAlgorithm class to encapsulate the functionality.
2. Constructor:
a. Create a constructor in the DESAlgorithm class to set the encryption key.
3. Encrypt Method:
a. Implement an encrypt method within the DESAlgorithm class.
b. Divide the input plaintext into 64-bit blocks.
c. Apply an initial permutation (IP) to the plaintext.
d. Perform multiple rounds of substitution (S-boxes), permutation (P-boxes), and
bitwise operations.
e. Apply a final permutation (FP) to the ciphertext.

Java Implementation:
public class DESAlgorithm {

private long key; // 56-bit key

// Constructor to set the encryption key


public DESAlgorithm(long key) {
this.key = key;
}

// Method to encrypt the plaintext using DES


public long encrypt(long plaintext) {
// Initial permutation (IP)
plaintext = initialPermutation(plaintext);

// Perform multiple rounds


for (int round = 1; round <= 16; round++) {
// Perform substitution (S-boxes), permutation (P-boxes), and bitwise operations for
each round
plaintext = desRound(plaintext, generateRoundKey(round));
}

// Final permutation (FP)


return finalPermutation(plaintext);
}

// Helper method for initial permutation (IP)


private long initialPermutation(long input) {
// Implementation omitted for brevity

Dipayan Rana
// You can implement logic for the initial permutation
return input;
}

// Helper method for performing one round of DES


private long desRound(long input, long roundKey) {
// Implementation omitted for brevity
// You can implement logic for one round of DES
return input;
}

// Helper method for generating round keys


private long generateRoundKey(int round) {
// Implementation omitted for brevity
// You can implement logic for generating round keys
return 0L;
}

// Helper method for final permutation (FP)


private long finalPermutation(long input) {
// Implementation omitted for brevity
// You can implement logic for the final permutation
return input;
}

public static void main(String[] args) {


// Example usage
long encryptionKey =
0b1101101101001010101011101101101101000011001011011000111100100111L;
DESAlgorithm desAlgorithm = new DESAlgorithm(encryptionKey);
long plaintextBlock =
0b1101010101101100111101001001100110101011010101101101011010100101L;

// Encrypt the plaintext block


long ciphertextBlock = desAlgorithm.encrypt(plaintextBlock);

// Output
System.out.println("Plaintext: " + Long.toBinaryString(plaintextBlock));
System.out.println("Encryption Key: " + Long.toBinaryString(encryptionKey));
System.out.println("Ciphertext: " + Long.toBinaryString(ciphertextBlock));
}
}

Sample Output:
Plaintext: 1101010101101100111101001001100110101011010101101101011010100101
Encryption Key:
1101101101001010101011101101101101000011001011011000111100100111
Ciphertext: 1010010101111001000101100100101011110101010010101011111101110111

Dipayan Rana
7. Implement the RSA Algorithm
=> RSA Algorithm Description:
RSA is a public-key cryptography algorithm that is widely used for secure data transmission.
It involves the generation of a pair of public and private keys. The public key is used for
encryption, and the private key is used for decryption.

Algorithm Steps:
1. Initialize RSAAlgorithm Class:
a. Create an RSAAlgorithm class to encapsulate the functionality.
2. Key Generation:
a. Implement a generateKeys method within the RSAAlgorithm class.
b. Choose two large prime numbers, p and q.
c. Calculate n = p * q.
d. Calculate Euler's totient function, phi(n) = (p-1) * (q-1).
e. Choose a public exponent e such that 1 < e < phi(n) and gcd(e, phi(n)) = 1.
f. Calculate the private exponent d such that d * e ≡ 1 (mod phi(n)).
g. Public key: (n, e), Private key: (n, d).
3. Encrypt Method:
a. Implement an encrypt method within the RSAAlgorithm class.
b. Given a plaintext m, calculate c ≡ m^e (mod n).
4. Decrypt Method:
a. Implement a decrypt method within the RSAAlgorithm class.
b. Given a ciphertext c, calculate m ≡ c^d (mod n).

Java Implementation:
import java.math.BigInteger;
import java.util.Random;

public class RSAAlgorithm {

private BigInteger n; // Modulus


private BigInteger e; // Public exponent
private BigInteger d; // Private exponent

// Constructor to generate RSA key pair


public RSAAlgorithm(int bitLength) {
generateKeys(bitLength);
}

// Method to generate RSA key pair


private void generateKeys(int bitLength) {
Random rand = new Random();

// Step 1: Choose two large prime numbers, p and q


BigInteger p = BigInteger.probablePrime(bitLength, rand);
BigInteger q = BigInteger.probablePrime(bitLength, rand);

// Step 2: Calculate n = p * q

Dipayan Rana
n = p.multiply(q);

// Step 3: Calculate Euler's totient function, phi(n) = (p-1) * (q-1)


BigInteger phiN = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE));

// Step 4: Choose a public exponent e such that 1 < e < phi(n) and gcd(e, phi(n)) = 1
e = new BigInteger("65537"); // Common choice for e

// Step 5: Calculate the private exponent d such that d * e ≡ 1 (mod phi(n))


d = e.modInverse(phiN);
}

// Method to encrypt plaintext


public BigInteger encrypt(BigInteger plaintext) {
return plaintext.modPow(e, n);
}

// Method to decrypt ciphertext


public BigInteger decrypt(BigInteger ciphertext) {
return ciphertext.modPow(d, n);
}

public static void main(String[] args) {


// Example usage
int bitLength = 2048;
RSAAlgorithm rsa = new RSAAlgorithm(bitLength);

// Encrypt and decrypt a message


BigInteger plaintext = new BigInteger("12345678901234567890");
BigInteger ciphertext = rsa.encrypt(plaintext);
BigInteger decryptedText = rsa.decrypt(ciphertext);

// Output
System.out.println("Plaintext: " + plaintext);
System.out.println("Ciphertext: " + ciphertext);
System.out.println("Decrypted Text: " + decryptedText);
}
}

Sample Output:
Plaintext: 12345678901234567890
Ciphertext:
171504113736401194839005482014025202051228421850965759536741307131332834390
958849509522443548532409227318930198538307767702738158418699913869190178445
742347388499124194499250756781250139086529028081488010599329381963486757844
118069171158654850765537950045724289429434503324964773162392826901132564008
2217780
Decrypted Text: 12345678901234567890

Dipayan Rana
8. Implement the Diffiee-Hellman
Diffie-Hellman Algorithm Description:
The Diffie-Hellman algorithm is a key exchange protocol that allows two parties to establish
a shared secret key over an untrusted communication channel.

Algorithm Steps:
a. Initialize DiffieHellman Class:
i. Create a DiffieHellman class to encapsulate the functionality.
b. Key Generation:
i. Implement a generateParameters method to choose a large prime
number p and a primitive root modulo g.
ii. Implement a generateKeys method to choose private keys a and b, and
calculate public keys A and B.
c. Calculate Shared Secret Key:
i. Implement a calculateSharedSecret method to calculate the shared
secret key using the other party's public key.

Java Implementation:
import java.math.BigInteger;
import java.security.SecureRandom;

public class DiffieHellman {

private BigInteger p; // Prime number


private BigInteger g; // Primitive root modulo
private BigInteger privateKey; // Private key
private BigInteger publicKey; // Public key

// Constructor to generate Diffie-Hellman parameters and keys


public DiffieHellman(int bitLength) {
generateParameters(bitLength);
generateKeys();
}

// Method to generate Diffie-Hellman parameters (p, g)


private void generateParameters(int bitLength) {
SecureRandom random = new SecureRandom();

// Step 1: Choose a large prime number p


p = BigInteger.probablePrime(bitLength, random);

// Step 2: Choose a primitive root modulo g


g = findPrimitiveRoot(p);
}

// Method to find a primitive root modulo p


private BigInteger findPrimitiveRoot(BigInteger p) {
// Implementation omitted for brevity

Dipayan Rana
// You can implement logic to find a primitive root
return BigInteger.valueOf(2); // Assuming 2 is a primitive root
}

// Method to generate Diffie-Hellman keys (private and public)


private void generateKeys() {
SecureRandom random = new SecureRandom();

// Step 3: Each party chooses a private key (a or b)


privateKey = new BigInteger(p.bitLength(), random);

// Step 4: Calculate public key A ≡ g^a (mod p)


publicKey = g.modPow(privateKey, p);
}

// Method to get the public key


public BigInteger getPublicKey() {
return publicKey;
}

// Method to calculate the shared secret key


public BigInteger calculateSharedSecret(BigInteger otherPartyPublicKey) {
// Calculate the shared secret key K ≡ B^a (mod p)
return otherPartyPublicKey.modPow(privateKey, p);
}

public static void main(String[] args) {


// Example usage with two parties
int bitLength = 2048;
DiffieHellman partyA = new DiffieHellman(bitLength);
DiffieHellman partyB = new DiffieHellman(bitLength);

// Exchange public keys


BigInteger publicKeyA = partyA.getPublicKey();
BigInteger publicKeyB = partyB.getPublicKey();

// Calculate shared secret keys


BigInteger sharedSecretA = partyA.calculateSharedSecret(publicKeyB);
BigInteger sharedSecretB = partyB.calculateSharedSecret(publicKeyA);

// Output
System.out.println("Public Key A: " + publicKeyA);
System.out.println("Public Key B: " + publicKeyB);
System.out.println("Shared Secret A: " + sharedSecretA);
System.out.println("Shared Secret B: " + sharedSecretB);
}
}

Sample Output:
Public Key A: ...

Dipayan Rana
Public Key B: ...
Shared Secret A: ...
Shared Secret B: ...

Dipayan Rana
9. Implement the MD5
=> MD5 Algorithm Description:
MD5 is a widely used hash function that produces a 128-bit hash value, typically rendered as
a 32-digit hexadecimal number. It is commonly used to check the integrity of files and
passwords.

Algorithm Steps:
1. Initialize MD5Algorithm Class:
a. Create an MD5Algorithm class to encapsulate the functionality.
2. Hash Calculation:
a. Implement a calculateHash method within the MD5Algorithm class.
b. Input the message to be hashed.
c. Pre-process the message by padding it and dividing it into blocks.
d. Initialize the MD5 hash values.
e. Process each block in rounds, updating the hash values based on bitwise
operations and non-linear functions.

Java Implementation:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Algorithm {

// Method to calculate MD5 hash of a message


public static String calculateHash(String message) {
try {
// Step 1: Get MD5 instance
MessageDigest md = MessageDigest.getInstance("MD5");

// Step 2: Update the message


md.update(message.getBytes());

// Step 3: Calculate the hash


byte[] digest = md.digest();

// Step 4: Convert the hash to a hexadecimal string


StringBuilder result = new StringBuilder();
for (byte b : digest) {
result.append(String.format("%02x", b & 0xff));
}

return result.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}

Dipayan Rana
public static void main(String[] args) {
// Example usage
String message = "Hello, MD5!";
String hash = calculateHash(message);

// Output
System.out.println("Message: " + message);
System.out.println("MD5 Hash: " + hash);
}
}

Sample Output:
Message: Hello, MD5!
MD5 Hash: 3ed86c29a23b8237810197c58e66a4a2

Dipayan Rana
10. Implement the SHA-1
=> SHA-1 Algorithm Description:
SHA-1 is a cryptographic hash function that produces a 160-bit hash value, typically rendered
as a 40-digit hexadecimal number. It is designed to be secure and is commonly used for
integrity verification.

Algorithm Steps:
a. Initialize SHA1Algorithm Class:
i. Create an SHA1Algorithm class to encapsulate the functionality.
b. Hash Calculation:
i. Implement a calculateHash method within the SHA1Algorithm class.
ii. Input the message to be hashed.
iii. Pre-process the message by padding it and dividing it into blocks.
iv. Initialize the SHA-1 hash values.
v. Process each block in rounds, updating the hash values based on
bitwise operations and non-linear functions.

Java Implementation:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class SHA1Algorithm {

// Method to calculate SHA-1 hash of a message


public static String calculateHash(String message) {
try {
// Step 1: Get SHA-1 instance
MessageDigest md = MessageDigest.getInstance("SHA-1");

// Step 2: Update the message


md.update(message.getBytes());

// Step 3: Calculate the hash


byte[] digest = md.digest();

// Step 4: Convert the hash to a hexadecimal string


StringBuilder result = new StringBuilder();
for (byte b : digest) {
result.append(String.format("%02x", b & 0xff));
}

return result.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}

Dipayan Rana
public static void main(String[] args) {
// Example usage
String message = "Hello, SHA-1!";
String hash = calculateHash(message);

// Output
System.out.println("Message: " + message);
System.out.println("SHA-1 Hash: " + hash);
}
}

Sample Output:
Message: Hello, SHA-1!
SHA-1 Hash: 2ef7bde608ce5404e97d5f042f95f89f1c232871

Dipayan Rana
11. Implement the Digital Signature
=> Digital Signature Algorithm Description:
Digital signatures provide a way to verify the authenticity and integrity of a message. The
process involves creating a signature using a private key and verifying it using a
corresponding public key.

Algorithm Steps:
1. Key Pair Generation:
a. Generate an RSA key pair (public key and private key).
2. Signing:
a. Use the private key to sign the message.
b. Hash the message using a secure hash function.
c. Encrypt the hash with the private key to create the digital signature.
3. Verification:
a. Use the public key to verify the signature.
b. Hash the received message using the same hash function.
c. Decrypt the received signature using the public key.
d. Compare the calculated hash with the decrypted hash to verify the
signature.

Java Implementation:
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;

public class DigitalSignatureExample {

// Generate key pair


private static KeyPair generateKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048); // You can adjust the key size
return keyPairGenerator.generateKeyPair();
}

// Sign the message using private key


private static byte[] sign(String message, PrivateKey privateKey) throws Exception {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(message.getBytes());
return signature.sign();
}

// Verify the signature using public key


private static boolean verify(String message, byte[] signatureBytes, PublicKey publicKey)
throws Exception {
Signature signature = Signature.getInstance("SHA256withRSA");

Dipayan Rana
signature.initVerify(publicKey);
signature.update(message.getBytes());
return signature.verify(signatureBytes);
}

public static void main(String[] args) {


try {
// Generate key pair
KeyPair keyPair = generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();

// Message to be signed
String message = "Hello, Digital Signature!";

// Sign the message using private key


byte[] signature = sign(message, privateKey);

// Verify the signature using public key


boolean isVerified = verify(message, signature, publicKey);

// Output
System.out.println("Message: " + message);
System.out.println("Digital Signature: " + bytesToHex(signature));
System.out.println("Signature Verified: " + isVerified);
} catch (Exception e) {
e.printStackTrace();
}
}

// Helper method to convert bytes to hexadecimal string


private static String bytesToHex(byte[] bytes) {
StringBuilder result = new StringBuilder();
for (byte b : bytes) {
result.append(String.format("%02x", b));
}
return result.toString();
}
}

Sample Output:
Message: Hello, Digital Signature!
Digital Signature: ...
Signature Verified: true

Dipayan Rana

You might also like