Cryptography - An Introduction

Cryptography, derived from the Greek κρυπτός (kruptós: hidden, private), is the practice of storing and transferring information securely and privately in presence of third parties who may harm or take undue advantages if the information falls in their hands. The terms cryptography and cryptology are generally interchangeably used but cryptography and cryptanalysis and considered the subset of cryptology. 

In earlier times cryptography was synonymous with encryption i.e. the conversion of plain text data into cipher text (some kind of encoded text) but now it has evolved into a bigger topic going far beyond but also encompassing encryption.

Cryptography can be broadly divided into:

a) Encryption: The conversion of messages and data into an encoded form such that only people authorized to view it can actually view it. The input data referred to as plain-text is converted into an unreadable form called cipher-text and is then transmitted. When reached the destination the data can be decrypted using certain methods to get back the plain-text. 

Encryption can be classified into:

  • Private Key or Symmetric Encryption: In this technique of encryption the same key is used to encrypt and decrypt the message. A specific private key must be decided before performing symmetric encryption.
  • Public Key Encryption: In this technique a user issues a public key which is used to encrypt the message. The private key is only with the user making him the sole party who can decrypt the encoded message. For instance, A issues a public key. B encrypts his message with A's public key and sends the encrypted message to A. A then decrypts the message using his private key.
b) Hashing: Hashing is the process in which arbitrary data is passed into an irreversible function which then produces a fixed length output which can act as a digital fingerprint of the input data. The input data is called the message and the output data is generally termed the message digest. It should however be noted that hashing is not a form of data compression which can convert data of any length into fixed small length data as the output data cannot be converted back to the input message. 

Hashing may initially seem hard to accept (how can you simply not get the data back?) but let us take up an example. Take the modulus function, f(x) = x % 3. Now f(4) maps to 1 and f(25) also maps to 1. If I tell you that this function mapped to 1 you simply cannot tell if the input was 4,7,25 or any other number of type 3k + 1.

What are the uses of hashing, you ask?

I can tell you of two immediately.

i) Passwords: We can simply not store passwords as plain texts. Hence, they are stored as hashes instead. The hash of the input password is compared with the stored hash to tell if the password was correct.

ii) Checking file integrity: We download numerous files from the internet. Some of the websites provides hashes of their files on their website. As the attacks on the internet have increased enormously we cannot guarantee the originality of the file. We can instead download it, hash it and compare it with the hash given on the website to ensure the file downloaded without any corruption or remove the suspicion of incomplete downloads. Two files with the same content will have same hashes so we can check for duplicate files too.

For example,
A asks B, "What is the value of x3 - 15 for x=4?". A does not provide B with the answer (i.e. 49) but instead hashes it using MD5 (a hash function) and provides B with the hash (i.e. f457c545a9ded88f18ecee47145a72c0). Now A can find his own answer and hash it with MD5 to see if it is the correct answer. 

c) Steganography: It is the art of concealing a message inside another message. The cover message may seem totally normal or total garbage at the first view but has useful information under it. A technique of steganography for example is writing a private letter in between the lines of a normal letter using invisible ink.

For example,
How arE you doIng Sir? THat pERson told mE you were not well.
The above text has a hidden message inside it formed by joining all the capitalized letters: he is there.

Ciphers : The Caesar Cipher


Just because the article has sounded too theoretical until now, here I introduce some practicality into it. During the earlier ages the encryption was pen and paper type which is too fragile for today's computer age. Today we have much advanced and unbreakable encryption techniques. However, we should know the basics before going into advanced study about the topic. The very trivial types of encryption (or ciphers) are called the substitution ciphers which work by replacement of each letter of the message with another letter. 

The simplest of substitution ciphers is the Caesar cipher (it was used by Julius Caesar for sending messages, hence the name). In this we shift every letter by specific amount in the English alphabet to get the cipher-text.

For example,
ABCXYZ becomes BCDYZA on a shift of 1.


The Caesar Cipher
It is known that Caesar used a shift of 3 in his messages before sending them. We can see however that this is an extremely weak encryption because we have only 25 possible shifts (the 26th one returns the message as it is). We can easily try all the possible shifts and decode the message. The cracking will be explained later in another article about Cryptanalysis.


