""" One way encryption methods for the demo. Imports module hmac which provides the HMAC algorithm according to RFC 1024 Current version uses SHA256 for hash mapping. """ import hmac import hashlib import random def make_one_way_key(): random.seed() x1 = random.randrange(0, 0Xffffffff) x2 = random.randrange(0, 0Xffffffff) x3 = random.randrange(0, 0Xffffffff) x4 = random.randrange(0, 0Xffffffff) return "%x%x%x%x" % (x1, x2, x3, x4) class OneWayEncrypt: def __init__(self, key): self.key = key self.m = hmac.new(key, "", hashlib.sha256) # keep code books of translated values self.codes = {} self.scale_factors = {} def _derive(self, name): """ Derive a scale and offset from the encrypted value of the name. The scale and offset can be used to conceal floating point numbers while retaining their numerical order relationship. """ # return stored value if we have it otherwise calculate if self.scale_factors.has_key(name): scale = self.scale_factors[name] else: # encrypt the name into a string of 64 hex digits namestr = self.encrypt_word(name) # Use the last 15 hexidecimal digits for the scale1 s_scale = namestr[-15:] hexstring = "0X%s" % s_scale scale1 = float( eval(hexstring) ) # use 15 digits to the left for scale2 s_offset = namestr[-30:-15] hexstring2 = "0X%s" % s_offset scale2 = float( eval(hexstring2 )) scale = scale1 + scale2 ## print "scale %s %s %g " % (s_scale, hexstring, scale) ## print "offset %s %s %g " % (s_offset, hexstring, offset) #save scale factor self.scale_factors[name] = scale return scale def encrypt_word(self, word): """ Encrypt a string """ h = self.m.copy() h.update(word) digest = h.hexdigest() self.codes[digest] = ["w", word] return digest def encrypt_int(self, k): """ Encrypt an integer value - encrypted integers cannot be compared for relative value. """ s = str(k) h = self.m.copy() h.update(s) digest = h.hexdigest() self.codes[digest] = ["i", k] return digest def encrypt_float(self, name, x): """ Encrypt a real value -- actually conceal the value, this is not true encryption. The result may be compared for relative value. """ # derive scale scale = self._derive(name) # apply and return return scale * x def encrypt_range(self, name, range_pair): """ Encrypt or conceal a pair of real values representing a range as xmin->xmax. Return as a pair of concealed real values with the first smaller than the second. """ return ( self.encrypt_float(name, range_pair[0]), self.encrypt_float(name, range_pair[1]))