Search
• Alibek Jakupov

# Data encryption basic algorithms: Java implementation

Updated: May 1

In this blog post we are going to see some basic data encryption algorithms, with their implementation in Java. The goal of this article is to provide some 'hands-on' experience instead of inundating the reader with piles of theoretical information, which is extremely important, but requires much more careful investigation than simple blog post.

All the code is also available on github, and can be easily used for reader's personal needs. Up we go!

## Ceaser Cipher

The most well-known and the most basic algorithm. All the computer security courses start with this algorithm to show the evolution of data encryption techniques.

Quote from Wikipedia:

In cryptography, a Caesar cipher, also known as Caesar's cipher, the shift cipher, Caesar's code or Caesar shift, is one of the simplest and most widely known encryption techniques. It is a type of substitution cipher in which each letter in the plaintext is replaced by a letter some fixed number of positions down the alphabet. For example, with a left shift of 3, D would be replaced by A, E would become B, and so on. The method is named after Julius Caesar, who used it in his private correspondence. The encryption step performed by a Caesar cipher is often incorporated as part of more complex schemes, such as the Vigenère cipher, and still has modern application in the ROT13 system. As with all single-alphabet substitution ciphers, the Caesar cipher is easily broken and in modern practice offers essentially no communications security.

Here's the implementation

```import java.util.Scanner;

public class Cipher {
private static String message;
private static String option = "";

public static String encode(String message, int k) {
String encodedMessage = "";
for (char e:message.toCharArray()) {
if (e+k > 122) {
e = (char) ('A' + (e+k-123));
} else {
e+=k;
}
encodedMessage+=e;
}
return encodedMessage;
}

public static String decode(String message, int k) {
String decodedMessage = "";
for (char e:message.toCharArray()) {
if (e-k<65) {
int a = e-k;
int b = 65-a;
e = (char) ('z' - b+1);
}else {
e-=k;
}
decodedMessage+=e;
}
return decodedMessage;
}

public static void main (String[] args) {
int k = 0;
System.out.println("Enter your message");
Scanner input = new Scanner(System.in);
message = input.nextLine();
System.out.println("Enter k:");
System.out.println("Decode or encode?");
k = input.nextInt();

option = input.nextLine();

if (option.trim().toLowerCase().equals("encode")) {
System.out.println(encode(message, k));
} else if (option.trim().toLowerCase().equals
("decode")) {
System.out.println(decode(message, k));
} else {
System.out.println("Unknown command");
}
}
}```

# Vigenère cipher

This method consist in encrypting alphabetic text by using a series of interwoven Caesar ciphers, based on the letters of a keyword.

Quote from Wikipedia

First described by Giovan Battista Bellaso in 1553, the cipher is easy to understand and implement, but it resisted all attempts to break it until 1863, three centuries later. This earned it the description le chiffre indéchiffrable (French for 'the indecipherable cipher'). Many people have tried to implement encryption schemes that are essentially Vigenère ciphers. In 1863, Friedrich Kasiski was the first to publish a general method of deciphering Vigenère ciphers. In the 19th century the scheme was misattributed to Blaise de Vigenère (1523–1596), and so acquired its present name. In a Caesar cipher, each letter of the alphabet is shifted along some number of places. For example, in a Caesar cipher of shift 3, A would become D, B would become E, Y would become B and so on. The Vigenère cipher has several Caesar ciphers in sequence with different shift values. To encrypt, a table of alphabets can be used, termed a tabula recta, Vigenère square or Vigenère table. It has the alphabet written out 26 times in different rows, each alphabet shifted cyclically to the left compared to the previous alphabet, corresponding to the 26 possible Caesar ciphers. At different points in the encryption process, the cipher uses a different alphabet from one of the rows. The alphabet used at each point depends on a repeating keyword.

And the implementation

```import java.util.Scanner;

public class Vigenere {
public static String encode (String input, String keyword) {
char temp;
String encryptedText = "";

for (int i = 0, j =0; i<input.length(); i++) {
temp = (char) ('A' + (input.charAt(i)+keyword.charAt(j))%26);
System.out.println(input.charAt(i) + " + " + keyword.charAt(j) + " = " + temp);
j = ++j % keyword.length();
encryptedText += temp;
}

return encryptedText;
}

public static String decode (String input, String keyword) {
char temp;
String encryptedText = "";

for (int i = 0, j =0; i<input.length(); i++) {
temp = (char) ('A' + (input.charAt(i)- keyword.charAt(j) + 26)%26);
System.out.println(input.charAt(i) + " + " + keyword.charAt(j) + " = " + temp);
j = ++j % keyword.length();
encryptedText += temp;
}

return encryptedText;
}

public static void main (String[] args) {
System.out.println("Enter your sequence");
String input = "";
String keyword = "";
String option ="";

Scanner scanner = new Scanner (System.in);
input = scanner.nextLine();
input = input.trim();
System.out.println("Enter your keyword");
keyword =scanner.nextLine();
keyword = keyword.trim();
System.out.println("Enter Option");
option = scanner.nextLine();

if (option.trim().toLowerCase().equals("encode")) {
System.out.println(encode(input, keyword));
} else if (option.trim().toLowerCase().equals("decode")) {
System.out.println(decode(input, keyword));
} else {
System.out.println("Unknown Option");
}

}
}```

