def send_command(args, callback=lambda sock: print("Connected", sock)):
    """connects to the server and sends the command

    :param args:   this object is similar to the one parsed from the commandline,
        contains "host" and "port" members
    :param callback(sock, respjson): a function to call when connected to the server.
        sock:   Gets passed the socket object, the socket object at this point is already connected and is ready to send or recv.
    :return the callback result
    """

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        print('connecting to server...', end='')
        s.connect((args.host, args.port))  # connect
        print('\rConnection established                       ')

        # random initialization vector
        setattr(args, 'iv', secrets.token_bytes(16))

        if not hasattr(args, 'cipherfunc'):
            setattr(args, 'cipherfunc', CipherLib.none)

        ################
        # serialize args
        ################
        import copy
        s_args = copy.deepcopy(vars(args))
        for k, v in s_args.items():
            if isinstance(v,
                          types.FunctionType):  # functions get the name passed
                s_args[k] = v.__name__
            elif isinstance(v, bytes):  # bytes get turned into strings
                s_args[k] = _bytes_to_string(v)

        s_args['cipher'] = s_args.get('cipherfunc', 'none')
        del s_args['key']  # delete key (otherwise is sent in plaintext)

        request_json = json.dumps(s_args)
        print('Sending command: "{}"'.format(request_json))

        # send the command/request json
        send_msg(s, _string_to_bytes(request_json))

        # check if server acknowledged the command
        # (if resp is included in one of the success response codes)
        resp = recv_msg(s)
        resp_json = AttrDict(json.loads(_bytes_to_string(resp)))
        if resp_json.readystate in [202]:
            res = callback(s)

            send_msg(s, b'200')  # send OK code
            print('\nTransaction complete')
            return res
    def callback(conn: socket):
        ciphertext = b''
        with open(filename, 'rb') as f:
            data = f.read()
            ciphertext = args.cipherfunc(data=data, key=args.key, iv=args.iv)

        return send_msg(
            conn,
            _string_to_bytes(
                json.dumps({
                    'filename': filename,
                    'data': _bytes_to_string(ciphertext),
                    'iv': _bytes_to_string(args.iv),
                })))
Exemple #3
0
def put(conn: socket, args=None):
    # recv file from client and write to file
    print('receiving file...')
    client_data = AttrDict(json.loads(_bytes_to_string(recv_msg(conn))))

    args.filename = os.path.join('files', args.filename)

    data = client_data.data

    if data is None:
        print("Problem: data received is None")
    print("got the file data!: {}Bytes".format(len(data)))

    if not os.path.isdir('./files'):
        os.mkdir('./files')

    with open(args.filename, 'wb+') as file:
        plaintext = args.cipherfunc(data=data,
                                    key=args.key,
                                    decrypt=True,
                                    iv=client_data.iv)
        file.write(plaintext)

    print('recieved file:', args.filename)

    if os.path.isfile(args.filename):
        subprocess.Popen(r'explorer /select,"{}"'.format(args.filename))
    def callback(conn: socket):
        # receive data
        resp = AttrDict(json.loads(_bytes_to_string(recv_msg(conn))))

        if args.file_index:
            args.filename = resp.filename
            delattr(args, 'file_index')

        if not os.path.isdir('./files'):
            os.mkdir('./files')

        filename = args.filename \
            if args.filename.startswith('files') \
            else os.path.join('files', args.filename)

        if os.path.isdir(filename):
            args.filename = os.path.join(args.filename, resp.filename)

        # === done preparing filesystem ===

        with open(filename, 'wb+') as f:
            plaintext = args.cipherfunc(data=resp.data,
                                        key=args.key,
                                        decrypt=True,
                                        iv=resp.iv)
            f.write(plaintext)
            if os.path.isfile(filename):
                subprocess.Popen(r'explorer /select,"{}"'.format(filename))
