def test_basic(self): secret = "hunter42" alice = JPAKE(secret=secret, signer_id=b"alice") bob = JPAKE(secret=secret, signer_id=b"bob") alice.process_one(bob.one()), bob.process_one(alice.one()) alice.process_two(bob.two()), bob.process_two(alice.two()) self.assertEqual(alice.K, bob.K)
def test_process_two_twice(self): secret = "hunter42" alice = JPAKE(secret=secret, signer_id=b"alice") bob = JPAKE(secret=secret, signer_id=b"bob") alice.process_one(bob.one()), bob.process_one(alice.one()) bob_two = bob.two() alice.process_two(bob_two) self.assertRaises(OutOfSequenceError, alice.process_two, bob_two)
def test_step_two_before_secret(self): alice = JPAKE(signer_id=b"alice") bob = JPAKE(signer_id=b"bob") bob.process_one(alice.one()) self.assertRaises(OutOfSequenceError, bob.two)
def do_tests(self, params): pw = "password" jA, jB = JPAKE(pw, params=params), JPAKE(pw, params=params) m1A, m1B = jA.one(), jB.one() m2A, m2B = jA.two(m1B), jB.two(m1A) kA, kB = jA.three(m2B), jB.three(m2A) self.failUnlessEqual(hexlify(kA), hexlify(kB)) self.failUnlessEqual(len(kA), len(sha256().digest())) jA, jB = JPAKE(pw, params=params), JPAKE("passwerd", params=params) m1A, m1B = jA.one(), jB.one() m2A, m2B = jA.two(m1B), jB.two(m1A) kA, kB = jA.three(m2B), jB.three(m2A) self.failIfEqual(hexlify(kA), hexlify(kB)) self.failUnlessEqual(len(kA), len(sha256().digest())) self.failUnlessEqual(len(kB), len(sha256().digest()))
def test_default_is_80(self): pw = "password" jA, jB = JPAKE(pw, params=params_80), JPAKE(pw) m1A, m1B = jA.one(), jB.one() m2A, m2B = jA.two(m1B), jB.two(m1A) kA, kB = jA.three(m2B), jB.three(m2A) self.failUnlessEqual(hexlify(kA), hexlify(kB)) self.failUnlessEqual(len(kA), len(sha256().digest()))
def test_skip_verification_one(self): secret = "hunter42" alice = JPAKE(secret=secret, signer_id=b"alice") bob = JPAKE(secret=secret, signer_id=b"bob") bob_one = bob.one() alice.process_one(gx3=bob_one['gx1'], gx4=bob_one['gx2'], verify=False)
class Harness: def setup(self, params=params_80): self.params = params self.pw = pw = "password" self.jA = JPAKE(pw, signerid="Alice", params=params) self.jB = JPAKE(pw, signerid="Bob", params=params) self.m1A,self.m1B = self.jA.one(), self.jB.one() self.m2A,self.m2B = self.jA.two(self.m1B), self.jB.two(self.m1A) #kA,kB = self.jA.three(m2B), self.jB.three(m2A) def construct(self): JPAKE(self.pw, signerid="Alice", params=self.params) def one(self): self.jA.one() def two(self): self.jA.two(self.m1B) def three(self): self.jA.three(self.m2B)
def test_success(self): pw = "password" jA, jB = JPAKE(pw, signerid="Alice"), JPAKE(pw, signerid="Bob") m1A, m1B = jA.one(), jB.one() m2A, m2B = jA.two(m1B), jB.two(m1A) kA, kB = jA.three(m2B), jB.three(m2A) self.failUnlessEqual(hexlify(kA), hexlify(kB)) self.failUnlessEqual(len(kA), len(sha256().digest()))
def test_process_one_twice(self): secret = "hunter42" alice = JPAKE(secret=secret, signer_id=b"alice") bob = JPAKE(secret=secret, signer_id=b"bob") alice_one = alice.one() bob.process_one(alice_one) self.assertRaises(OutOfSequenceError, bob.process_one, alice_one)
def test_skip_verification_on_dict(self): secret = "hunter42" alice = JPAKE(secret=secret, signer_id=b"alice") bob = JPAKE(secret=secret, signer_id=b"bob") self.assertRaises(ValueError, alice.process_one, bob.one(), verify=False)
def test_failure(self): pw = "password" jA, jB = JPAKE(pw), JPAKE("passwerd") m1A, m1B = jA.one(), jB.one() m2A, m2B = jA.two(m1B), jB.two(m1A) kA, kB = jA.three(m2B), jB.three(m2A) self.failIfEqual(hexlify(kA), hexlify(kB)) self.failUnlessEqual(len(kA), len(sha256().digest())) self.failUnlessEqual(len(kB), len(sha256().digest()))
def test_no_proofs_one(self): secret = "hunter42" alice = JPAKE(secret=secret, signer_id=b"alice") bob = JPAKE(secret=secret, signer_id=b"bob") bob_one = bob.one() self.assertRaises(Exception, alice.process_one, gx3=bob_one['gx1'], gx4=bob_one['gx2'])
class Harness: def setup(self, params=params_80): self.params = params self.pw = pw = "password" self.jA = JPAKE(pw, signerid="Alice", params=params) self.jB = JPAKE(pw, signerid="Bob", params=params) self.m1A, self.m1B = self.jA.one(), self.jB.one() self.m2A, self.m2B = self.jA.two(self.m1B), self.jB.two(self.m1A) #kA,kB = self.jA.three(m2B), self.jB.three(m2A) def construct(self): JPAKE(self.pw, signerid="Alice", params=self.params) def one(self): self.jA.one() def two(self): self.jA.two(self.m1B) def three(self): self.jA.three(self.m2B)
def main(): if len(sys.argv) == 1: print "Usage: ./desktop.py <jpake-password> [server-url]" sys.exit(1) s = sys.argv[1] if len(s) != 12: print "Invalid J-PAKE code. Not 12 characters long" sys.exit(1) (password,channel) = (s[0:4] + s[4:8], s[8:12]) if len(sys.argv) == 3: server = sys.argv[2] else: server = "http://localhost:5000" url = "%s/%s" % (server, channel) print "X Password = %s" % password print "X Channel = %s" % channel print "X Server = %s" % server print "X Channel URL = %s" % url j = JPAKE(password, signerid="sender", params=params_128) # Get Server.Message1 print "X Getting Server.Message1" server_one = get(url) print "X Got Server.Message1: %s" % str(server_one) # Put Client.Message1 print "X Putting Client.Message1" client_one = { 'type': 'sender1', 'payload': j.one() } client_one_etag = put(url, client_one) print "X Put Client.Message1 (etag=%s) %s" % (client_one_etag, client_one) # Get Server.Message2 print "X Getting Server.Message2" while True: try: server_two = get(url, client_one_etag) break except urllib2.HTTPError, e: if e.code == 304: print "X Did not get right response yet. Trying again." pass else: raise time.sleep(1)
def test_signerid(self): pw = "password" jA, jB = JPAKE(pw, signerid="a"), JPAKE(pw, signerid="b") m1A, m1B = jA.one(), jB.one() m2A, m2B = jA.two(m1B), jB.two(m1A) kA, kB = jA.three(m2B), jB.three(m2A) self.failUnlessEqual(hexlify(kA), hexlify(kB)) self.failUnlessEqual(len(kA), len(sha256().digest())) jA, jB = JPAKE(pw, signerid="a"), JPAKE("passwerd", signerid="b") m1A, m1B = jA.one(), jB.one() m2A, m2B = jA.two(m1B), jB.two(m1A) kA, kB = jA.three(m2B), jB.three(m2A) self.failIfEqual(hexlify(kA), hexlify(kB)) self.failUnlessEqual(len(kA), len(sha256().digest())) self.failUnlessEqual(len(kB), len(sha256().digest())) jA, jB = JPAKE(pw, signerid="same"), JPAKE(pw, signerid="same") m1A, m1B = jA.one(), jB.one() self.failUnlessRaises(DuplicateSignerID, jA.two, m1B) self.failUnlessRaises(DuplicateSignerID, jB.two, m1A)
def test_pack(self): pw = "password" jA, jB = JPAKE(pw, signerid="Alice"), JPAKE(pw, signerid="Bob") m1A, m1B = jA.one(), jB.one() m1Ap = jA.pack_one(m1A) #print "m1:", len(json.dumps(m1A)), len(m1Ap) m2A, m2B = jA.two(m1B), jB.two(jB.unpack_one(m1Ap)) m2Ap = jA.pack_two(m2A) #print "m2:", len(json.dumps(m2A)), len(m2Ap) kA, kB = jA.three(m2B), jB.three(jB.unpack_two(m2Ap)) self.failUnlessEqual(hexlify(kA), hexlify(kB)) self.failUnlessEqual(len(kA), len(sha256().digest()))
def test_entropy(self): entropy = PRNG("seed") pw = "password" jA, jB = JPAKE(pw, entropy=entropy), JPAKE(pw, entropy=entropy) m1A1, m1B1 = jA.one(), jB.one() m2A1, m2B1 = jA.two(m1B1), jB.two(m1A1) kA1, kB1 = jA.three(m2B1), jB.three(m2A1) self.failUnlessEqual(hexlify(kA1), hexlify(kB1)) # run it again with the same entropy stream: all messages should be # identical entropy = PRNG("seed") jA, jB = JPAKE(pw, entropy=entropy), JPAKE(pw, entropy=entropy) m1A2, m1B2 = jA.one(), jB.one() m2A2, m2B2 = jA.two(m1B2), jB.two(m1A2) kA2, kB2 = jA.three(m2B2), jB.three(m2A2) self.failUnlessEqual(hexlify(kA2), hexlify(kB2)) self.failUnlessEqual(m1A1, m1A2) self.failUnlessEqual(m1B1, m1B2) self.failUnlessEqual(m2A1, m2A2) self.failUnlessEqual(m2B1, m2B2) self.failUnlessEqual(kA1, kA2) self.failUnlessEqual(kB1, kB2)
def test_ascii(self): self.failUnlessRaises(SignerIDMustBeASCII, JPAKE, "pw", signerid="not-ascii\xff") jA, jB = JPAKE("pw", signerid="Alice"), JPAKE("pw", signerid="Bob") m1A = jA.one() m1Ap = jA.pack_one(m1A) # now doctor m1Ap to contain non-ascii, to exercise the check in # unpack_one. We happen to know that the signerid is stored at the # end of the packed structure assert m1Ap[-5:] == "Alice" m1Ap_bad = m1Ap[:-5] + "Alic\xff" self.failUnlessRaises(SignerIDMustBeASCII, jA.unpack_one, m1Ap_bad) # same for message two m2A = jA.two(jB.one()) m2Ap = jA.pack_two(m2A) assert m2Ap[-5:] == "Alice" m2Ap_bad = m2Ap[:-5] + "Alic\xff" self.failUnlessRaises(SignerIDMustBeASCII, jA.unpack_two, m2Ap_bad)
from jpake import JPAKE secret = "1234" alice = JPAKE(secret=secret, signer_id=b"alice") bob = JPAKE(secret=secret, signer_id=b"bob") alice.process_one(bob.one()) bob.process_one(alice.one()) alice.process_two(bob.two()) bob.process_two(alice.two()) print(alice.K) print(bob.K)
class PAKEClient (object): def __init__(self, server, password, identity, channel = None): self.password = password self.server = server self.identity = identity self.channel = channel self.session_id = ''.join(["%x" % random.randint(0,15) for i in range(256)]) self.jpake = JPAKE(password, signerid=identity, params=params_128) self.key = None self.message_one = None self.message_one_etag = None self.remote_message_one = None self.message_two = None self.message_two_etag = None self.remote_message_two = None self.message_three = None self.message_three_etag = None self.remote_message_three = None pass def get(self, url, etag = None): headers = {'X-KeyExchange-Id': self.session_id} if etag: headers['If-None-Match'] = etag request = urllib2.Request(url, None, headers) start = time.time() response = urllib2.urlopen(request) data = response.read() duration = time.time() - start return (duration, simplejson.loads(data)) def get_message(self, etag = None): return self.get("%s/%s" % (self.server, self.channel), etag) def put(self, url, data): #print "X %s.put %s" % (self.identity, str(data)) opener = urllib2.build_opener(urllib2.HTTPHandler) json = simplejson.dumps(data) request = urllib2.Request(url, data=json, headers={'X-KeyExchange-Id': self.session_id}) request.add_header('Content-Type', 'application/json') request.get_method = lambda: 'PUT' start = time.time() response = urllib2.urlopen(request) duration = time.time() - start return (duration, response.info().getheader('Etag')) def put_message(self, data): return self.put("%s/%s" % (self.server, self.channel), data) def createChannel(self): #print "X %s.createChannel" % self.identity (duration, self.channel) = self.get("%s/new_channel" % self.server) print "OK %0.4f CREATE" % (duration) def putMessageOne(self): #print "X %s.putMessageOne" % self.identity self.message_one = { 'type': '%s1' % self.identity, 'payload': self.jpake.one() } (duration, self.message_one_etag) = self.put_message(self.message_one) print "OK %.04f PUT 1 %s" % (duration, self.identity) def getMessageOne(self): #print "X %s.getMessageOne" % self.identity (duration, self.remote_message_one) = self.get_message(self.message_one_etag) print "OK %0.4f GET 1 %s" % (duration, self.identity) def putMessageTwo(self): #print "X %s.putMessageTwo" % self.identity self.message_two = { 'type': '%s2' % self.identity, 'payload': self.jpake.two(self.remote_message_one['payload']) } (duration, self.message_two_etag) = self.put_message(self.message_two) print "OK %0.4f PUT 2 %s" % (duration, self.identity) def getMessageTwo(self): #print "X %s.getMessageTwo" % self.identity (duration, self.remote_message_two) = self.get_message(self.message_two_etag) print "OK %0.4f GET 2 %s" % (duration, self.identity) def putMessageThree(self): #print "X %s.putMessageThree" % self.identity self.key = self.jpake.three(self.remote_message_two['payload']) self.message_three = { 'type': '%s3' % self.identity, 'payload': sha256(sha256(self.key).digest()).hexdigest() } (duration, self.message_three_etag) = self.put_message(self.message_three) print "OK %0.4f PUT 3 %s" % (duration, self.identity) def getMessageThree(self): #print "X %s.getMessageThree" % self.identity (duration, self.remote_message_three) = self.get_message(self.message_three_etag) print "OK %0.4f GET 1 %s" % (duration, self.identity)
print "X Password = %s" % password print "X URL = %s" % url j = JPAKE(password, signerid="sender", params=params_80) # Get Server.Message1 print "X Getting Server.Message1" server_one = get(url) print "X Got Server.Message1: %s" % str(server_one) # Put Client.Message1 print "X Putting Client.Message1" client_one = { 'type': 'sender1', 'payload': j.one() } client_one_etag = put(url, client_one) print "X Put Client.Message1 (etag=%s) %s" % (client_one_etag, client_one) # Get Server.Message2 print "X Getting Server.Message2" while True: try: server_two = get(url, client_one_etag) break except urllib2.HTTPError, e: if e.code == 304: print "X Did not get right response yet. Trying again." pass else: