Department of Computing

Local Navigation

COMP249 Web Technology

Practical - Week 8

In this week's practical you will explore the idea of message encryption and digital signatures. If I want to transmit a message and ensure that it hasn't changed between being sent and recieved, I might encrypt it and add a digital signature to the message. A digital signature would include a hash key computed from the message and would be encrypted with my private key; if you can decrypt this with my public key you will know it is from me and if the hash key matches one that you compute locally you will know that the message is intact.

Since Python doesn't have an asymmetric encryption library as part of the standard installation, we will use the symmetric encryption module rotor. Rotor implements the encryption method used in the Enigma device from WWII famously broken by Alan Turing. The following code encrypts some text with rotor:

import rotor
key = 'very secret key' 
message = "The answer to the first question is 'In order to avoid scabies'"
rot = rotor.newrotor(key)
enc = rot.encrypt(message)
    

Similarly to decrypt the message, we construct a rotor object with the same key:

import rotor
key = 'very secret key' 
rot = rotor.newrotor(key)
message = rot.decrypt(enc)
    

Note: the rotor package isn't available in more recent versions of Python (it's in 2.3). Instead you can substitute the following encrypt and decrypt procedures which serve to illustrate the idea even if they aren't really very secure. You can download some real crypography modules from the Python Cryptography Toolkit.

def encrypt(key, message):
    "encode the message using the secret key"

    result = ""
    for ch in message:
        result += chr( ord(ch) + ord(key[0]) )
    return result


def decrypt(key, message):
    "decode a message given the key"

    result = ""
    for ch in message:
        result += chr( ord(ch) - ord(key[0]) )
    return result

To implement message signing, we need a message hashing function. Python provides the hmac module for this purpose. Hmac is good because it's designed just for this purpose (Message Authentication) and uses a secret key to compute the hash. We can use the same key we'll be encrypting the message with:

import hmac
hm = hmac.new(key)
hm.update(message)
digest = hm.hexdigest()

Using these tools, write a function which accepts a message and a key, construct a composite message consisting of the original message and the hmac digest, and then return the encrypted version of this message. Write a complementary function which accepts a key and an encrypted message and decrypts the message, verifies the signature and returns the decrypted original message if all is well or an error message if not.

To solve this problem, you'll need to make up some kind of text format to encode your message+digest. One option is to use the Python pickle module to generate a printable version of a simple datastructure like a list:

import pickle
encmsg = [message, digest]
encmsgtext = pickle.dumps(encmsg)
# now encrypt and  send encmsgtext
...
# decrypt message
encmsgtext = mydecryptproc( transmitted_message )
# regenerate the list
encmsg = pickle.loads(encmsgtext)
...
    

Note that pickle is Python specific.

Portfolio

The Python Cryptography Toolkit provides a collection of cryptography algorithms and protocols for Python. You might want to discuss in your portfolio how Python can be used to transform plain text into ciphertext using an encryption algorithm or how a public key algorithm can be used to sign a message. See the manual of the Python Cryptography Toolkit for an introduction. You can download the PyCrypto module from here.

Comments to: comp249-admin@ics.mq.edu.au

Copyright & Site information