def kdf2(sharedsecret, nonce, activationcode, len, iterations=10000, digest='SHA256', macmodule=hmac, checksum=True): ''' key derivation function - takes the shared secret, an activation code and a nonce to generate a new key - the last 4 btyes (8 chars) of the nonce is the salt - the last byte (2 chars) of the activation code are the checksum - the activation code mitght contain '-' signs for grouping char blocks aabbcc-ddeeff-112233-445566 :param sharedsecret: hexlified binary value :param nonce: hexlified binary value :param activationcode: base32 encoded value ''' digestmodule = get_hashalgo_from_description(digest, fallback='SHA256') byte_len = 2 salt_len = 8 * byte_len salt = u'' + nonce[-salt_len:] bSalt = binascii.unhexlify(salt) activationcode = activationcode.replace('-', '') acode = activationcode if checksum is True: acode = str(activationcode)[:-2] try: bcode = base64.b32decode(acode) except Exception as exx: error = "Error during decoding activation code %r: %r" % (acode, exx) log.error(error) raise Exception(error) if checksum is True: checkCode = str(activationcode[-2:]) veriCode = str(check(bcode)[-2:]) if checkCode != veriCode: raise Exception('[crypt:kdf2] activation code checksum error.' ' [%s]%s:%s' % (acode, veriCode, checkCode)) activ = binascii.hexlify(bcode) passphrase = u'' + sharedsecret + activ + nonce[:-salt_len] keyStream = PBKDF2(binascii.unhexlify(passphrase), bSalt, iterations=iterations, digestmodule=digestmodule) key = keyStream.read(len) return key
def pbkdf2(password, salt, dk_length, iterations=1000, hashfunc=sha1): return PBKDF2(password, salt, iterations, hashfunc).read(dk_length)