Today I want to talk to you about ciphers, more in particular Caesar Ciphers. Encryption and Decryption of secret messages date back a long time before computers. Countless Nations have utilized ciphers to communicate secrets across distances. For example, lets say I have soldier on the other side of the planet and I am relaying them a message that might put their life at risk. Do we want that message falling into the wrong hands? No. So what can we do? Well, the simple answer is to encrypt the message. Today almost every message is encrypted and packet into protocols several of times. For example, your computer encrypts packets it sends back and forth with your WiFi router all the time. Computers, for better or worse, require us to come up with new encryption methods on a daily basis. However, everyone has to start somewhere. Before you can plunge in and understand things like AES and RSA encryption, we need to start in something basic, like Caesar Ciphers.
Caesar Cipher is pretty simple. It is a substitution cipher that people like to think was user by Julius Caesar. In this cipher we follow a formula to encrypt a message and another to decrypt. Let us take a look at what that means mathematically.
Here is our encryption formula:
And here is decryption:
And thats it folks. Wait, what does this actually mean? Well, lets first start with out assumptions:
- The alphabet we are working with contains 26 letters (English)
- n is is a number less than or equal to 25.
These assumptions can be modified for any alphabet language of you choosing. If the alphabet contains m letters, than n has to be less than or equal to m-1. As long as you keep both conditions, you will be fine. Here is a general outline and picture of how the algorithm works. You should be aware that normally n is set to 3, but it will work with any number.
- Assign numeric values to each letter in the alphabet.
- for each letter in plain_text
- new letter is letter_numeric_value + n
- for each letter in plain_text
- for each letter in cipher
- plain_text_letter is letter_numeric_value - n
- for each letter in cipher
For it to make some sense, here is a visual picture from Wikipedia:
So the letter E in our message (plain text) is 5 and n=3, so our encrypted value of E is B. Now that we have some background and a simple example, let us implement it in Python. Like always, we will use Python 2.7. Here is how Caesar Cipher looks like in Python:
First lets look at a simple encryption module:
import sys def main(argv): if (len(sys.argv) != 2): sys.exit('Usage: sub.py <k>') plaintext = list(raw_input('Enter message: ')) alphabet = list('abcdefghijklmnopqrstuvwxyz') k = int(sys.argv) cipher = '' for c in plaintext: if c in alphabet: cipher += alphabet[(alphabet.index(c)+k)%(len(alphabet))] print 'Your encrypted message is: ' + cipher if __name__ == "__main__": main(sys.argv[1:])
In this example we define the alphabet and make use of Python List and Indexing. We ask the user to pass in a key of length k and preform the substation. Here is an example run:
Now let us up the stakes to something more complex. After all, this is an encryption that people used to do by hand all the time. Take a look at this program:
import sys def encrypt(k): plaintext = raw_input('Enter plain text message: ') cipher = '' for each in plaintext: c = (ord(each)+k) % 126 if c < 32: c+=31 cipher += chr(c) print 'Your encrypted message is: ' + cipher def decrypt(k): cipher = raw_input('Enter encrypted message: ') plaintext = '' for each in cipher: p = (ord(each)-k) % 126 if p < 32: p+=95 plaintext += chr(p) print 'Your plain text message is: ' + plaintext def main(argv): if (len(sys.argv) != 3): sys.exit('Usage: ceaser.py <k> <mode>') if sys.argv == 'e': encrypt(int(sys.argv)) elif sys.argv == 'd': decrypt(int(sys.argv)) else: sys.exit('Error in mode type') if __name__ == "__main__": main(sys.argv[1:])
The first question you might ask is why is the mod 126? Well, this version of Caesar Cipher was adapted to take full use of the ASCII Printable Character map, minus the first 32 characters that are not printable. With this program, we can chose a larger n and create a “harder” to break ciphers. You will also notice that now we can do Encryption and Decryption in the same program. Let us try to decrypt ‘khoor’ and see what we get:
Sweet. Now let’s try to encrypt something a little longer with a different key.
Caesar ciphers are nice to play around with and to learn basic concepts, but is really impractical. The number of combination you can get is really small compared to what the computer can generate. Brute force attacks can always crack the code with very little human intervention. Consider a 26 letter alphabet. There are only 25 options for selecting a unique n. That means that if I can generate all the 25 permutations, 1 of them has to be the correct plain text. Let us look brute force braking using the following script:
import sys def decrypt(k,cipher): plaintext = '' for each in cipher: p = (ord(each)-k) % 126 if p < 32: p+=95 plaintext += chr(p) print plaintext def main(argv): if (len(sys.argv) != 1): sys.exit('Usage: brute_ceaser.py') cipher = raw_input('Enter message: ') for i in range(1,95,1): decrypt(i,cipher) if __name__ == "__main__": main(sys.argv[1:])
I will spare you the entire 94 lines that got printed out, here are a few. Can you guess what the message originally was?
Here is another one:
I will let you come to your own conclusions as to how “hard” it is to brake Caesar Ciphers. Personally, I wouldn’t use them for anything simple. Than again, I do not know how many people would check if you used it. I hoped you gain some understanding to how cipher works, substitution ciphers in particular. Next time I might dig a little farther into security algorithms and play around with another step up in encryption-decryption algorithms.