Let's Talk Encryption

Part 2 - Vigenère cipher

Posted on August 9, 2016 as Cryptography. 7 minutes read.

Vigenère cipher - how it works?

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.

  • Since our message is 5 letters and keyword is only 4 we have to repeat it until it's same length as message - in this example keyword will be boomb.
  • Now we have to take the first letter from the message and find it on the left-vertical row of the table.
  • Next get the first letter of the keyword and also get its position, now on the upper-horizontal row.
  • After that find where lines, in which were those letters cross and write down the letter you get.
  • Repeat for each letter.

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.

  • Get the keyword and repeat it until it's same length (boomb) as ciphertext (iszxp).
  • Get the first letter of a keyword from the upper-horizontal row of the table
  • Get the first letter of a ciphertext and find it in the same row that the letter from the previous step.
  • Finally find the letter from the left-vertical row that is in the same line as the letter from the previous step.
  • Repeat for each letter.

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.

  • Kasiski examination
  • Friedman test
  • Frequency analysis
  • Key elimination

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

Keep learning and stay safe!

~ W3ndige