Exemple #5
0
def get(conn: socket, args=None):
    # send the file to client
    if args.file_index:
        args.filename = os.listdir('files')[int(args.filename)]

    iv = secrets.token_bytes(16)
    args_filename = args.filename
    filename = os.path.join('files', args_filename)
    with open(filename, 'rb') as f:
        plaintext = f.read()
        ciphertext = args.cipherfunc(data=plaintext, key=args.key, iv=iv)
    print("finished reading file \"{}\", {}B".format(filename,
                                                     len(ciphertext)))

    return send_msg(
        conn,
        _string_to_bytes(
            json.dumps({
                'filename': filename,
                'data': _bytes_to_string(ciphertext),
                'iv': _bytes_to_string(iv),
            })))
Exemple #6
0
def recv_next_command(conn: socket, client_parser=None):
    """
    waits for a command by the client, and returns the parsed args,
    responds to the client with 202 and data on success

    :param conn: socket connection
    :return: client command arguments, or None if invalid command
    """
    command_json = _bytes_to_string(recv_msg(conn))
    print("received req:", command_json)

    try:
        #
        #
        #
        client_args = {  # extend defaults
            'file_index': None,
            'local': False,
            'key': DEFAULT_KEY,
            'cipher': 'none',
            'filename': '',
            'function': lambda x: None,
            'iv': None,
        }
        client_args.update(json.loads(command_json))  # update
        client_args = AttrDict(client_args)

        # converting args (parsing strings to bytes and function names to functions)
        client_args.cipherfunc = getattr(CipherLib, client_args.cipher)
        client_args.iv = _string_to_bytes(client_args.iv)
        client_args.function = eval(client_args.function)

        # printing object:
        import pprint
        pp = pprint.PrettyPrinter(indent=4)
        print('client_args received')
        pp.pprint(vars(client_args))

        #

        server_resp = _string_to_bytes(
            json.dumps({
                'readystate': 202,  # code "202" meaning (accepted)
            }))
        send_msg(conn, server_resp)
        return client_args
    except Exception as e:
        print("ERROR executing command:", e)
        return None
def main():
    """
    Step 1: Alice generates an RSA key pair PK=(n,e) and SK=(d) and  generates two random  values, r_0 and r_1, and sends them to Bob along with her PK
    Step 2: Bob picks a bit b to be either 0 or 1, and selects r_b
    Step 3: Bob generates a random value k and blinds  r_b by computing  〖v=r〗_b+k^e  mod n and send it to Alice
    Step 4: Alice doesn't know which of  r_0 and r_1 Bob chose.
        She applies them both and come up with two possible values for k:k_0=(v−x_0 )^d  mod n and k_1=(v−x_1 )^d  mod n 
 Eventually,
        one of these will be equal to  k and can be correctly decrypted by Bob (but not Alice),
        while the other will produce a meaningless random value that does not  reveal any  information about  k
    Step 5: Alice combines the two secret messages with each of the possible keys, m_0^′=m_0+k_0 and m_1^′=m_1+k_1, and sends them both to Bob
    Step 6: Bob knows which of the two messages can be unblinded with  k, so he is able to compute  exactly one of the messages m_b=m_b^′−k
    :return:
    """
    parser = get_arg_parser()
    print(DESCRIPTION + "\n")

    args = parser.parse_args()

    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        print('connecting to server...', end='')
        s.connect((args.host, args.port))  # connect
        print('\rConnection established ')

        # recv public key
        resp = recv_msg(s)
        resp = json.loads(_bytes_to_string(resp))

        alice_pubkey = rsa.PublicKey(resp['n'], resp['e'])
        r_b_choices = list(map(_string_to_bytes, resp['r_b_choices']))

        print('alice_pubkey', alice_pubkey)
        print('r_b_choices', r_b_choices)

        #    Step 2: Bob picks a bit b to be either 0 or 1, and selects r_bs
        r_b = int.from_bytes(r_b_choices[args.msg_index], 'big')

        #    Step 3: Bob generates a random value k and blinds  r_b by computing  〖v=r〗_b+k^e  mod n and send it to Alice
        k = secrets.token_bytes(4)
        k_int = int.from_bytes(k, 'big')
        print('k=', k_int)
        print('r_b=', r_b)
        v = _string_to_bytes(str(alice_pubkey.blind(r_b, k_int)))

        print('v=', v)
        send_msg(s, v)

        #    Step 6: Bob knows which of the two messages can be unblinded with  k, so he is able to compute  exactly one of the messages m_b=m_b^′−k
        resp6 = recv_msg(s)
        resp6_str = _bytes_to_string(resp6)
        print('resp6_str=', resp6_str)
        combined_list = resp6_str.split(',')
        combined_list = list(map(_string_to_bytes, combined_list))

        f = Fernet(k)

        # value = combined_list[args.msg_index] ^ k_int
        value = f.decrypt(combined_list[args.msg_index])

        print('the value is:', value)

        if resp in [202]:
            send_msg(s, b'200')  # send OK code
            print('\nTransaction complete')
