def hash(self, key, text): # L is the byte length of hash outputs. # B is the byte length of hash algorithm's basic compression # function's block size (64 for most hashes) # # Sanitize the key. RFC 2104 recommends key length be at least L and # if it is longer than B, it should be hashed and the resulting L # bytes will be used as the key # L = self.hashmodule.digest_size B = 64 # can't get from module keylen = len(key) if keylen > B: key = self.hashmodule.new(key).digest() keylen = len(key) assert keylen == L elif keylen < B: # append enough zeros to get it to length B key = key + '\000' * (B - keylen) keylen = len(key) # # Precompute the inner and outer intermediate values kipad = xor(key, chr(self.__IPAD) * keylen) kopad = xor(key, chr(self.__OPAD) * keylen) # # perform the inner hashes hash = self.hashmodule.new(kipad) hash.update(text) inner = hash.digest() # # preform the outer hashes hash = self.hashmodule.new(kopad) hash.update(inner) outer = hash.digest() return outer
def _f(self, prf, s, c, i): """The F function for PBKDF2 from PKCS 5""" istr = struct.pack('>i', i)[0] u = prf.hash(s + istr) for j in range(c): u = xor(u, prf.hash(u)) return u
def __init__(self, hashmodule, key): self.hashmodule = hashmodule L = self.hashmodule.digest_size # XXX what is B? B = 64 # can't get from module keylen = len(key) if keylen > B: key = self.hashmodule.new(key).digest() keylen = len(key) assert keylen == L elif keylen < B: # append enough zeros to get it to length B key = key + '\000' * (B - keylen) keylen = len(key) self.kipad = xor(key, chr(self.IPAD) * keylen) self.kopad = xor(key, chr(self.OPAD) * keylen)