Encryption


  1. Playfair Encryption

import java.util.HashSet;
import java.util.Scanner;

public class PlayfairCipher {
private static final int SIZE = 5;
private char[][] keyMatrix = new char[SIZE][SIZE];
private String key;

public PlayfairCipher(String key) {
    this.key = key.toUpperCase();
    createKeyMatrix();
}

private void createKeyMatrix() {
    StringBuilder keyString = new StringBuilder();
    HashSet<Character> set = new HashSet<>();

    for (char ch : key.toCharArray()) {
        if (ch >= 'A' && ch <= 'Z' && !set.contains(ch) && ch != 'J') {
            set.add(ch);
            keyString.append(ch);
        }
    }

    for (char ch = 'A'; ch <= 'Z'; ch++) {
        if (!set.contains(ch) && ch != 'J') {
            keyString.append(ch);
        }
    }

    int index = 0;
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            keyMatrix[i][j] = keyString.charAt(index++);
        }
    }
}

private String formatMessage(String message) {
    message = message.toUpperCase().replaceAll("[^A-Z]", "");
    StringBuilder formattedMessage = new StringBuilder();

    for (int i = 0; i < message.length(); i++) {
        formattedMessage.append(message.charAt(i));
        if (i + 1 < message.length() && message.charAt(i) == message.charAt(i + 1)) {
            formattedMessage.append('X'); // Insert 'X' between duplicate letters
        }
    }

    if (formattedMessage.length() % 2 != 0) {
        formattedMessage.append('X'); // Append 'X' if the length is odd
    }

    return formattedMessage.toString();
}

private String encrypt(String message) {
    StringBuilder encryptedMessage = new StringBuilder();
    message = formatMessage(message);

    for (int i = 0; i < message.length(); i += 2) {
        char first = message.charAt(i);
        char second = message.charAt(i + 1);
        int[] firstPos = getPosition(first);
        int[] secondPos = getPosition(second);

        if (firstPos[0] == secondPos[0]) { // Same row
            encryptedMessage.append(keyMatrix[firstPos[0]][(firstPos[1] + 1) % SIZE]);
            encryptedMessage.append(keyMatrix[secondPos[0]][(secondPos[1] + 1) % SIZE]);
        } else if (firstPos[1] == secondPos[1]) { // Same column
            encryptedMessage.append(keyMatrix[(firstPos[0] + 1) % SIZE][firstPos[1]]);
            encryptedMessage.append(keyMatrix[(secondPos[0] + 1) % SIZE][secondPos[1]]);
        } else { // Rectangle
            encryptedMessage.append(keyMatrix[firstPos[0]][secondPos[1]]);
            encryptedMessage.append(keyMatrix[secondPos[0]][firstPos[1]]);
        }
    }

    return encryptedMessage.toString();
}

private int[] getPosition(char ch) {
    for (int i = 0; i < SIZE; i++) {
        for (int j = 0; j < SIZE; j++) {
            if (keyMatrix[i][j] == ch) {
                return new int[]{i, j};
            }
        }
    }
    return null;
}

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    String key = "INFORMATION";
    PlayfairCipher playfairCipher = new PlayfairCipher(key);

    System.out.println("Enter the message to encrypt:");
    String message = scanner.nextLine();
    String encryptedMessage = playfairCipher.encrypt(message);

    System.out.println("Encrypted Message: " + encryptedMessage);
    scanner.close();
}

}

  1. Transposition Single encryption

import java.util.Scanner;

