3 # A simple implementation of pbkdf2 using stock python modules. See RFC2898
4 # for details. Basically, it derives a key from a password and salt.
6 # (c) 2004 Matt Johnston <matt @ ucc asn au>
7 # This code may be freely used and modified for any purpose.
10 # v0.1 October 2004 - Initial release
11 # v0.2 8 March 2007 - Make usable with hashlib in Python 2.5 and use
12 # v0.3 "" the correct digest_size rather than always 20
16 from binascii
import hexlify
, unhexlify
17 from struct
import pack
23 sha256
= hashlib
.sha256
29 # this is what you want to call.
30 def pbkdf2( password
, salt
, itercount
, keylen
, hashfn
= sha
):
32 # depending whether the hashfn is from hashlib or sha/md5
33 digest_size
= hashfn().digest_size
35 digest_size
= hashfn
.digest_size
36 # l - number of output blocks to produce
37 l
= keylen
/ digest_size
38 if keylen
% digest_size
!= 0:
41 h
= hmac
.new( password
, None, hashfn
)
44 for i
in range(1, l
+1):
45 T
+= pbkdf2_F( h
, salt
, itercount
, i
)
51 raise "xorstr(): lengths differ"
54 for i
in range(len(a
)):
55 ret
+= chr(ord(a
[i
]) ^
ord(b
[i
]))
64 # Helper as per the spec. h is a hmac which has been created seeded with the
65 # password, it will be copy()ed and not modified.
66 def pbkdf2_F( h
, salt
, itercount
, blocknum
):
67 U
= prf( h
, salt
+ pack('>i',blocknum
) )
70 for i
in range(2, itercount
+1):
78 # test vector from rfc3211
80 salt
= unhexlify( '1234567878563412' )
81 password
= 'All n-entities must communicate with other n-entities via n-1 entiteeheehees'
84 ret
= pbkdf2( password
, salt
, itercount
, keylen
)
85 hexret
= ' '.join(map(lambda c
: '%02x' % ord(c
), ret
)).upper()
86 print "key: %s" % hexret
87 print "expected: 6A 89 70 BF 68 C9 2C AE A8 4A 8D F2 85 10 85 86"
90 password
= unhexlify('6561696D72627A70636F706275736171746B6D77')
91 expect
= 'C9A0B2622F13916036E29E7462E206E8BA5B50CE9212752EB8EA2A4AA7B40A4CC1BF'
92 salt
= unhexlify('45248F9D0CEBCB86A18243E76C972A1F3B36772A')
95 ret
= pbkdf2( password
, salt
, itercount
, keylen
)
96 hexret
= hexlify(ret
).upper()
97 print "key: %s" % hexret
98 print "expected: %s" % expect
102 if __name__
== '__main__':