Skip to content

bwhmather/python-jpake

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Python JPake

Build Status Coverage

Python implementation of the J-PAKE password authenticated key agreement algorithm.

Written with reference to warner/python-jpake but makes use of python 3 features and presents a different api.

Installation

Recommended method is to use the version from pypi:

$ pip install jpake

Please note that this library only supports python versions 3.4 and later.

Usage

Basic usage demonstrating how to securely generate two copies of the same key in a single process:

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())

self.assertEqual(alice.K, bob.K)

More complete example:

def client_main():
    # Request that the server start a new connection.
    session_id = send_start_session()

    # Obtain a copy of the secret through the side-channel.
    secret = get_via_sidechannel()

    jpake = JPAKE(secret=secret, signer_id=b"client")

    server_one = send_handshake_phase_one(session_id, jpake.one())

    jpake.process_one(
        remote_gx1=server_one['gx1'], remote_zkp_x1=server_one['zkp_x1'],
        remote_gx2=server_one['gx2'], remote_zkp_x2=server_one['zkp_x2'],
    )

    server_two = send_handshake_phase_two(session_id, jpake.two())
    jpake.process_two(
        remote_A=server_two['A'], remote_zkp_A=server_two['zkp_A'],
    )

    send_secret_message("hello world", key=jpake.K)


def handle_start_session()
    session_id = generate_session_id()
    secret = generate_secret()

    db.put('secrets', session_id, secret)

    # Return the secret to the user via a trusted sidechannel.
    # DO NOT return the secret as a response, as doing so defeats the whole
    # purpose of the exercise.
    send_via_sidechannel(secret)

    return session_id

def handle_handshake_phase_one(session_id, client_one):
    # Load the shared secret from the datastore.
    secret = db.get('secrets', session_id)

    # Create a new JPAKE handshake object.
    jpake = JPAKE(secret=secret, signer_id="server")

    session.process_one(
        remote_gx1=client_one['gx1'], remote_zkp_x1=client_one['zkp_x1'],
        remote_gx2=client_one['gx2'], remote_zkp_x2=client_one['zkp_x2'],
    )

    # Save the important bits of the handshake to the db so that we can
    # restore it when we receive step 2.
    db.put('handshakes', session_id, {
        # Generated locally.
        'x1': session.x1,
        'x2': session.x2,
        # Sent by the client.
        'remote_gx1': session.remote_gx1,
        'remote_gx2': session.remote_gx2,
    })

    return session.one()

def handle_handshake_phase_two(handshake_id, client_two):
    # Reload the jpake handshake object from the db
    db.get
    jpake = JPAKE(
        x1=handshake['x3'], x=session['x4'],
        gx3=handshake['gx1'], gx4=handshake['gx2'],
        verify=False,
    )

    # Check the details sent by the client
    session.process_two(B=client_one['A'], zkp_B=client_one['zkp_A'])

    # Save to the database


def handle_secret_message(message):
    pass

License

This project is licensed under the BSD 3-clause revised license. See LICENSE for details.

About

Python implementation of the J-PAKE password authenticated key agreement algorithm

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages