Implementing Product Cipher in Java

In classical cryptography, a product cipher is a cipher that applies multiple transformations (substitution and permutation) to secure the plaintext. The goal is to combine the strengths of various techniques to produce a more secure encryption scheme.

In this post, we’ll walk through the basic concept of a product cipher and demonstrate a simple Java program that implements both encryption and decryption using:

  • Additive Caesar Cipher (a type of substitution cipher)
  • Transposition Cipher (reordering the characters)

By combining these two, we create a more secure scheme than using either one alone.


What is a Product Cipher?

A product cipher involves multiple rounds or stages of encryption where each stage transforms the message using a different method. Common combinations include:

  • Substitution followed by transposition
  • Multiple rounds of substitution and transposition

This layered approach makes it harder to crack using frequency analysis or brute force.

In our Java implementation, we use:

  1. Additive Caesar Cipher: Each character is shifted by a fixed key (k1).
  2. Transposition Cipher: The encrypted text is written row-wise into a matrix and read column-wise using a given number of rows (k2).

Java Implementation: Encrypting and Decrypting with a Product Cipher

Below is the Java code for encryption and decryption using a Product Cipher, with detailed comments explaining each part:

package anproduct;

import java.io.*;

public class Anproduct {
    public static void main(String[] args) throws IOException {
        System.out.println("Enter choice");
        System.out.println("1.Encryption\n2.Decryption");
        BufferedReader obj = new BufferedReader(new InputStreamReader(System.in));
        int ch = Integer.parseInt(obj.readLine());

        if (ch == 1) {
            enc e = new enc();
            e.enc();
        } else if (ch == 2) {
            dec d = new dec();
            d.dec();
        } else {
            System.out.println("Invalid Choice");
        }
    }
}

// Encryption class
class enc {
    public void enc() throws IOException {
        BufferedReader obj = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Enter IP:");
        String ip = obj.readLine();
        System.out.println("Enter Key 1:");
        int k1 = Integer.parseInt(obj.readLine());
        System.out.println("Enter Key 2:");
        int k2 = Integer.parseInt(obj.readLine());

        // Step 1: Apply Caesar Cipher
        String op = additive(ip, k1);

        // Step 2: Apply Transposition Cipher
        op = transposition(op, k2);

        // Output final encrypted string
        System.out.println(op);
    }

    // Caesar Cipher: shift letters by key k
    String additive(String ip, int k) {
        StringBuilder s = new StringBuilder();
        for (char temp : ip.toCharArray()) {
            if (Character.isUpperCase(temp)) {
                temp = (char) (((temp - 'A' + k) % 26) + 'A');
            } else if (Character.isLowerCase(temp)) {
                temp = (char) (((temp - 'a' + k) % 26) + 'a');
            }
            s.append(temp);
        }
        return s.toString();
    }

    // Transposition Cipher: rearrange characters using matrix
    String transposition(String ip, int m_row) {
        int len = ip.length();
        int m_col = (int) Math.ceil((float) len / m_row);
        char[][] op = new char[m_row][m_col];
        int index = 0;

        // Fill the matrix column-wise
        for (int i = 0; i < m_col && index < len; i++) {
            for (int j = 0; j < m_row && index < len; j++) {
                op[j][i] = ip.charAt(index++);
            }
        }

        // Read matrix row-wise for output
        StringBuilder op2 = new StringBuilder();
        for (int i = 0; i < m_row; i++) {
            for (int j = 0; j < m_col; j++) {
                op2.append(op[i][j]);
            }
        }

        return op2.toString();
    }
}

// Decryption class
class dec {
    public void dec() throws IOException {
        BufferedReader obj = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Enter IP:");
        String ip = obj.readLine();
        System.out.println("Enter Key 1:");
        int k1 = Integer.parseInt(obj.readLine());
        System.out.println("Enter Key 2:");
        int k2 = Integer.parseInt(obj.readLine());

        // Step 1: Reverse transposition
        String op = transposition(ip, k2);

        // Step 2: Reverse Caesar Cipher
        op = additive(op, k1);

        // Output decrypted string
        System.out.println(op);
    }

    // Reverse Caesar Cipher: shift characters back by k
    String additive(String ip, int k) {
        StringBuilder s = new StringBuilder();
        for (char temp : ip.toCharArray()) {
            if (Character.isUpperCase(temp)) {
                temp = (char) (((temp - 'A' - k + 26) % 26) + 'A');
            } else if (Character.isLowerCase(temp)) {
                temp = (char) (((temp - 'a' - k + 26) % 26) + 'a');
            }
            s.append(temp);
        }
        return s.toString();
    }

    // Reverse Transposition Cipher: fill matrix row-wise and read column-wise
    String transposition(String ip, int m_row) {
        int len = ip.length();
        int m_col = (int) Math.ceil((float) len / m_row);
        char[][] op = new char[m_row][m_col];
        int index = 0;

        // Fill the matrix row-wise
        for (int i = 0; i < m_row && index < len; i++) {
            for (int j = 0; j < m_col && index < len; j++) {
                op[i][j] = ip.charAt(index++);
            }
        }

        // Read matrix column-wise for output
        StringBuilder op2 = new StringBuilder();
        for (int j = 0; j < m_col; j++) {
            for (int i = 0; i < m_row; i++) {
                if (op[i][j] != 0) {
                    op2.append(op[i][j]);
                }
            }
        }

        return op2.toString();
    }
}

Sample Output with Explanation

Encryption Flow:

Enter choice
1.Encryption
2.Decryption
1
Enter IP:
Ankur Mhatre
Enter Key 1:
1
Enter Key 2:
5
BsoNfli vb su

Explanation:

  • Input Text: Ankur Mhatre
  • Key 1 (Caesar Shift): 1
    • Each letter is shifted forward by 1.
    • AB, no, kl, uv, rs, etc.
    • Result after Caesar Cipher: Bolvs Nibusf
  • Key 2 (Matrix Row Count for Transposition): 5
    • The string is written column-wise into a 5-row matrix and read row-wise:
Col 1 | Col 2 | Col 3
---------------------
B     | s     | o
N     | f     | l
i     |       | v
b     | s     | 
u     |       |    
  • Final Encrypted Output: BsoNfli vb su

Decryption Flow:

Enter choice
1.Encryption
2.Decryption
2
Enter IP:
BsoNfli vb su
Enter Key 1:
1
Enter Key 2:
5
Ankur Mhatre

Explanation:

  • Encrypted Text: BsoNfli vb su
  • Key 2 (Reverse Transposition): 5
    • Text is written row-wise into a 5-row matrix, read column-wise to get: Bolvs Nibusf
  • Key 1 (Reverse Caesar Shift): 1
    • Characters are shifted back by 1.
    • Final Decrypted Output: Ankur Mhatre

Final Thoughts

This Java example illustrates how classical cryptographic techniques like substitution and transposition can be layered to build a Product Cipher. While not secure enough for modern usage, understanding these methods gives insight into how encryption has evolved and how fundamental concepts influence modern cryptography.

In practical applications, algorithms like AES, RSA, and ECC, combined with secure key management and hashing, form the basis of secure communication today. However, this example is a great educational tool to get hands-on with the basic building blocks of cryptography.

Click here for older version of this post.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.