public class SingleColumnarTransposition {

// Method to encrypt the message
public static String encrypt(String message, String key) {
    // Remove spaces and convert to uppercase
    message = message.replaceAll(" ", "").toUpperCase();
    int keyLength = key.length();
    int messageLength = message.length();
    
    // Calculate number of rows needed
    int rows = (int) Math.ceil((double) messageLength / keyLength);
    
    // Create a 2D array to hold the characters
    char[][] grid = new char[rows][keyLength];
    
    // Fill the grid with the message
    for (int i = 0; i < messageLength; i++) {
        grid[i / keyLength][i % keyLength] = message.charAt(i);
    }
    
    // Fill remaining cells with padding character '_'
    for (int i = messageLength; i < rows * keyLength; i++) {
        grid[i / keyLength][i % keyLength] = '_';
    }
    
    // Create an array of column indices based on the key
    int[] keyOrder = new int[keyLength];
    for (int i = 0; i < keyLength; i++) {
        keyOrder[i] = i;
    }
    
    // Sort the keyOrder based on the alphabetical order of the key
    for (int i = 0; i < keyLength; i++) {
        for (int j = i + 1; j < keyLength; j++) {
            if (key.charAt(keyOrder[i]) > key.charAt(keyOrder[j])) {
                // Swap
                int temp = keyOrder[i];
                keyOrder[i] = keyOrder[j];
                keyOrder[j] = temp;
            }
        }
    }
    
    // Read the columns in the order defined by the sorted key
    StringBuilder cipherText = new StringBuilder();
    for (int col : keyOrder) {
        for (int row = 0; row < rows; row++) {
            cipherText.append(grid[row][col]);
        }
    }
    
    return cipherText.toString();
}

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    
    // Take user input for the message and key
    System.out.println("Enter the message to encrypt:");
    String message = scanner.nextLine();
    
    System.out.println("Enter the key:");
    String key = scanner.nextLine();
    
    // Encrypt the message
    String encryptedMessage = encrypt(message, key);
    System.out.println("Encrypted Message: " + encryptedMessage);
    
    scanner.close();
}

}

  1. Transposition double encryption

import java.util.*;

public class DoubleColumnarTransposition {

// Method to encrypt using a single key
public static String encrypt(String message, String key) {
    int col = key.length();
    int row = (int) Math.ceil((double) message.length() / col);
    char[][] matrix = new char[row][col];

    // Fill the matrix with the message
    for (int i = 0, k = 0; i < row; i++) {
        for (int j = 0; j < col; j++) {
            if (k < message.length()) {
                matrix[i][j] = message.charAt(k++);
            } else {
                matrix[i][j] = '_'; // Padding character
            }
        }
    }

    // Create a list of column indices based on the key
    List<Integer> keyOrder = new ArrayList<>();
    for (char c : key.toCharArray()) {
        keyOrder.add((int) c);
    }
    Collections.sort(keyOrder);

    StringBuilder cipher = new StringBuilder();
    for (int i = 0; i < col; i++) {
        int index = key.indexOf((char) keyOrder.get(i).intValue());
        for (int j = 0; j < row; j++) {
            cipher.append(matrix[j][index]);
        }
    }
    return cipher.toString();
}

// Method to perform double encryption
public static String doubleEncrypt(String message, String key1, String key2) {
    String firstEncryption = encrypt(message, key1);
    return encrypt(firstEncryption, key2);
}

public static void main(String[] args) {
    String message = "PATIENT RECORDS";
    String key1 = "HOSPITAL";
    String key2 = "SECURE";

    String encryptedMessage = doubleEncrypt(message, key1, key2);
    System.out.println("Encrypted Message: " + encryptedMessage);
}

}

  1. Caesar

import java.util.*;
class Caesar
{
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
System.out.println("Enter Plaintext");
String pt=sc.nextLine();

    System.out.println("Enter shift value");
    int shift=sc.nextInt();
    String encoded="";
    
    for(int x=0;x<pt.length();x++)
    {
        char ch=pt.charAt(x);
        if(Character.isUpperCase(ch))
        {
            encoded+=(char)(((int)ch+ shift - 65) % 26 + 65);
        }
        else if(Character.isDigit(ch))
        {
            int num=(ch + shift - '0') % 10;
            encoded+=Integer.toString(num);
        }
        else
        {
            encoded+=(char)(((int)ch + shift - 97) % 26 + 97);
        }
    }
    System.out.println("Encrypted text : "+encoded);
}

}

  1. RailFence