Here is an example JavaScript Caesar Cipher, Just enter the message, choose the shift amount and it will encode it for you:





The Example Code

The following section provides example of Caesar cipher in Java, Python and JavaScript which shifts all the alphabets by the shift factor but has no effect on numbers or other symbols.

Java:

// Caesar.java - Abdul Fatir
import java.io.*;
public class Caesar
{
	public static void main(String argv[])throws IOException
	{
		final String message = argv[0];
		BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
		System.out.print("Please enter a shift amount:");
		int shift=Integer.parseInt(reader.readLine());
		String cipher="";
		for(int i=0;i<message.length();i++)
		{
			int char_code = (int)message.charAt(i);
			int encoded_char=0;
			if(char_code >= 65 && char_code <= 90)
			{
				if(char_code + shift <= 90)
				{
					encoded_char = char_code + shift;
					cipher += ((char)encoded_char);
				}
				else
				{
					encoded_char = char_code + shift - 90;
					encoded_char += 64;
					cipher += ((char)encoded_char);
				}
			}
			else if(char_code >= 97 && char_code <= 122)
			{
				if(char_code + shift <= 122)
				{
					encoded_char = char_code + shift;
					cipher += ((char)encoded_char);
				}
				else
				{
					encoded_char = char_code + shift - 122;
					encoded_char += 96;
					cipher += ((char)encoded_char);
				}
			}
			
			else
			{
				cipher += ((char)char_code);
			}
		}
		System.out.print("The cipher-text is: "+cipher);
	}
}

Python:

# Caesar.py - Abdul Fatir
import sys
message = sys.argv[1]
shift = int(raw_input("Please enter a shift amount:"))
cipher = ''
for i in range(len(message)):
	charASCIIcode = ord(message[i])
	if charASCIIcode >= ord('A') and charASCIIcode <= ord('Z'):
		if charASCIIcode + shift <= ord('Z'):
			cipher += chr(charASCIIcode+shift)
		else:
			cipher += chr(charASCIIcode+shift-ord('Z')+ord('A')-1)
	elif charASCIIcode >= ord('a') and charASCIIcode <= ord('z'):
		if charASCIIcode + shift <= ord('z'):
			cipher += chr(charASCIIcode+shift)
		else:
			cipher += chr(charASCIIcode+shift-ord('z')+ord('a')-1)
	else:
		cipher += chr(charASCIIcode)
print 'The cipher-text is: %s' % cipher

JavaScript:

<script type="text/javascript">
	function encodeData()
	{
		var input_data = document.getElementsByName('raw_data')[0].value;
		var shift_factor = parseInt(document.getElementsByName('shift_factor')[0].value);
		var encoded = "";
		for(var i=0;i<input_data.length;i++)
		{
			var char_code = input_data.charCodeAt(i);
			if(char_code >= 65 && char_code <= 90)
			{
				if(char_code + shift_factor <= 90)
				{
					encoded_char = char_code + shift_factor;
					encoded += String.fromCharCode(encoded_char);
				}
				else
				{
					encoded_char = char_code + shift_factor - 90;
					encoded_char += 64;
					encoded += String.fromCharCode(encoded_char);
				}
			}
			else if(char_code >= 97 && char_code <= 122)
			{
				if(char_code + shift_factor <= 122)
				{
					encoded_char = char_code + shift_factor;
					encoded += String.fromCharCode(encoded_char);
				}
				else
				{
					encoded_char = char_code + shift_factor - 122;
					encoded_char += 96;
					encoded += String.fromCharCode(encoded_char);
				}
			}
			
			else
			{
				encoded += String.fromCharCode(char_code);
			}
		}
		document.getElementsByName('encoded_data')[0].value = encoded;
	}
	</script>


References and Further Readings:
[1] learncryptography.com/
[2] http://en.wikipedia.org/wiki/Cryptography
[3] http://en.wikipedia.org/wiki/Encryption
[4] http://en.wikipedia.org/wiki/Cryptographic_hash_function
[5] www.garykessler.net/library/crypto.html