Just as I detailed part of my project of making a simple chat application in PHP I will document my process of creating a simple encryption program in java. The program will use the one use pad secret key system which I will explain as the tutorial progresses.
Let’s begin with the simple java program structure for our starting class which will be in a file named OnePad.java
public class OnePad {
public static void main(String[] args) {
}
}
Between the braces of the main method I’ll place the code for that and between the braces of the class we place other methods and class variables which have global scope.
The first thing I’ll need is a message to encrypt. We can get it from anywhere like user input or a file or we can hard-code it into the program which is what I’ll do for now so I need to declare a String.
and I’ll need a space to store the encrypted message so I’ll declare a blank variable to store that.
Then I’ll need a way to convert Strings into an array so I can work on each character in the string one at a time so I’ll make a method for that.
Then I’ll need a way to print out Strings and arrays so I’ll make methods for that.
I’ll need a random number generator so I’ll make a method for that.
I’ll need a way to fill in an integer array with random numbers I can generate so that’s a method too.
And I’ll want a way to use more cryptographically secure random number generation in the future so I can code a method for producing whole bytes that meet that standard too if I want.
Now my code looks like this…
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Scanner;
public class OnePad {
public static void main(String[] args) {
// hard coded test message option
//String message = “Hello.”;//this is our message
Scanner sc = new Scanner(System.in);//creates a scanner sc object to take input from the system’s
//standard input which is the terminal’s keyboard
System.out.println(“Please enter a message you’d like to encrypt and press RETURN”);
String message = sc.nextLine();//accepts user input and stores it as the message to encrypt
System.out.println(“This is our message that will be encrypted and decrypted : ” + message);//show the message
//tell the user how large the message is
int length = message.length();//this is the length of the message
System.out.println(“The message is ” + length + ” characters in length.”);
//generate random pad – this is the basic key to encrypt and decrypt
int[] pad1array = new int[length];
for (int i = 0; i < length; i++){
pad1array[i] = randomint();
//or use next line for extra security instead of previous line
//pad1array[i] = securerandomint();
}
System.out.println(“Encryption Step 1 : Randomly Generated Pad created = ” + Arrays.toString(pad1array));//show the pad to the user
//convert message to asciiarray
int asciicodearray[] = new int[length];//loads values in an array
for (int i = 0; i < length; i++){
int x = message.charAt(i);
asciicodearray[i] = x;
}
System.out.println(“Encryption Step 2 : Message converted to ASCII CODE : ” + message + ” = ” + Arrays.toString(asciicodearray));//show the ascii array to the user
//encrypt asciicode with pad
int[] cryptedarray = new int[length];
for (int i = 0; i < length; i++){
cryptedarray[i] = asciicodearray[i] + pad1array[i];
}
System.out.println(“Encryption Step 3 : Pad applied to Message by addition = ” + Arrays.toString(cryptedarray));//show encrypted message
//adjust if an encrypted number is over 255 which is a character set overflow
for (int i = 0; i < length; i++){
if (cryptedarray[i] > 255){
cryptedarray[i] = cryptedarray[i] – 255;
}
}
System.out.println(“Encryption Step 4 : Character-set overflow is adjusted for =” + Arrays.toString(cryptedarray));//show the adjusted result
//use stringbuilder to remake the string from the char array
char[] asciicarencrypted = new char[length];
for (int i = 0; i < length; i++){
asciicarencrypted[i] = (char)cryptedarray[i];
}
System.out.println(“Encryption Step 5 : Ascii code converted to char array = ” + Arrays.toString(asciicarencrypted));//show it
//build a string from the encrypted char array for general use
String encryptedstring = “”;
StringBuilder es = new StringBuilder(encryptedstring);
es.append(asciicarencrypted);
System.out.println(“Encryption Step 6 : Encrypted array turned into a string ” + es);//show the result
/////////////////////////////////////////////////////////
//reverse the process
System.out.println(“The encryption is complete \nNow the process will be reversed… “);//show the adjusted result
//apply the pad again, but by subtraction instead of addition
int[] decrypt = new int[length];
for (int i = 0; i < length; i++){
decrypt[i] = cryptedarray[i] – pad1array[i];
}
System.out.println(“Decryption Step 1 : Pad applied by subtraction = ” + Arrays.toString(decrypt));//show the result
//adjust for underflow of characterset
for (int i = 0; i < length; i++){
if (decrypt[i] < 0){
decrypt[i] = decrypt[i] + 255;
}
}
System.out.println(“Decryption Step 2 : Character set underflow is adjusted for = ” + Arrays.toString(decrypt));//show the result
//convert from integers to a char array
char[] asciicar = new char[length];
for (int i = 0; i < length; i++){
asciicar[i] = (char)decrypt[i];
}
System.out.println(“Decryption Step 3 : Ascii code converted to char array = ” + Arrays.toString(asciicar));//show the result
//use stringbuilder to remake the string from the char array
String decryptedstring = “”;
StringBuilder ds = new StringBuilder(decryptedstring);
ds.append(asciicar);
System.out.println(“Decryption Step 4 : The message is rebuilt from the char array = ” + ds);//show the result
}
//generate random numbers
public static int randomint(){
return (int)(Math.random()* 256);
}
//more secure random numbers – not in use by default code
public static int securerandomint(){
SecureRandom rand = new SecureRandom();
return rand.nextInt();
}
}
Now I have a good basic structure to base my program off of, but I’ll explain the process of the encryption scheme.
First the user enters a message, and that message is converted from a string into an array of integers, a random set of numbers the length of the message is generated to create a single use pad, and then the array is modified by adding the respective corresponding pad numbers to each array number, the result is then shifted down a bit or can be modified in any way to keep them within a range of a particular character set if so desired or just kept as a series of numbers, and then the it’s converted back to string which is not necessary, but could be useful for manipulation and storage. And the encryption is complete. To reverse the process the pad is applied to the encrypted message and then the shifting reversed. It’s pretty simple.
Obviously this basic structure can be modified to make the program more practical in many ways like taking input from a file, storing the pad key in a file, and methods added allowing a pad to be reentered for later decryption, and the more secure random number generator included in the code can be used instead of the standard java random number generator, but this is the basic idea of how a single use pad scheme can be programmed.
Now the question is how effective is a one time use pad scheme in hidding data? Well basically it’s unbreakable without the key.
The pattern matching techniques which are used to analyze data that recurs does not work on one time pad systems because each space for a character is filled with something random so a letter “A” in one space would not be a letter “A” in another so the frequency of a letter or any other character is not detectable.
The only distinguishing mark is the file length which is the same as the original message and that can indicate perhaps a computer program or picture or piece of text was encrypted, but that’s just an assumption the decryption expert would need to make and it’s not much to go on.
In fact by adding extra black spaces or a special character which can be stripped out latter the length of the file can be greatly modified not only making it impossible to know the original length, but making much more work for the decryption expert.
However it must be understood that the longer a file is the more vulnerable to pattern matching techniques it becomes. The weakness of this exploit lies not in the encryption scheme, but rather in the random number generator which is part of the method.
A large amount of text encrypted by one generator could result in the discovery that it creates more of a certain kind of number than another which could help the decryption expert discover at least part of the code.
And so an alternative random number generator which is more secure is provided in the source code, but must be enabled by uncommenting and commenting certain lines which should be fairly obvious.
There are three troubles with the one time use pad that should be covered:
One and Two: Because the pad has to be the same length as the input it really isn’t great for really large files or messages and it is usually impossible to memorize unlike a passphrase which is usually easy to remember so the pad which serves as a secret key must be stored providing a vulnerability.
Three: Because the key is entirely secret known only to the person who creates it an arranged meeting or secure electronic transfer session must be arranged if the encrypted message is to be shared and so generating a series of keys to use and exchanging them ahead of time is necessary if it is to be used as an effective form of communication rather than for private storage of data. And in that case to maintain top security each pad would only be used once and then discarded. Hence the term, “one time pad.”