예제 #1
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 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),
                })))
예제 #4
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),
            })))
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')
예제 #6
0
def ls(conn: socket, args=None):
    # send list of files
    filelist = os.listdir('files/')
    filelist_json = json.dumps(filelist)
    send_msg(conn, _string_to_bytes(filelist_json))
예제 #7
0
                #    Step 1: Alice generates an RSA key pair PK=(n,e) and SK=(d)

                pubkey, privkey = rsa.newkeys(32, poolsize=8)

                print(pubkey)
                print(privkey)

                #    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)]