import java.util.*;
class Railfence
{
public static String encrypt(String plain, int key)
{
char rail[][]=new char[key][plain.length()];
for(int x=0;x<key;x++)
{
Arrays.fill(rail[x], '\n');
}
boolean dirDown=false;
int row=0, col=0;

       for(int x=0;x<plain.length();x++)
       {
            if(row==0 || row==key-1)
            {
                dirDown=!dirDown;
            }
            rail[row][col++]=plain.charAt(x);
            
            if(dirDown){
            row++;
            }
            else{
            row--;
            }
       }
       
       StringBuilder result=new StringBuilder();
       for(int x=0;x<key;x++)
       {
           for(int y=0;y<plain.length();y++)
           {
               if(rail[x][y]!='\n')
               {
                   result.append(rail[x][y]);
               }
           }
       }
       return result.toString();
   }
   
   public static String decrypt(String cipher, int key)
   {
       int len=cipher.length();
       char rail[][]=new char[key][len];
       
       for(int x=0;x<key;x++)
       {
           Arrays.fill(rail[x],'\n');
       }
       
       boolean dirDown=true;
       int row=0, col=0;
       
       for(int x=0;x<len;x++)
       {
           if(row==0)
           {
               dirDown=true;;
           }
           if(row==key-1)
           {
               dirDown=false;
           }
           rail[row][col]='*';
           col++;
           
           if(dirDown){
               row++;
           }
           else{
               row--;
           }
       }
       
       StringBuilder result=new StringBuilder();
       int index=0;
       for(int x=0;x<key;x++)
       {
           for(int y=0;y<len;y++)
           {
               if(rail[x][y]=='*' && index<len)
               {
                   rail[x][y]=cipher.charAt(index++);
               }
           }
       }
       row=0;
       col=0;
       for(int x=0;x<key;x++)
       {
           for(int y=0;y<len;y++)
           {
               if(row==0)
               {
                   dirDown=true;
               }
               if(row==key-1)
               {
                   dirDown=false;
               }
               if(rail[x][y]!='*')
               {
                    result.append(rail[row][col]);
                    col++;
               }
               
               if(dirDown)
               {
                   row++;
               }
               else
               {
                   row--;
               }
           }
           if(col>=len)
           {
               break;
           }
        }
        return result.toString();
    }
    public static void main(String args[])
    {
           Scanner sc=new Scanner(System.in);
           System.out.println("Enter plaintext");
           String plain=sc.next();
           System.out.println("Enter key");
           int key=sc.nextInt();
           String output=encrypt(plain,key);
           System.out.println("Cipher text:"+output);
           System.out.println("Enter cipher text");
           String cipher=sc.next();
           String output2=decrypt(cipher,key);
           System.out.print("Plain text: "+output2);
    }

}

  1. Hill Cipher

import java.util.Scanner;
public class HillCipher{

static int[][] key = {
    {6, 24},
    {1, 13}
};

static final int MOD = 26;

static int charToNum(char c) {
    return c - 'A';
}

static char numToChar(int n) {
    return (char) ((n % MOD + MOD) % MOD + 'A');
}

static String encryptPair(char a, char b) {
    int x = charToNum(a);
    int y = charToNum(b);
    int c1 = (key[0][0] * x + key[0][1] * y) % MOD;
    int c2 = (key[1][0] * x + key[1][1] * y) % MOD;
    return "" + numToChar(c1) + numToChar(c2);
}

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.print("Enter the text to encrypt (A-Z only): ");
    String input = sc.nextLine().toUpperCase().replaceAll("[^A-Z]", "");

    if (input.length() % 2 != 0) {
        input += "X"; // pad with X if odd
    }

    StringBuilder encrypted = new StringBuilder();
    for (int i = 0; i < input.length(); i += 2) {
        encrypted.append(encryptPair(input.charAt(i), input.charAt(i + 1)));
    }

    System.out.println("Encrypted: " + encrypted);
}

}

  1. AES

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Scanner;

public class SimpleAESEncryption {

// Method to encrypt the plaintext
public static String encrypt(String plaintext, String key) throws Exception {
    SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes());
    return Base64.getEncoder().encodeToString(encryptedBytes);
}