## Route Cipher

In cryptography, a transposition cipher is a technique of encryption by which the indices held by units of plaintext (characters or groups of characters) are shifted according to a regular system, so that the encrypted text constitutes a permutation of the initial data. Consequetly, the order of the units is changed (the initial text is reordered). Mathematically a bijective function is used on the characters' positions to encrypt and an inverse function to decrypt.

Route cipher is one of the forms of transposition cipher.

As Wikipedia says:

In a route cipher, the plaintext is first written out in a grid of given dimensions, then read off in a pattern given in the key. For example, using the same plaintext that we used for rail fence:
```W R I O R F E O E
E E S V E L A N J
A D C E D E T C X

```
The key might specify "spiral inwards, clockwise, starting from the top right". That would give a cipher text of:
```EJXCTEDEC DAEWRIORF EONALEVSE

```
Route ciphers have many more keys than a rail fence. In fact, for messages of reasonable length, the number of possible keys is potentially too great to be enumerated even by modern machinery. However, not all keys are equally good. Badly chosen routes will leave excessive chunks of plaintext, or text simply reversed, and this will give cryptanalysts a clue as to the routes. A variation of the route cipher was the Union Route Cipher, used by Union forces during the American Civil War. This worked much like an ordinary route cipher, but transposed whole words instead of individual letters. Because this would leave certain highly sensitive words exposed, such words would first be concealed by code. The cipher clerk may also add entire null words, which were often chosen to make the ciphertext humorous.

Java implementation

```import java.util.Random;
import java.util.Scanner;

import sun.net.www.content.text.plain;

public class RouteCipher {
private static String plainText = "";
private static int rows = 0;
private static int columns = 0;
private static char[][] array;
private static Scanner scanner;
private static String encodedMessage = "";
private static String decodedMessage;

public static void main (String[] args) {
scanner = new Scanner (System.in);
System.out.println("Enter text");
plainText = scanner.nextLine();
plainText = plainText.trim();
plainText = plainText.replaceAll("\\s","");
Random random = new Random();

if (plainText.length()%4 ==0) {
rows = plainText.length()/4;
columns = 4;
} else {
while (plainText.length()%4!=0) {
plainText += (char)('A'
+ random.nextInt(41));
}
System.out.println(plainText);
rows = plainText.length()/4;
columns = 4;
}

array = new char[rows][columns];

for (int i = 0, k =0; i<rows; i++) {
for (int j =0; j<columns; j++) {
System.out.println(
plainText.toCharArray()[k]);
array[i][j] = plainText.toCharArray()[k];
k = ++k % plainText.length();
}
}

System.out.println("Message in a table");
for (int i = 0; i<rows; i++) {
for (int j =0; j<columns; j++) {
System.out.print(array[i][j] + " ");
}
System.out.println();
}

System.out.println("Transformation matrix");
for (int j = columns-1; j >= 0; j--) {
for (int i = rows-1; i >= 0; i--) {
System.out.print(array[i][j] + " ");
encodedMessage += array[i][j];
}
System.out.println();
}

System.out.println("The " +
"encrypted message is: "+ encodedMessage);
}
}```

## Playfair cipher

Quote from Wikipedia:

The Playfair cipher or Playfair square or Wheatstone-Playfair cipher is a manual symmetric encryption technique and was the first literal digram substitution cipher. The scheme was invented in 1854 by Charles Wheatstone, but bears the name of Lord Playfair for promoting its use. The technique encrypts pairs of letters (bigrams or digrams), instead of single letters as in the simple substitution cipher and rather more complex Vigenère cipher systems then in use. The Playfair is thus significantly harder to break since the frequency analysis used for simple substitution ciphers does not work with it. The frequency analysis of bigrams is possible, but considerably more difficult. With 600 possible bigrams rather than the 26 possible monograms (single symbols, usually letters in this context), a considerably larger cipher text is required in order to be useful.

