-
Notifications
You must be signed in to change notification settings - Fork 0
/
pbkdf.py
71 lines (56 loc) · 1.67 KB
/
pbkdf.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#!/usr/bin/python
"""
Given a password p, salt s and length l, output a NIST SP800-132 compliant Master Key.
Implements PBKDF2.
original : http://matt.ucc.asn.au/src/pbkdf2.py
# (c) 2004 Matt Johnston <matt @ ucc asn au>
# This code may be freely used, distributed, relicensed, and modified for any
# purpose.
"""
from Crypto.Hash import SHA256
import hmac
import binascii
from struct import pack, unpack
import warnings
def prf( h, data ):
hm = h.copy()
hm.update( data )
return hm.digest()
def xorstr( a, b ):
if len(a) != len(b):
raise "xorstr(): lengths differ"
ret = ''
for i in range(len(a)):
ret += chr(ord(a[i]) ^ ord(b[i]))
return ret
def pbkdf2_F( h, salt, itercount, blocknum ):
U = prf( h, salt + pack('>i',blocknum ) )
T = U
for i in range(2, itercount+1):
U = prf( h, U )
T = xorstr( T, U )
return T
def pbkdf(password, salt, itercount=10**5, keylen=32, hashfn = SHA256):
""" callme """
warnings.simplefilter("ignore", RuntimeWarning,0)
digest_size = hashfn.digest_size
# l - number of output blocks to produce
l = keylen / digest_size
if keylen % digest_size != 0:
l += 1
h = hmac.new( password, None, hashfn )
T = ""
for i in range(1, l+1):
T += pbkdf2_F( h, salt, itercount, i )
return T[0: keylen]
def hexdigest(ret):
return "".join(map(lambda c: '%02x' % ord(c), ret))
if __name__ == "__main__":
password = "Those who work for the few die by the many."
salt = binascii.unhexlify("1234567878563412")
rounds = 10 ** 6
keylen = 32 # bytes
print "Iterating..."
ret = pbkdf( password, salt, rounds, keylen )
hexret = "".join(map(lambda c: '%02x' % ord(c), ret))
print "key: %s "%hexret