Below is the file 'addrhash.py' from this revision. You can also download the file.
#!/usr/bin/env python2.4 from Crypto.Hash import SHA256, HMAC from Crypto.Cipher import AES import sys import config import socket import base64 def get_cipher(): sha = SHA256.new() sha.update(config.aes_key) return AES.new(sha.digest()) def our_pton(ip_string): try: return verification_value() + socket.inet_pton(socket.AF_INET, ip_string) except socket.error: pass def our_ntop(encoded): return socket.inet_ntop(socket.AF_INET, encoded) def mac_value(val): m = HMAC.new(config.mac_key) m.update(val) return m.digest()[:12] def wrap_with_hmac(val): return mac_value(val) + val def strip_hmac_and_verify(val): their_mac, val = val[:12], val[12:] if their_mac != mac_value(val): raise Exception("HMAC does not verify!") return val def encode(ip_string): enc = wrap_with_hmac(socket.inet_pton(socket.AF_INET, ip_string)) print len(enc) enc = get_cipher().encrypt(enc) print len(enc) return base64.encodestring(enc).rstrip('\n').rstrip('==') def decode(email_address): bytes = base64.decodestring(email_address + '==\n') if len(bytes) != 16: raise Exception("This is not a valid email address.") decoded = get_cipher().decrypt(bytes) decoded = strip_hmac_and_verify(decoded) return our_ntop(decoded) if __name__ == '__main__': ops = {'dec' : decode, 'enc' : encode} if len(sys.argv) != 3 or not ops.has_key(sys.argv[1]): print >>sys.stderr, """\ Usage: %s <enc> <ip_address> %s <dec> <email_address>""" % (sys.argv[0], sys.argv[0]) sys.exit(1) print ops[sys.argv[1]](sys.argv[2])