// Method to decrypt the ciphertext
public static String decrypt(String ciphertext, String key) throws Exception {
    SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "AES");
    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secretKey);
    byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(ciphertext));
    return new String(decryptedBytes);
}

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    
    // Take user input for plaintext and key
    System.out.println("Enter the plaintext:");
    String plaintext = scanner.nextLine();
    
    System.out.println("Enter a 16-character key (128 bits):");
    String key = scanner.nextLine();
    
    // Ensure the key is 16 characters long
    if (key.length() != 16) {
        System.out.println("Key must be 16 characters long.");
        return;
    }
    
    try {
        // Encrypt the plaintext
        String ciphertext = encrypt(plaintext, key);
        System.out.println("Ciphertext: " + ciphertext);
        
        // Decrypt the ciphertext
        String decryptedText = decrypt(ciphertext, key);
        System.out.println("Decrypted Plaintext: " + decryptedText);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        scanner.close();
    }
}

}

  1. DES

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Scanner;

public class SimpleDESEncryption {

// Method to encrypt the plaintext
public static String encrypt(String plaintext, String key) throws Exception {
    SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "DES");
    Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes());
    return Base64.getEncoder().encodeToString(encryptedBytes);
}

// Method to decrypt the ciphertext
public static String decrypt(String ciphertext, String key) throws Exception {
    SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(), "DES");
    Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secretKey);
    byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(ciphertext));
    return new String(decryptedBytes);
}

public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    
    // Take user input for plaintext and key
    System.out.println("Enter the plaintext:");
    String plaintext = scanner.nextLine();
    
    System.out.println("Enter an 8-byte key:");
    String key = scanner.nextLine();
    
    // Ensure the key is 8 bytes long
    if (key.length() != 8) {
        System.out.println("Key must be 8 bytes long.");
        return;
    }
    
    try {
        // Encrypt the plaintext
        String ciphertext = encrypt(plaintext, key);
        System.out.println("Ciphertext: " + ciphertext);
        
        // Decrypt the ciphertext
        String decryptedText = decrypt(ciphertext, key);
        System.out.println("Decrypted Plaintext: " + decryptedText);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        scanner.close();
    }
}

}

  1. RSA

public class RSA {

// Function to compute modular exponentiation
public static int modExp(int base, int exp, int mod) {
    int result = 1;
    base = base % mod; // Update base if it's more than or equal to mod
    while (exp > 0) {
        // If exp is odd, multiply base with result
        if ((exp & 1) == 1) {
            result = (result * base) % mod;
        }
        // exp must be even now
        exp = exp >> 1; // Divide exp by 2
        base = (base * base) % mod; // Square the base
    }
    return result;
}

// Function to generate keys
public static int[] generateKeys() {
    int p = 11; // First prime
    int q = 13; // Second prime
    int n = p * q; // n = p * q
    int phi = (p - 1) * (q - 1); // φ(n)

    // Choose e
    int e = 3; // Common choice for e
    int d = 0;

    // Calculate d such that (d * e) % φ(n) = 1
    for (int i = 1; i < phi; i++) {
        if ((i * e) % phi == 1) {
            d = i;
            break;
        }
    }

    return new int[]{e, d, n}; // Return e, d, n
}

// Function to encrypt the message
public static int encrypt(int message, int e, int n) {
    return modExp(message, e, n);
}

// Function to decrypt the message
public static int decrypt(int ciphertext, int d, int n) {
    return modExp(ciphertext, d, n);
}

public static void main(String[] args) {
    // Generate keys
    int[] keys = generateKeys();
    int e = keys[0];
    int d = keys[1];
    int n = keys[2];
    int decryptt=7;
    int message = 7;
    System.out.println("Public Key (e, n): (" + e + ", " + n + ")");
    System.out.println("Private Key (d, n): (" + d + ", " + n + ")"); 
    int cipher = encrypt(message, e, n);
    int decrypt = decrypt(cipher, d, n);
    System.out.println("Original Message: " + message);

    // Encrypt the message
    System.out.println("Encrypted Message: " + cipher);

    // Decrypt the message
    System.out.println("Decrypted Message: " + decryptt);
}

}