Exemple #8
0
currentdir = os.path.dirname(
    os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)

from utils import send_msg, recv_msg, SafeArgumentParser, AttrDict
from encryption_utils import CipherLib, _string_to_bytes, _bytes_to_string

os.chdir(os.path.dirname(
    os.path.realpath(__file__)))  # move path to file dir, to access files

# 256 bits = 32 bytes
# b'c37ddfe20d88021bc66a06706ac9fbdd0bb2dc0b043cf4d22dbbbcda086f0f48'
DEFAULT_KEY = _bytes_to_string(
    b'\xc3\x7d\xdf\xe2\x0d\x88\x02\x1b\xc6\x6a\x06\x70\x6a\xc9\xfb\xdd\x0b\xb2\xdc\x0b\x04\x3c\xf4\xd2\x2d\xbb\xbc\xda\x08\x6f\x0f\x48'
)


def get_arg_parser():
    parser = argparse.ArgumentParser("Server side app")
    parser.add_argument(
        '--port',
        default=65431,
        type=int,
        help='Port to listen on (non-privileged ports are > 1023)')
    parser.add_argument('--host',
                        default='127.0.0.1',
                        type=str,
                        help='the ipv4 address to open connections')
Exemple #9
0
                #    generates n random  values, r_0 and r_1, and sends them to Bob along with her PK
                r_b_choices = [secrets.token_bytes(4) for i in range(args.n_msgs)]
                
                json_string = json.dumps({
                    'e': pubkey.e,
                    'n': pubkey.n,
                    'r_b_choices': list(map(_bytes_to_string, r_b_choices)),
                })
                send_msg(conn, _string_to_bytes(json_string))

                # Step 4: Alice doesn't know which of  r_0 and r_1 Bob chose.
                #         She applies them both and come up with two possible values for k:k_0=(v−x_0 )^d  mod n and k_1=(v−x_1 )^d  mod n  Eventually,
                #         one of these will be equal to  k and can be correctly decrypted by Bob (but not Alice),
                #         while the other will produce a meaningless random value that does not  reveal any  information about k
                resp4 = recv_msg(conn)
                v = _bytes_to_string(resp4)
                print('v=', v)
                print('r_b_choices=', r_b_choices)
                k_list = [privkey.unblind(v, int.from_bytes(r_b, 'big')) for r_b in r_b_choices]
                
                print('k_list=', k_list)

                # combining the message with the key: m' = m+k
                # combined_msgs = [messages[i] ^ k_list[i] for i in range(args.n_msgs)]
                print('before getting msgs')
                
                combined_msgs = [Fernet(k_list[i]).encrypt(messages[i]) for i in range(args.n_msgs)]
                print('after msg list')
                combined_msgs = ','.join(list(map(_bytes_to_string, combined_msgs))) # serialized
                print('sending combined_msgs:', combined_msgs)
                send_msg(conn, combined_msgs)