Skip to content

Instantly share code, notes, and snippets.

@wizardofozzie
Last active August 29, 2015 14:19
Show Gist options
  • Save wizardofozzie/6d18530f1dc150393c64 to your computer and use it in GitHub Desktop.
Save wizardofozzie/6d18530f1dc150393c64 to your computer and use it in GitHub Desktop.
from binascii import hexlify, unhexlify
import hmac, struct, hashlib, sys
is_python2 = True if sys.version_info.major == 2 else False
def pbkdf_two(passwd, salt, iters=2048, keylen=64, digestmod=hashlib.sha512):
"""
>>> hexlify(pbkdf_two(b'All n-entities must communicate with other n-entities via n-1 entiteeheehees', unhexlify('1234567878563412'), 500, 16, hashlib.sha1))
'6a8970bf68c92caea84a8df285108586'
"""
dgsz = digestmod().digest_size if callable(digestmod) else digestmod.digest_size
if keylen is None: keylen = dgsz
# Helper function which copies each iteration for h, where h is an hmac seeded with password
def pbhelper(h, salt, itercount, blocksize):
def prf(h, data):
hm = h.copy()
hm.update(data)
return hm.digest()
U = prf(h, salt + struct.pack('>i', blocksize))
T = U
for j in range(2, itercount+1):
U = prf(h, U)
T = "".join([chr( ord(x) ^ ord(y) ) for (x, y) in zip( T, U )]) \
if is_python2 else bytes([x ^ y for (x, y) in zip(T, U)]) # XORing
return T
L = int(keylen/dgsz) # L - number of output blocks to produce
if keylen % dgsz != 0: L += 1
h = hmac.new(key=passwd, msg=None, digestmod=digestmod )
T = b""
for i in range(1, L+1):
T += pbhelper(h, salt, iters, i)
return T[:keylen]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment