def test_ldap_salted_sha1(self): logging.info("---===test_ldap_salted_sha1===--") erh = ersatzlib.ErsatzHashGenerator(hash.ldap_salted_sha1, user, realPW, ersatzPW) erh.initSaltHash() self.verify_test(erh) print erh.hash logging.info("Passed!")
def test_md5_crypt(self): logging.info("---===test_md5_crypt===--") erh = ersatzlib.ErsatzHashGenerator(hash.md5_crypt, user, realPW, ersatzPW) erh.initSaltHash() self.verify_test(erh) print erh.hash logging.info("Passed!")
def test_ldap_sha512_crypt(self): logging.info("---===test_ldap_sha512_crypt===--") erh = ersatzlib.ErsatzHashGenerator(hash.ldap_sha512_crypt, user, realPW, ersatzPW, rounds=hashRounds) erh.initSaltHash() self.verify_test(erh) print erh.hash logging.info("Passed!")
def _test_pbkdf2_sha256(self): logging.info("---===test_pbkdf2_sha256===--") erh = ersatzlib.ErsatzHashGenerator(hash.pbkdf2_sha256, user, realPW, ersatzPW, rounds=hashRounds) erh.initSaltHash() self.verify_test(erh) print erh.hash logging.info("Passed!")
def new(password, server=defaultServer, clientId=None, username="******"): """ Encrypts a new @password by interacting with the Pythia service. @clientId: If specified, this value is used. If omitted, a suitable value is selected. @returns a tuple of required values to verify the password: (w,t,z,p) where: @w: client ID (key selector) @t: tweak (randomly generated user ID) @z: protected passwords @p: server public key bound to clientId - used to verify future proofs from this server. """ # Set the client ID if not clientId: w = secureRandom() else: w = clientId if ersatzHash == True: ersatzPw = "ersatz" ersatzHashGen = ersatzlib.ErsatzHashGenerator(hash.pbkdf2_sha1,\ username, password, \ ersatzPw, rounds=5000) #create ersatz salt t = ersatzHashGen._compute_ersatz_salt(password, ersatzPw) ersatzHashGen.salt = t a = ersatzHashGen._compute_ersatz_hash(password) a = passlib.utils.ab64_decode(a) #create ersatz input ersatzInput = ersatzHashGen._ersatzfy_input(password) z, p = query(ersatzInput, w, t, server) z = vpop.wrap( pyrelic.vpop.update(vpop.unwrapY(z), long(a.encode('hex'), 16))) #do the Z^a nonsense, where a is the pbkdf2 else: t = secureRandom() hashedPW = pbkdf2_sha1.encrypt(password, salt=t, rounds=5000) z, p = query(hashedPW, w, t, server) z = vpop.wrap( pyrelic.vpop.update(vpop.unwrapY(z), long(hashedPW.encode('hex'), 16))) #t = secureRandom() #z,p = query(password, w, t, server) return w, t, z, p
def check(password, w, t, z, p, server=defaultServer, username="******"): """ Checks an existing @password against the Pythia server using the values (w,t,z,p). @returns: True if the password passes authentication; False otherwise. """ if ersatzHash: ersatzHashGen = ersatzlib.ErsatzHashGenerator(hash.pbkdf2_sha1,\ username, password, \ "ersatz", rounds=5000) ersatzHashGen.salt = t ersatzInput = ersatzHashGen._ersatzfy_input(password) #check true password zPrime1, _ = query(ersatzInput, w, t, previousPubkey=p, server=server) zPrime2, _ = query(password, w, t, previousPubkey=p, server=server) #create ersatz salt a = passlib.utils.ab64_decode( ersatzHashGen._compute_ersatz_hash(password)) zPrime1 = vpop.wrap( pyrelic.vpop.update(vpop.unwrapY(zPrime1), long(a.encode('hex'), 16))) a = passlib.utils.ab64_decode( hash.pbkdf2_sha1.encrypt(password, salt=t, rounds=5000)) zPrime2 = vpop.wrap( pyrelic.vpop.update(vpop.unwrapY(zPrime2), long(a.encode('hex'), 16))) if z == zPrime1: return 1 elif z == zPrime2: return 2 else: return 0 #check ersatz password else: hashedPW = pbkdf2_sha1.encrypt(password, salt=t, rounds=5000) zPrime, _ = query(hashedPW, w, t, previousPubkey=p, server=server) zPrime = vpop.wrap( pyrelic.vpop.update(vpop.unwrapY(zPrime), long(hashedPW.encode('hex'), 16))) #zPrime,_ = query(password, w, t, previousPubkey=p, server=server) return z == zPrime
def time_ersatz_hash(hashFunc, username, realPW, ersatzPW, \ hashRounds, count): erh = ersatzlib.ErsatzHashGenerator(hashFunc, username, realPW, \ ersatzPW, rounds=hashRounds) erh.initSaltHash() saltTime = list() for i in range(count): start = timeit.default_timer() erh._compute_ersatz_salt(realPW, ersatzPW) stop = timeit.default_timer() saltTime.append(stop - start) hashTime = list() for i in range(count): start = timeit.default_timer() erh._compute_ersatz_hash(realPW) stop = timeit.default_timer() hashTime.append(stop - start) verifyTrueTime = list() for i in range(count): start = timeit.default_timer() erh.verify(realPW) stop = timeit.default_timer() verifyTrueTime.append(stop - start) verifyErsatzTime = list() for i in range(count): start = timeit.default_timer() erh.verify(ersatzPW) stop = timeit.default_timer() verifyErsatzTime.append(stop - start) verifyFalseTime = list() for i in range(count): start = timeit.default_timer() erh.verify("false") stop = timeit.default_timer() verifyFalseTime.append(stop - start) return {"saltTime":saltTime, "hashTime":hashTime,\ "verifyTrueTime":verifyTrueTime,\ "verifyErsatzTime":verifyErsatzTime,\ "verifyFalseTime":verifyFalseTime}
def test_multithreaded(self): logging.info("---===test_multithreaded===--") erh = ersatzlib.ErsatzHashGenerator(hash.sha1_crypt, user, realPW, ersatzPW, rounds=hashRounds) erh.initSaltHash() start = timeit.default_timer() erh.multithreaded_verify(realPW) stop = timeit.default_timer() print stop - start start = timeit.default_timer() erh.verify(realPW) stop = timeit.default_timer() print stop - start logging.info("Passed!")