November 2, 2020

Caeser Cipher – Implementation & Attack

Caeser Cipher

Caeser encryption is one of the oldest encryption methods known to us. The procedure of decryption and encryption are described in the book “De Vita Caesarum – Divius Iulius”.

The process is based on a so-called letter rotation. If a rotation of 3 (original Caeser method) means, the letter A becomes a D, B becomes an E and so on. With another rotation basis we speak e.g. of ROT13. With ROT13 the letter A becomes N, B becomes O and so on. Here you can read more about the details. With the following python script we can encrypt and decrypt messages.

import string
import sys
import getopt

LOWER_DICT = list(string.ascii_lowercase)

def usage():
    print("for encryption please run: \n")
    print("caeser --mode=encrypt --mesage=<message> --key=<key>")
    print("\n" + "-"*10 + "\n")
    print("for decryption please run: \n")
    print("caeser --mode=decrypt --mesage=<message> --key=<key>")


def parse_params(optlist):
    mode = ""
    message = ""
    key = 0

    for opt in optlist[0]:
        if "mode" in opt[0]:
            mode = opt[1]

        elif "message" in opt[0]:
            message = opt[1]

        elif "key" in opt[0]:
            key = int(opt[1])

        else:
            pass

    return (mode, message, key)

def rotate(char, key):
    try:
        origin = LOWER_DICT.index(char.lower())
        target = origin + key

        return LOWER_DICT[(target % len(LOWER_DICT))]
    except:
        return char

def main(argv):
    try:
        optlist = getopt.getopt(argv[1:], "",["mode=","key=", "message="])
        mode, message, key = parse_params(optlist)
       
        if mode == "encrypt":
            encrypted_message = ""
            for char in message:
                encrypted_message += rotate(char, key)

            print("encrypted message: \n")
            print(encrypted_message)

        elif mode == "decrypt":
            decrypted_message = ""
            key = key - (2*key)
            for char in message:
                decrypted_message += rotate(char, key)

            print("decrypted message: \n") 
            print(decrypted_message)
        else:
            sys.exit("unrecognised mode: '{}'".format(mode))
    except Exception as e:
        print(e)
        usage()
        sys.exit(1)

if __name__ == "__main__":
    main(sys.argv)

Our secret message is:

“Far out in the uncharted backwaters of the unfashionable end of the western spiral arm of the Galaxy lies a small unregarded yellow sun.”

We encrypt the message with a key of 12 and call our python script:

python caesar.py --mode=encrypt --message="Far out in the uncharted backwaters of the unfashionable end of the western spiral arm of the Galaxy lies a small unregarded yellow sun." --key=12

Our encrypted message is:

“rmd agf uz ftq gzotmdfqp nmowimfqde ar ftq gzrmetuazmnxq qzp ar ftq iqefqdz ebudmx mdy ar ftq smxmjk xuqe m eymxx gzdqsmdpqp kqxxai egz.”

Let us briefly test the decryption:

python caesar.py --mode=decrypt --message="rmd agf uz ftq gzotmdfqp nmowimfqde ar ftq gzrmetuazmnxq qzp ar ftq iqefqdz ebudmx mdy ar ftq smxmjk xuqe m eymxx gzdqsmdpqp kqxxai egz." --key=12

Perfect!

How to attack?

We simply write a small script which tries all the possibilities (26 keys). This is how we attack. After each run we test if we can read something useful. Our attack code looks like follows:

import sys
import string

LOWER_DICT = list(string.ascii_lowercase)

def rotate(char, key):
    try:
        origin = LOWER_DICT.index(char.lower())
        target = origin + key

        return LOWER_DICT[(target % len(LOWER_DICT))]
    except:
        return char


def main(args):
    secret_message = sys.argv[1]

    print("attack: '{}'".format(secret_message))

    for i in range(0,26):
        decrypted_message = ""
        print("\n rotate with key: {} \n".format(i))
        for char in secret_message:
            decrypted_message += rotate(char, i -(i*2))
        print(decrypted_message)

if __name__ == "__main__":
    main(sys.argv)

And here it goes:

I hope you had fun and could see how easy it is to crack a simple shift cipher. Code can be found here: https://github.com/AICDEV/thefinn/tree/master/cryptography/caeser_cipher

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *