Let's Talk Encryption

August 09, 2016

Vigenère cipher is an method of encrypting message by using series of different Caesar ciphers based on the letters of a keyword. Basically to encrypt a message using the Vigenère cipher you first need to choose a keyword. After that repeat this keyword over and over until it is the same length as your secret message.

Now for each plaintext letter, you find the letter on the left-vertical row of the tabula recta. Then you take the corresponding letter from your keyword, and find it at the top-horizontal row of the table. Where these two lines cross in the table is the ciphertext letter you use.

tabula-recta

Tabula Recta

Let's encrypt message - hello with a keyword boom.

When you finish you should get the encrypted message: iszxp

As you now may suspect - decrypting is just reversing the process on encryption - but knowing the ciphertext (places where lines cross) and keyword - upper row of the table.

And that's it! We can easilly encrypt and decrypt the messages with Vigenère cipher.

History behind Vigenère cipher

tabula-recta

A reproduction of the Confederacy's cipher disk

This cipher was originally invented by Giovan Battista Bellaso in 1553, in book called La cifra del. Sig. Giovan Battista Bellaso, but is called after Blaise de Vigenère. Blaise published the stronger version of a cipher in 1586 which was later in 19th century misattributed to Vigenère. This cipher gained the reputation of being strong, even some mathematicians called it 'unbreakable' but in 19th Friedrich Kasiski published a method of deciphering a Vigenère cipher.

Nowadays there are couple of ways of deciphering the cipher.

Read More

Programming the Vigenère cipher

As always, best way to learn ciphers is by programming one. I'm using Python, with itertools and functools.

#!/usr/bin/python3
from itertools import cycle
import functools

Then let's see how the encrypt function works.

alphabet = 'abcdefghijklmnopqrstuvwxyz'

def encrypt(key, plaintext):
    pairs = zip(plaintext, cycle(key))
    ciphertext = ''

    for pair in pairs:
        total = functools.reduce(lambda x, y: alphabet.index(x) + alphabet.index(y), pair)
        ciphertext += alphabet[total % 26]

    return ciphertext.lower()

Firstly I define the alphabet that will help me getting character indexes. Then I'm getting the plaintext and the key, and I'm building a list of tuples using zip() function. Next I use cycle() to repeat the letters of my key for the entire length of the plaintext.

After that I use functools.reduce (reduce in python2) so I can get the index of characters to add them. I finally get the new letter after a modulo of 26 and append that to our resulting ciphertext string.

def decrypt(key, ciphertext):
    pairs = zip(ciphertext, cycle(key))
    plaintext = ''

    for pair in pairs:
        total = functools.reduce(lambda x, y: alphabet.index(x) - alphabet.index(y), pair)
        plaintext += alphabet[total % 26]

    return plaintext

The decryption function is exactly the same but instead of adding numbers I'm subtracting them.

def main():
    print("[*] Welcome to Vigenere Cipher tool")
    print("[*] Would you like to encrypt [E] or [D] decrypt the message?")
    mode = input("[*] Enter your chooice: ").upper()
    if mode == "E":
        plaintext = input("[*] Please enter your message: ")
        key = input("[*] Now enter your key: ")
        encrypted = encrypt(key, plaintext)
        print("[*] Encrypting...")
        print('[*] Encrytped: %s' % encrypted)
    if mode == "D":
        ciphertext = input("[*] Please enter your message: ")
        key = input("[*] Now enter your key: ")
        decrypted = decrypt(key, ciphertext)
        print("[*] Decrypting...")
        print('[*] Decrypted: %s' % decrypted)
    else:
      	print("[*] Error")

if __name__ == '__main__':
    main()

Main function is created to get the messages and keywords from the user, as well as a option to encrypt or decrypt the text.

Now let's check how this works!

Firstly encrypt mode, (after entering 'e' or 'E' letter). I'm gonna stick with the word hello and the boom keyword as we may check whether or not it works ;)

$ python3 viegenare.py
[*] Welcome to Vigenere Cipher tool
[*] Would you like to encrypt [E] or [D] decrypt the message?
[*] Enter your chooice: E
[*] Please enter your message: hello
[*] Now enter your key: boom
[*] Encrypting...
[*] Encrytped: iszxp

Great! Now the decrypt mode.

$ python3 viegenare.py
[*] Welcome to Vigenere Cipher tool
[*] Would you like to encrypt [E] or [D] decrypt the message?
[*] Enter your chooice: d
[*] Please enter your message: iszxp
[*] Now enter your key: boom
[*] Decrypting...
[*] Decrypted: hello

Now we have fully functioning Vigenère cipher tool. I hoped you enjoyed this topic as a part of the Let's talk encryption series. Stay tuned for more updates about encryption as well as other infosec topics.

Part of Encryption Tools Project

Github

Contact

If you have any suggestions regarding this post or just want to chat together check out these ways to reach out to me.