```P L A Y F
I R E X M
B C D G H
K N O Q S
T U V W Z

```
Encrypting the message "Hide the gold in the tree stump" (note the null "X" used to separate the repeated "E"s) :
`HI DE TH EG OL DI NT HE TR EX ES TU MP`

Here is the source code:

```import java.util.Scanner;

import sun.reflect.ReflectionFactory.GetReflectionFactoryAction;

public class Playfair {
private static char[][] alphaMatrix;
private static String key;
private static String message;
private static Scanner scanner;
private static String encryptedMessage = "";

public static int getRow(char letter, char[][] alphaMatrix) {
int row = -1;

for (int i = 0; i<5; i++) {
for (int j =0; j<5; j++ ) {
if (alphaMatrix[i][j]==letter) {
row = i;
}
}
}

return row;
}

public static int getColumn(char letter, char[][] alphaMatrix) {
int column = -1;

for (int i = 0; i<5; i++) {
for (int j =0; j<5; j++ ) {
if (alphaMatrix[i][j]==letter) {
column = j;
}
}
}

return column;
}

public static void main (String[] args) {
System.out.println("Welcome");
scanner = new Scanner(System.in);
System.out.println("Enter your key:");
key = scanner.nextLine();
key = key.replaceAll("\\s","").trim().toUpperCase();
String temp = "";

for (char letter:key.toCharArray()) {
if (!(temp.indexOf(letter)>=0)) {
temp+=letter;
}
}

key = temp;

alphaMatrix = new char;

int counter = 0;
char symbol;

//create a string then transform to matrix
while (key.toCharArray().length != 26) {
symbol = (char) ('A' + counter);
if ((key.indexOf(symbol)<0) && (symbol!= 'Q') ) {
key +=symbol;
}
symbol = (char) ('A' + counter++);
}
System.out.println(key);

//transform a string to matrix
for (int i = 0, k =0; i<5; i++) {
for (int j =0; j<5; j++) {
alphaMatrix[i][j] = key.toCharArray()[k];
k = ++k % key.length();
}
}

for (int i = 0; i<5; i++) {
for (int j =0; j<5; j++ ) {
System.out.print(alphaMatrix[i][j] + " ");
}
System.out.println();
}

System.out.println("Enter your message: ");
message = scanner.nextLine();
message = message.replaceAll("\\s","").trim().toUpperCase();

//replace the repeating symbols

for (int i =0; i < message.length()-1; i++) {
if (message.
toCharArray()[i]==
message.toCharArray()[i+1]) {
message = message.substring(0,i+1)
+ 'X' + message.substring(i+1,message.length());
}
}

if (message.length()%2 !=0) {
message +='Z';
}
System.out.println(message);

//start working with letter pairs
//if the letters get columns and getrows correspond...
//either...
for (int i =0; i< message.length(); i++) {
System.out.println(message.
toCharArray()[i] + "~" +
message.toCharArray()[i+1]);
if (getColumn(message.
toCharArray()[i], alphaMatrix) == getColumn(message.
toCharArray()[i+1], alphaMatrix)) {
System.out.println("The columns are equal");
if (getRow(message.
toCharArray()[i], alphaMatrix) != 4) {
encryptedMessage +=alphaMatrix[getRow(message.
toCharArray()[i], alphaMatrix)+1]
[getColumn(message.
toCharArray()[i], alphaMatrix)];
} else {
encryptedMessage +=alphaMatrix
[getColumn(message.
toCharArray()[i], alphaMatrix)];
}
if (getRow(message.
toCharArray()[i+1], alphaMatrix) != 4) {
encryptedMessage +=alphaMatrix[getRow(message.
toCharArray()[i+1], alphaMatrix)+1]
[getColumn(message.
toCharArray()[i+1], alphaMatrix)];
} else {
encryptedMessage +=alphaMatrix
[getColumn(message.
toCharArray()[i+1], alphaMatrix)];
}
}else if (getRow(message.
toCharArray()[i], alphaMatrix) == getRow(message.
toCharArray()[i+1], alphaMatrix)) {
System.out.println("The rows are equal");
if (getColumn(message.
toCharArray()[i], alphaMatrix) != 4) {
encryptedMessage +=alphaMatrix[getRow(message.
toCharArray()[i], alphaMatrix)]
[getColumn(message.
toCharArray()[i], alphaMatrix)+1];
} else {
encryptedMessage +=alphaMatrix[getRow(message.
toCharArray()[i], alphaMatrix)]
;
}
if (getRow(message.
toCharArray()[i+1], alphaMatrix) != 4) {
encryptedMessage +=alphaMatrix[getRow(message.
toCharArray()[i+1], alphaMatrix)]
[getColumn(message.
toCharArray()[i+1], alphaMatrix)+1];
} else {
encryptedMessage +=alphaMatrix[getRow(message.
toCharArray()[i+1], alphaMatrix)]
;
}
} else {
System.out.println("Neither");
encryptedMessage +=alphaMatrix[getRow(message.
toCharArray()[i], alphaMatrix)]
[getColumn(message.
toCharArray()[i+1], alphaMatrix)];
encryptedMessage +=alphaMatrix[getRow(message.
toCharArray()[i+1], alphaMatrix)]
[getColumn(message.
toCharArray()[i], alphaMatrix)];
}
i++;
}

System.out.println(encryptedMessage);
}
}```

