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, distributed, relicensed, and modified for any
11 # v0.1 October 2004 - Initial release
12 # v0.2 8 March 2007 - Make usable with hashlib in Python 2.5 and use
13 # v0.3 "" the correct digest_size rather than always 20
14 # v0.4 13 March 2009 - Mention distribution and relicensing in the copyright
18 from binascii
import hexlify
, unhexlify
19 from struct
import pack
25 sha256
= hashlib
.sha256
31 # this is what you want to call.
32 def pbkdf2( password
, salt
, itercount
, keylen
, hashfn
= sha
):
34 # depending whether the hashfn is from hashlib or sha/md5
35 digest_size
= hashfn().digest_size
37 digest_size
= hashfn
.digest_size
38 # l - number of output blocks to produce
39 l
= keylen
/ digest_size
40 if keylen
% digest_size
!= 0:
43 h
= hmac
.new( password
, None, hashfn
)
46 for i
in range(1, l
+1):
47 T
+= pbkdf2_F( h
, salt
, itercount
, i
)
53 raise "xorstr(): lengths differ"
56 for i
in range(len(a
)):
57 ret
+= chr(ord(a
[i
]) ^
ord(b
[i
]))
66 # Helper as per the spec. h is a hmac which has been created seeded with the
67 # password, it will be copy()ed and not modified.
68 def pbkdf2_F( h
, salt
, itercount
, blocknum
):
69 U
= prf( h
, salt
+ pack('>i',blocknum
) )
72 for i
in range(2, itercount
+1):
80 # test vector from rfc3211
82 salt
= unhexlify( '1234567878563412' )
83 password
= 'All n-entities must communicate with other n-entities via n-1 entiteeheehees'
86 ret
= pbkdf2( password
, salt
, itercount
, keylen
)
87 hexret
= ' '.join(map(lambda c
: '%02x' % ord(c
), ret
)).upper()
88 print "key: %s" % hexret
89 print "expected: 6A 89 70 BF 68 C9 2C AE A8 4A 8D F2 85 10 85 86"
92 password
= unhexlify('6561696D72627A70636F706275736171746B6D77')
93 expect
= 'C9A0B2622F13916036E29E7462E206E8BA5B50CE9212752EB8EA2A4AA7B40A4CC1BF'
94 salt
= unhexlify('45248F9D0CEBCB86A18243E76C972A1F3B36772A')
97 ret
= pbkdf2( password
, salt
, itercount
, keylen
)
98 hexret
= hexlify(ret
).upper()
99 print "key: %s" % hexret
100 print "expected: %s" % expect
104 if __name__
== '__main__':