Tuesday, July 2, 2013

Simple symmetric / Shared key encryption tutorial

I was looking for a way to explain cryptography to my 8 year old son this evening and we devised a simple share key encryption / decryption method.  The key is symmetrical because both sides have the same key  and the same key is used for both encrypting and decrypting.

We took a simple ceasar cipher and extended it slightly by creating a stronger key.  Something like this:

Plain Text = HELLO WORLD
Key = [2, -5, 3, 7]
to encrypt we take the positional value for each letter and apply the replacement for the next key bit in turn.  For example:

Start at keybit = 1 [2]
H = 8, H + 2 = 10, 10 = J
keybit = 2 [-5]
E = 5, E - 5 = 0 (26), 26 = Z
keybit = 3 [3]
L = 12, 12 + 3 = 15, 15 = O
keybit = 4 [7]
L = 12, 12 + 7 = 19, 19 = S

Now start at key bit =1 
O = 15, 15 + 2 = 17, 17 = Q
and so on.

So long as the same key is used for decryption the thing works a treat.

So I explained that simple key can be made and shared between friends then private messages can be sent to and fro and only those with the key will know what the messages mean.

To demonstrate I made a program that he can use to make the process a bit quicker...
#!/usr/bin/python

import sys

alphabet = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ',',','.','!','?','\'','#','@','$','%','^','&','(',')','-','_','=','+',']','[','{','}','\\','|','/','"',':',';','<','>','`','~','1','2','3','4','5','6','7','8','9','0']

def encrypt(key, message):
    ciphertext = []
    pos = 0
    for c in message:
        i = alphabet.index(c)
        j = (i + key[pos]) % len(alphabet)
        ciphertext.append(alphabet[j])
        pos += 1
        if pos > len(key)-1: pos = 0
    return "".join(ciphertext)


if __name__ == '__main__':
    key = [3,-6,2,-7,23435363, -3243543, 324]
    for line in sys.stdin:
        encrypted = encrypt(key, line.strip())
        print encrypted

# vim:expandtab:ts=4:softtabstop=4:autoindent
And test it as follows
dave@davidpc:~/bin/simpleenc> echo "Hello World" | ./encrypt.py 
KYneJ9!dave@davidpc:~/bin/simpleenc> echo "Hello World" | ./encrypt.py 
KYneJ9!rlnWrlnW
The Decrypt program is almost identical (and really shouldn't be a separate programme at all)
#!/usr/bin/python

import sys

alphabet = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',' ',',','.','!','?','\'','#','@','$','%','^','&','(',')','-','_','=','+',']','[','{','}','\\','|','/','"',':',';','<','>','`','~','1','2','3','4','5','6','7','8','9','0']

def decrypt(key, message):
    plaintext = []
    pos = 0
    for c in message:
        i = alphabet.index(c)
        j = (i - key[pos]) % len(alphabet)
        plaintext.append(alphabet[j])
        pos += 1
        if pos > len(key)-1: pos = 0
    return "".join(plaintext)
        

if __name__ == '__main__':
    key = [3,-6,2,-7,23435363, -3243543, 324]
    for line in sys.stdin:
        decrypted = decrypt(key, line.strip())
        print decrypted

# vim:expandtab:ts=4:softtabstop=4:autoindent
And the test...
dave@davidpc:~/bin/simpleenc> cat << EOF | ./decrypt.py 
> KYneJ9!rlnW
> EOF
Hello World
Post a Comment