src/eric7/Utilities/crypto/py3PBKDF2.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9473
3f23dbf37dbe
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
25 25
26 26
27 def pbkdf2(password, salt, iterations, digestMod): 27 def pbkdf2(password, salt, iterations, digestMod):
28 """ 28 """
29 Module function to hash a password according to the PBKDF2 specification. 29 Module function to hash a password according to the PBKDF2 specification.
30 30
31 @param password clear text password (bytes) 31 @param password clear text password (bytes)
32 @param salt salt value (bytes) 32 @param salt salt value (bytes)
33 @param iterations number of times hash function should be applied (integer) 33 @param iterations number of times hash function should be applied (integer)
34 @param digestMod hash function 34 @param digestMod hash function
35 @return hashed password (bytes) 35 @return hashed password (bytes)
38 for _ in range(iterations): 38 for _ in range(iterations):
39 pwHash = hmac.new(salt, pwHash, digestMod).digest() 39 pwHash = hmac.new(salt, pwHash, digestMod).digest()
40 return pwHash 40 return pwHash
41 41
42 42
43 def hashPasswordTuple(password, digestMod=hashlib.sha512, iterations=10000, 43 def hashPasswordTuple(
44 saltSize=32): 44 password, digestMod=hashlib.sha512, iterations=10000, saltSize=32
45 ):
45 """ 46 """
46 Module function to hash a password according to the PBKDF2 specification. 47 Module function to hash a password according to the PBKDF2 specification.
47 48
48 @param password clear text password (string) 49 @param password clear text password (string)
49 @param digestMod hash function 50 @param digestMod hash function
50 @param iterations number of times hash function should be applied (integer) 51 @param iterations number of times hash function should be applied (integer)
51 @param saltSize size of the salt (integer) 52 @param saltSize size of the salt (integer)
52 @return tuple of digestname (string), number of iterations (integer), 53 @return tuple of digestname (string), number of iterations (integer),
57 pwHash = pbkdf2(password, salt, iterations, digestMod) 58 pwHash = pbkdf2(password, salt, iterations, digestMod)
58 digestname = digestMod.__name__.replace("openssl_", "") 59 digestname = digestMod.__name__.replace("openssl_", "")
59 return digestname, iterations, salt, pwHash 60 return digestname, iterations, salt, pwHash
60 61
61 62
62 def hashPassword(password, digestMod=hashlib.sha512, iterations=10000, 63 def hashPassword(password, digestMod=hashlib.sha512, iterations=10000, saltSize=32):
63 saltSize=32):
64 """ 64 """
65 Module function to hash a password according to the PBKDF2 specification. 65 Module function to hash a password according to the PBKDF2 specification.
66 66
67 @param password clear text password (string) 67 @param password clear text password (string)
68 @param digestMod hash function 68 @param digestMod hash function
69 @param iterations number of times hash function should be applied (integer) 69 @param iterations number of times hash function should be applied (integer)
70 @param saltSize size of the salt (integer) 70 @param saltSize size of the salt (integer)
71 @return hashed password entry according to PBKDF2 specification (string) 71 @return hashed password entry according to PBKDF2 specification (string)
72 """ 72 """
73 digestname, iterations, salt, pwHash = hashPasswordTuple( 73 digestname, iterations, salt, pwHash = hashPasswordTuple(
74 password, digestMod, iterations, saltSize) 74 password, digestMod, iterations, saltSize
75 return Delimiter.join([ 75 )
76 digestname, 76 return Delimiter.join(
77 str(iterations), 77 [
78 base64.b64encode(salt).decode("ascii"), 78 digestname,
79 base64.b64encode(pwHash).decode("ascii") 79 str(iterations),
80 ]) 80 base64.b64encode(salt).decode("ascii"),
81 base64.b64encode(pwHash).decode("ascii"),
82 ]
83 )
81 84
82 85
83 def verifyPassword(password, pwHash): 86 def verifyPassword(password, pwHash):
84 """ 87 """
85 Module function to verify a password against a hash encoded password. 88 Module function to verify a password against a hash encoded password.
86 89
87 @param password clear text password (string) 90 @param password clear text password (string)
88 @param pwHash hash encoded password in the form 91 @param pwHash hash encoded password in the form
89 'digestmod$iterations$salt$hashed_password' as produced by the 92 'digestmod$iterations$salt$hashed_password' as produced by the
90 hashPassword function (string) 93 hashPassword function (string)
91 @return flag indicating a successfull verification (boolean) 94 @return flag indicating a successfull verification (boolean)
95 try: 98 try:
96 digestname, iterations, salt, pwHash = pwHash.split(Delimiter) 99 digestname, iterations, salt, pwHash = pwHash.split(Delimiter)
97 except ValueError: 100 except ValueError:
98 raise ValueError( 101 raise ValueError(
99 "Expected hash encoded password in format " 102 "Expected hash encoded password in format "
100 "'digestmod{0}iterations{0}salt{0}hashed_password" 103 "'digestmod{0}iterations{0}salt{0}hashed_password".format(Delimiter)
101 .format(Delimiter)) 104 )
102 105
103 if digestname not in Hashes.keys(): 106 if digestname not in Hashes.keys():
104 raise ValueError( 107 raise ValueError(
105 "Unsupported hash algorithm '{0}' for hash encoded password '{1}'." 108 "Unsupported hash algorithm '{0}' for hash encoded password '{1}'.".format(
106 .format(digestname, pwHash)) 109 digestname, pwHash
107 110 )
111 )
112
108 iterations = int(iterations) 113 iterations = int(iterations)
109 salt = base64.b64decode(salt.encode("ascii")) 114 salt = base64.b64decode(salt.encode("ascii"))
110 pwHash = base64.b64decode(pwHash.encode("ascii")) 115 pwHash = base64.b64decode(pwHash.encode("ascii"))
111 password = password.encode("utf-8") 116 password = password.encode("utf-8")
112 return pwHash == pbkdf2(password, salt, iterations, Hashes[digestname]) 117 return pwHash == pbkdf2(password, salt, iterations, Hashes[digestname])
113 118
114 119
115 def rehashPassword(password, hashParameters): 120 def rehashPassword(password, hashParameters):
116 """ 121 """
117 Module function to recreate a password hash given the hash parameters. 122 Module function to recreate a password hash given the hash parameters.
118 123
119 @param password clear text password (string) 124 @param password clear text password (string)
120 @param hashParameters hash parameters in the form 125 @param hashParameters hash parameters in the form
121 'digestmod$iterations$salt' (string) 126 'digestmod$iterations$salt' (string)
122 @return hashed password (bytes) 127 @return hashed password (bytes)
123 @exception ValueError the hash parameters string is not of the expected 128 @exception ValueError the hash parameters string is not of the expected
126 try: 131 try:
127 digestname, iterations, salt = hashParameters.split(Delimiter) 132 digestname, iterations, salt = hashParameters.split(Delimiter)
128 except ValueError: 133 except ValueError:
129 raise ValueError( 134 raise ValueError(
130 "Expected hash parameters string in format " 135 "Expected hash parameters string in format "
131 "'digestmod{0}iterations{0}salt".format(Delimiter)) 136 "'digestmod{0}iterations{0}salt".format(Delimiter)
132 137 )
138
133 if digestname not in Hashes.keys(): 139 if digestname not in Hashes.keys():
134 raise ValueError( 140 raise ValueError(
135 "Unsupported hash algorithm '{0}' for hash parameters '{1}'." 141 "Unsupported hash algorithm '{0}' for hash parameters '{1}'.".format(
136 .format(digestname, hashParameters)) 142 digestname, hashParameters
137 143 )
144 )
145
138 iterations = int(iterations) 146 iterations = int(iterations)
139 salt = base64.b64decode(salt.encode("ascii")) 147 salt = base64.b64decode(salt.encode("ascii"))
140 password = password.encode("utf-8") 148 password = password.encode("utf-8")
141 return pbkdf2(password, salt, iterations, Hashes[digestname]) 149 return pbkdf2(password, salt, iterations, Hashes[digestname])

eric ide

mercurial