This is the method that cannot be cracked, but needs the use of a one-time pre-shared key the same size as, or longer than, the message being sent.

```     H       E       L       L       O  message
7 (H)   4 (E)  11 (L)  11 (L)  14 (O) message
+ 23 (X)  12 (M)   2 (C)  10 (K)  11 (L) key
= 30      16      13      21      25     message + key
=  4 (E)  16 (Q)  13 (N)  21 (V)  25 (Z) (message + key) mod 26
E       Q       N       V       Z  → ciphertext

```

```E       Q       N       V       Z  ciphertext
4 (E)  16 (Q)  13 (N)  21 (V)  25 (Z) ciphertext
-  23 (X)  12 (M)   2 (C)  10 (K)  11 (L) key
= -19       4      11      11      14     ciphertext – key
=   7 (H)   4 (E)  11 (L)  11 (L)  14 (O) ciphertext – key (mod 26)
H       E       L       L       O  → message```

Java code

```import java.util.Random;
import java.util.Scanner;

import sun.net.www.content.text.plain;

private static String plainText = "";
private static String key = "";
private static String encryptedMessage = "";
private static int messageSize;
private static Scanner scanner;
private static String option;

public static String encrypt (String plainText, String key) {
String encryptedMessage = "";
char letter;
int index;

for (int i =0 ; i < plainText.length(); i++) {
index = plainText.toCharArray()[i] + key.toCharArray()[i];

if (index <26) {
index= index;
} else {
index = index%26;
}
letter = (char) ('A' + index);
System.out.println(
plainText.toCharArray()[i] +
" + " + key.toCharArray()[i] +
" = " + index + " ~ " +
letter);
encryptedMessage += letter;
}

return encryptedMessage;
}

public static String decrypt (String plainText, String key) {
String decryptedMessage = "";
char letter;
int index;

for (int i =0 ; i < plainText.length(); i++) {
index = plainText.toCharArray()[i] - key.toCharArray()[i];

if (index > 0) {
index = index;
} else {
index +=26;
}
if (index == 26) {
index = 0;
}
letter = (char) ('A' + index);
System.out.println(
plainText.toCharArray()[i] +
" - " + key.toCharArray()[i] +
" = " + index + " ~ " +
letter);
decryptedMessage += letter;
}

return decryptedMessage;
}

public static void main (String[] args) {
System.out.println("Welcome");

scanner = new Scanner (System.in);
Random random = new Random();

System.out.println("Enter your message:");

plainText = scanner.nextLine();
plainText = plainText.replaceAll("\\s","").trim().toUpperCase();
plainText = plainText.replace("1", "ONE");
plainText = plainText.replace("2", "TWO");
plainText = plainText.replace("3", "THREE");
plainText = plainText.replace("4", "FOUR");
plainText = plainText.replace("5", "FIVE");
plainText = plainText.replace("6", "SIX");
plainText = plainText.replace("7", "SEVEN");
plainText = plainText.replace("8", "EIGHT");
plainText = plainText.replace("9", "NINE");
plainText = plainText.replace("0", "ZERO");

messageSize = plainText.length();

System.out.println("The modified message is: " + plainText);

System.out.println("Enter option");
option = scanner.nextLine();

if (option.trim().toLowerCase().equals("encrypt")) {
for (int i =0; i< messageSize; i++) {
key += (char) ('A' + random.nextInt(26));
}

System.out.println("The key is:" + key);

encryptedMessage = encrypt(plainText, key);

System.out.println("The encrypted message is: " + encryptedMessage);
} else if (option.trim().toLowerCase().equals
("decrypt")) {
System.out.println("Eneter key");

key = scanner.nextLine();

encryptedMessage = decrypt (plainText, key);

System.out.println("The source text is: " + encryptedMessage);
} else {
System.out.println("Unknown command");
}
}
}```

Hope this was useful. Enjoy

57 views

See All