40 for i in range(iterations): |
40 for i in range(iterations): |
41 hash = hmac.new(salt, hash, digestMod).digest() |
41 hash = hmac.new(salt, hash, digestMod).digest() |
42 return hash |
42 return hash |
43 |
43 |
44 |
44 |
45 def hashPasswordTuple(password, digestMod=hashlib.sha512, iterations=10000, saltSize=32): |
45 def hashPasswordTuple(password, digestMod=hashlib.sha512, iterations=10000, |
|
46 saltSize=32): |
46 """ |
47 """ |
47 Module function to hash a password according to the PBKDF2 specification. |
48 Module function to hash a password according to the PBKDF2 specification. |
48 |
49 |
49 @param password clear text password (string) |
50 @param password clear text password (string) |
50 @param digestMod hash function |
51 @param digestMod hash function |
58 hash = pbkdf2(password, salt, iterations, digestMod) |
59 hash = pbkdf2(password, salt, iterations, digestMod) |
59 digestname = digestMod.__name__.replace("openssl_", "") |
60 digestname = digestMod.__name__.replace("openssl_", "") |
60 return digestname, iterations, salt, hash |
61 return digestname, iterations, salt, hash |
61 |
62 |
62 |
63 |
63 def hashPassword(password, digestMod=hashlib.sha512, iterations=10000, saltSize=32): |
64 def hashPassword(password, digestMod=hashlib.sha512, iterations=10000, |
|
65 saltSize=32): |
64 """ |
66 """ |
65 Module function to hash a password according to the PBKDF2 specification. |
67 Module function to hash a password according to the PBKDF2 specification. |
66 |
68 |
67 @param password clear text password (string) |
69 @param password clear text password (string) |
68 @param digestMod hash function |
70 @param digestMod hash function |
94 """ |
96 """ |
95 try: |
97 try: |
96 digestname, iterations, salt, pwHash = hash.split(Delimiter) |
98 digestname, iterations, salt, pwHash = hash.split(Delimiter) |
97 except ValueError: |
99 except ValueError: |
98 raise ValueError( |
100 raise ValueError( |
99 "Expected hash encoded password in format "\ |
101 "Expected hash encoded password in format " |
100 "'digestmod{0}iterations{0}salt{0}hashed_password".format(Delimiter)) |
102 "'digestmod{0}iterations{0}salt{0}hashed_password" |
|
103 .format(Delimiter)) |
101 |
104 |
102 if digestname not in Hashes.keys(): |
105 if digestname not in Hashes.keys(): |
103 raise ValueError( |
106 raise ValueError( |
104 "Unsupported hash algorithm '{0}' for hash encoded password '{1}'.".format( |
107 "Unsupported hash algorithm '{0}' for hash encoded password '{1}'." |
105 digestname, hash)) |
108 .format(digestname, hash)) |
106 |
109 |
107 iterations = int(iterations) |
110 iterations = int(iterations) |
108 salt = base64.b64decode(salt.encode("ascii")) |
111 salt = base64.b64decode(salt.encode("ascii")) |
109 pwHash = base64.b64decode(pwHash.encode("ascii")) |
112 pwHash = base64.b64decode(pwHash.encode("ascii")) |
110 password = password.encode("utf-8") |
113 password = password.encode("utf-8") |
117 |
120 |
118 @param password clear text password (string) |
121 @param password clear text password (string) |
119 @param hashParameters hash parameters in the form |
122 @param hashParameters hash parameters in the form |
120 'digestmod$iterations$salt' (string) |
123 'digestmod$iterations$salt' (string) |
121 @return hashed password (bytes) |
124 @return hashed password (bytes) |
122 @exception ValueError the hash parameters string is not of the expected format |
125 @exception ValueError the hash parameters string is not of the expected |
123 or the digest is not one of the known ones |
126 format or the digest is not one of the known ones |
124 """ |
127 """ |
125 try: |
128 try: |
126 digestname, iterations, salt = hashParameters.split(Delimiter) |
129 digestname, iterations, salt = hashParameters.split(Delimiter) |
127 except ValueError: |
130 except ValueError: |
128 raise ValueError( |
131 raise ValueError( |
129 "Expected hash parameters string in format "\ |
132 "Expected hash parameters string in format "\ |
130 "'digestmod{0}iterations{0}salt".format(Delimiter)) |
133 "'digestmod{0}iterations{0}salt".format(Delimiter)) |
131 |
134 |
132 if digestname not in Hashes.keys(): |
135 if digestname not in Hashes.keys(): |
133 raise ValueError( |
136 raise ValueError( |
134 "Unsupported hash algorithm '{0}' for hash parameters '{1}'.".format( |
137 "Unsupported hash algorithm '{0}' for hash parameters '{1}'." |
135 digestname, hash)) |
138 .format(digestname, hash)) |
136 |
139 |
137 iterations = int(iterations) |
140 iterations = int(iterations) |
138 salt = base64.b64decode(salt.encode("ascii")) |
141 salt = base64.b64decode(salt.encode("ascii")) |
139 password = password.encode("utf-8") |
142 password = password.encode("utf-8") |
140 return pbkdf2(password, salt, iterations, Hashes[digestname]) |
143 return pbkdf2(password, salt, iterations, Hashes[digestname]) |