Esempio n. 1
0
def openWallet():
    name = input('Wallet Name ("[new]" to create wallet): ')
    if name != '[new]':
        if not os.path.isfile('wallets/' + name + '.privkey'):
            print(color.E('\nWallet not found!\n'))
            openWallet()
        phrase = getpass.getpass('Passphrase: ')
        wallet = Wallet(name, phrase)
        wallet.getKey()
        if wallet.key:
            print(color.I('\nOpened wallet ' + wallet.name + '\n'))
            print('\nType "help" to view commands\n')
            walletPrompt(wallet)
        else:
            openWallet()
    else:
        name = input('New wallet name: ')
        phrase = getpass.getpass('New passphrase for wallet: ')
        if not os.path.isfile('wallets/' + name + '.privkey'):
            newkey = RSA.generate(3072)
            privkey = newkey.exportKey().decode('utf-8')
            with open('wallets/' + name + '.privkey', 'a') as privf:
                enc = AESCipher(phrase)
                encKey = enc.encrypt(privkey)
                privf.write(str(encKey))
            print(color.I('Wallet created successfully!\n'))
            openWallet()
        else:
            print('Wallet with name "' + name + '" already exists!')
            openWallet()
Esempio n. 2
0
 def encrypt_data(body):
     # 如果请求的使用 AES 加密,则加密返回的数据
     logger.debug('使用 AES 加密 body')
     aes_cipher = AESCipher(client.secret_key)
     body = aes_cipher.encrypt(utf8(body))
     # 更新为加密后的数据
     self.handler.clear_write_buffer()
     self.handler.write(body)
     self.handler.set_header('X-Api-Encrypt-Type', 'aes')
Esempio n. 3
0
 def encrypt_data(body):
     # 如果请求的使用 AES 加密,则加密返回的数据
     logger.debug('使用 AES 加密 body')
     aes_cipher = AESCipher(client.secret_key)
     body = aes_cipher.encrypt(utf8(body))
     # 更新为加密后的数据
     self.handler.clear_write_buffer()
     self.handler.write(body)
     self.handler.set_header('X-Api-Encrypt-Type', 'aes')
Esempio n. 4
0
    def encrypt_data(self):
        aes_cipher = AESCipher(self.secret_key)
        headers_str = json_util.dumps(self.request_data.headers)
        # 加密 Headers 和 url
        self.request_data.headers = {
            'Content-Type': 'application/octet-stream',
            'X-Api-Encrypted-Headers': aes_cipher.encrypt(utf8(headers_str)),
            'X-Api-Encrypted-Uri': aes_cipher.encrypt(utf8(self.request_data.uri))
        }
        self.request_data.uri = '/?_t=%d&_nonce=%s' % \
                                (int(time.time()), text_type(random.random()))

        # 设置一个新的 url
        url = self.api_server.strip() + self.request_data.uri

        if self.request_data.body is not None and len(self.request_data.body) > 0:
            self.request_data.body = aes_cipher.encrypt(utf8(self.request_data.body))
            logger.debug(self.request_data.body)
        return url
Esempio n. 5
0
    def encrypt_data(self):
        aes_cipher = AESCipher(self.secret_key)
        headers_str = json_util.dumps(self.request_data.headers)
        # 加密 Headers 和 url
        self.request_data.headers = {
            'Content-Type': 'application/octet-stream',
            'X-Api-Encrypted-Headers': aes_cipher.encrypt(utf8(headers_str)),
            'X-Api-Encrypted-Uri':
            aes_cipher.encrypt(utf8(self.request_data.uri))
        }
        self.request_data.uri = '/?_t=%d&_nonce=%s' % \
                                (int(time.time()), text_type(random.random()))

        # 设置一个新的 url
        url = self.api_server.strip() + self.request_data.uri

        if self.request_data.body is not None and len(
                self.request_data.body) > 0:
            self.request_data.body = aes_cipher.encrypt(
                utf8(self.request_data.body))
            logger.debug(self.request_data.body)
        return url
    "attributes": {
        'epoch_time': int(time.time()),
        'a': "aaa",
        'c': "ccc",
        'b': "bbb"
    }
}
# cleartext_message = canonicaljson.encode_canonical_json(cleartext_message)
# logging.info("Canonical JSON message " + cleartext_message.decode('utf-8'))

if args.mode == 'encrypt':
    logging.info("Starting AES encryption")

    ac = AESCipher(key)
    logging.info("Loaded Key: " + ac.printKeyInfo())
    msg = ac.encrypt(json.dumps(cleartext_message).encode('utf-8'),
                     associated_data='')
    logging.info("End AES encryption")
    logging.info("Start PubSub Publish")
    resp = publisher.publish(topic_name, data=msg.encode('utf-8'))
    logging.info("Published Message: " + str(msg))
    logging.info("Published MessageID: " + resp.result())
    logging.info("End PubSub Publish")

if args.mode == 'sign':
    logging.info("Starting signature")
    hh = HMACFunctions(key)
    logging.info("Loaded Key: " + hh.printKeyInfo())
    msg_hash = hh.hash(json.dumps(cleartext_message).encode('utf-8'))
    logging.info("End signature")

    logging.info("Start PubSub Publish")
Esempio n. 7
0
class ClientConnector(Protocol):
    """Handle one connection to a client.

    Its functions include:
        - Initiate connection to client.
        - Send an authentication message to client to start transmission.
        - Receive encrypted data packets from client, separated by split_char.
        - Decrypt data packets. Get the ID (first 2 bytes of decrypted text).
          Create a connection to HTTP proxy for each unique ID.
        - Forward request to HTTP proxy. Encrypt and send back the response.
        - Close connection to HTTP proxy for a given ID if a packet
          of the ID with close_char is received.
    """
    def __init__(self, initiator):
        self.initiator = initiator

        self.main_pw = self.initiator.main_pw
        # control characters
        self.split_char = chr(27) + chr(28) + "%X" % struct.unpack(
            'B', self.main_pw[-2:-1])[0] + "%X" % struct.unpack(
                'B', self.main_pw[-3:-2])[0] + chr(31)
        self.client_pub = self.initiator.client_pub
        self.session_pw = urandom(16)
        self.cipher = AESCipher(self.session_pw, self.main_pw)
        self.authenticated = False
        self.buffer = ""
        self.latency = 10000
        self.i = initiator.register()
        self.idchar = (str(self.i) if 10 <= self.i <= 99 else '0' +
                       str(self.i))
        self.cronjob = None
        self.cancel_job = None

    def generate_auth_msg(self):
        """Generate encrypted message. For auth and init.

        The message is in the form
            server_sign(main_pw) (HEX) +
            client_pub(session_pw) + id
        Total length is 512 + 256 + 2 = 770 bytes
        """
        pw_enc = self.client_pub.encrypt(self.session_pw, None)[0]
        return '\r\n'.join(
            (self.initiator.signature_to_client, pw_enc, self.idchar,
             repr(self.initiator.client_recv_index_dict[self.i])))

    def ping_send(self):
        """Send the initial ping message to the client at a certain interval.

        Ping mechanism (S for server, C for client, t-i for i-th timestamp):
            packet 0: S->C, t-0
            packet 1: C->S, t-0 + t-1
            packet 2: S->C, t-1
        In this way, both server and client get the round-trip latency.

        Packet format (before encryption):
            "1"         (1 byte)          (type flag for ping)
            seq         (1 byte)          (0, 1 or 2)
            timestamp   (11 or 22 bytes)  (time in milliseconds, in hexagon)
        """
        raw_packet = "1" + "0" + get_timestamp()
        to_write = self.cipher.encrypt(raw_packet) + self.split_char
        if self.authenticated:
            #logging.debug("send ping0")
            self.transport.write(to_write)
            interval = random.randint(500, 1500) / 100
            if self.initiator.obfs_level == 3:
                RESET_INTERVAL = 5
            else:
                RESET_INTERVAL = 2
            self.cronjob = reactor.callLater(interval, self.ping_send)
            self.cancel_job = reactor.callLater(RESET_INTERVAL, self.close)

    def ping_recv(self, msg):
        """Parse ping 1 (without flag & seq) and send ping 2."""
        #logging.debug("recv ping1")
        self.cancel_job.cancel()
        time0 = parse_timestamp(msg[:11])
        self.latency = int(time() * 1000) - time0
        logging.debug("latency: %dms" % self.latency)
        raw_packet = "1" + "2" + msg[11:]
        to_write = self.cipher.encrypt(raw_packet) + self.split_char
        if self.transport:
            #logging.debug("send ping2")
            self.transport.write(to_write)

    def connectionMade(self):
        """Event handler of being successfully connected to the client."""
        logging.info("connected to client " +
                     addr_to_str(self.transport.getPeer()))
        self.transport.write(self.generate_auth_msg() + self.split_char)

    def dataReceived(self, recv_data):
        """Event handler of receiving some data from client.

        Split, decrypt and hand them back to Control.
        """
        # Avoid repetition caused by ping
        # logging.debug("received %d bytes from client " % len(recv_data) +
        #              addr_to_str(self.transport.getPeer()))

        self.buffer += recv_data

        # a list of encrypted data packages
        # the last item may be incomplete
        recv = self.buffer.split(self.split_char)
        # leave the last (may be incomplete) item intact
        for text_enc in recv[:-1]:
            text_dec = self.cipher.decrypt(text_enc)
            # flag is 0 for normal data packet, 1 for ping packet, 2 for auth
            flag = int(text_dec[0])
            if flag == 0:
                self.initiator.client_recv(text_dec[1:], self)
            elif flag == 2:
                auth_str = "AUTHENTICATED" + self.idchar
                if text_dec[1:].startswith(auth_str):
                    max_recved_idx = eval(text_dec[1:].lstrip(auth_str))
                    self.authenticate_success()
                    self.initiator.retransmit_clientconn_reload(
                        self, max_recved_idx)
                else:
                    self.close()
            else:
                # strip off type and seq (both are always 1)
                self.ping_recv(text_dec[2:])

        self.buffer = recv[-1]  # incomplete message

    def authenticate_success(self):
        self.authenticated = True
        logging.debug("Authentication confirm string received.")
        self.initiator.add_cli(self)
        self.ping_send()

    def close(self):
        '''a secure way to abort the connection'''
        try:
            self.cronjob.cancel()
        except Exception:
            pass
        # self.initiator.remove_cli(self)
        self.transport.loseConnection()

    def connectionLost(self, reason):
        """Event handler of losing the connection to the client.

        Call Control to handle it.
        """
        if self.authenticated:
            logging.info("client connection lost: " +
                         addr_to_str(self.transport.getPeer()))
        self.authenticated = False
        self.initiator.client_lost(self.i)

    def write(self, data, conn_id, index):
        """Encrypt and write data the client.

        Encrypted packets should be separated by split_char.
        Raw packet structure:
            type    (1 byte)   (0 for normal data packet)
            id      (2 bytes)
            index   (6 bytes)
            data
        """
        if index < 100000:
            index = '0' * (6 - len(str(index))) + str(index)
        else:
            index = str(index)
        # get current time with base 36 as a string in a certain length .
        to_write = self.cipher.encrypt("0" + conn_id + index + data) +\
            self.split_char
        logging.debug(
            "sending %d bytes to client %s with id %s" %
            (len(data), addr_to_str(self.transport.getPeer()), conn_id))
        self.transport.write(to_write)
        publisher = pubsub.PublisherClient()
        logging.info("Start PubSub Publish")
        ## Send 5 messages using the same symmetric key...
        for x in range(5):
            cleartext_message = {
                "data": "foo".encode(),
                "attributes": {
                    'epoch_time': int(time.time()),
                    'a': "aaa",
                    'c': "ccc",
                    'b': "bbb"
                }
            }
            logging.debug("Start AES encryption")
            encrypted_message = cc.encrypt(
                json.dumps(cleartext_message).encode('utf-8'),
                associated_data=tenantID)
            logging.debug("End AES encryption")
            logging.debug("Encrypted Message with dek: " + encrypted_message)

            topic_name = 'projects/{project_id}/topics/{topic}'.format(
                project_id=pubsub_project_id,
                topic=PUBSUB_TOPIC,
            )

            resp = publisher.publish(topic_name,
                                     data=encrypted_message.encode(),
                                     kms_key=name,
                                     dek_wrapped=dek_encrypted)
            logging.info("Published Message: " + encrypted_message)
            logging.info("Published MessageID: " + resp.result())
Esempio n. 9
0
class ClientConnector(Protocol):
    """Handle one connection to a client.

    Its functions include:
        - Initiate connection to client.
        - Send an authentication message to client to start transmission.
        - Receive encrypted data packets from client, separated by split_char.
        - Decrypt data packets. Get the ID (first 2 bytes of decrypted text).
          Create a connection to HTTP proxy for each unique ID.
        - Forward request to HTTP proxy. Encrypt and send back the response.
        - Close connection to HTTP proxy for a given ID if a packet
          of the ID with close_char is received.
    """

    def __init__(self, initiator):
        self.initiator = initiator

        self.main_pw = self.initiator.main_pw
        # control characters
        # self.split_char = chr(27) + chr(28) + chr(29) + chr(30) + chr(31)
        self.split_char = chr(27) + chr(28) + "%X" % struct.unpack('B', self.main_pw[-2:-1])[
            0] + "%X" % struct.unpack('B', self.main_pw[-3:-2])[0] + chr(31)
        self.pri = self.initiator.initiator.pri
        self.client_pub = self.initiator.client_pub
        self.session_pw = urandom(16)
        self.cipher = AESCipher(self.session_pw, self.main_pw)
        self.authenticated = False
        self.buffer = ""
        self.latency = 10000
        self.idchar = initiator.register()
        self.cronjob = None
        self.cancel_job = None

    def generate_auth_msg(self):
        """Generate encrypted message.

        The message is in the form
            server_sign(main_pw) (HEX) +
            client_pub(session_pw) + id
        Total length is 512 + 256 + 2 = 770 bytes
        """
        hex_sign = '%X' % self.pri.sign(self.main_pw, None)[0]
        pw_enc = self.client_pub.encrypt(self.session_pw, None)[0]
        return hex_sign + pw_enc + self.idchar

    def ping_send(self):
        """Send the initial ping message to the client at a certain interval.

        Ping mechanism (S for server, C for client, t-i for i-th timestamp):
            packet 0: S->C, t-0
            packet 1: C->S, t-0 + t-1
            packet 2: S->C, t-1
        In this way, both server and client get the round-trip latency.

        Packet format (before encryption):
            "1"         (1 byte)          (type flag for ping)
            seq         (1 byte)          (0, 1 or 2)
            timestamp   (11 or 22 bytes)  (time in milliseconds, in hexagon)
        """
        raw_packet = "1" + "0" + get_timestamp()
        to_write = self.cipher.encrypt(raw_packet) + self.split_char
        if self.authenticated:
            #logging.debug("send ping0")
            self.transport.write(to_write)
            interval = random.randint(500, 1500) / 100
            if self.initiator.obfs_level == 3:
                RESET_INTERVAL = 5
            else:
                RESET_INTERVAL = 2
            self.cronjob = reactor.callLater(interval, self.ping_send)
            self.cancel_job = reactor.callLater(RESET_INTERVAL, self.close)

    def ping_recv(self, msg):
        """Parse ping 1 (without flag & seq) and send ping 2."""
        #logging.debug("recv ping1")
        self.cancel_job.cancel()
        time0 = parse_timestamp(msg[:11])
        self.latency = int(time() * 1000) - time0
        logging.debug("latency: %dms" % self.latency)
        raw_packet = "1" + "2" + msg[11:]
        to_write = self.cipher.encrypt(raw_packet) + self.split_char
        if self.transport:
            #logging.debug("send ping2")
            self.transport.write(to_write)

    def connectionMade(self):
        """Event handler of being successfully connected to the client."""
        logging.info("connected to client " +
                     addr_to_str(self.transport.getPeer()))
        self.transport.write(self.generate_auth_msg())

    def dataReceived(self, recv_data):
        """Event handler of receiving some data from client.

        Split, decrypt and hand them back to Control.
        """
        # Avoid repetition caused by ping
        # logging.debug("received %d bytes from client " % len(recv_data) +
        #              addr_to_str(self.transport.getPeer()))

        self.buffer += recv_data

        # a list of encrypted data packages
        # the last item may be incomplete
        recv = self.buffer.split(self.split_char)
        # leave the last (may be incomplete) item intact
        for text_enc in recv[:-1]:
            text_dec = self.cipher.decrypt(text_enc)
            # flag is 0 for normal data packet, 1 for ping packet
            flag = int(text_dec[0])
            if flag == 0:
                self.initiator.client_recv(text_dec[1:])
            elif flag == 2:
                if text_dec[1:] == "AUTHENTICATED" + self.idchar:
                    self.authenticate_success()
                else:
                    self.close()
            else:
                # strip off type and seq (both are always 1)
                self.ping_recv(text_dec[2:])

        self.buffer = recv[-1]  # incomplete message

    def authenticate_success(self):
        self.authenticated = True
        logging.debug("Authentication confirm string received.")
        self.initiator.add_cli(self)
        self.ping_send()

    def close(self):
        '''a secure way to abort the connection'''
        try:
            self.cronjob.cancel()
        except Exception:
            pass
        self.transport.loseConnection()

    def connectionLost(self, reason):
        """Event handler of losing the connection to the client.

        Call Control to handle it.
        """
        if self.authenticated:
            logging.info("client connection lost: " +
                         addr_to_str(self.transport.getPeer()))
        self.authenticated = False
        self.initiator.client_lost(self)

    def write(self, data, conn_id, index):
        """Encrypt and write data the client.

        Encrypted packets should be separated by split_char.
        Raw packet structure:
            type    (1 byte)   (0 for normal data packet)
            id      (2 bytes)
            index   (6 bytes)
            data
        """

        to_write = self.cipher.encrypt("0" + conn_id + index + data) +\
            self.split_char
        logging.debug("sending %d bytes to client %s with id %s" % (len(data),
                                                                    addr_to_str(
                                                                        self.transport.getPeer()),
                                                                    conn_id))
        self.transport.write(to_write)
Esempio n. 10
0
    logging.info(
        '  For service account at: https://www.googleapis.com/service_accounts/v1/metadata/x509/'
        + args.recipient)

    cert_url = 'https://www.googleapis.com/service_accounts/v1/metadata/x509/' + args.recipient
    r = requests.get(cert_url)
    pem = r.json().get(args.recipient_key_id)
    rs = RSACipher(public_key_pem=pem)

    # Create a new TINK AES key used for data encryption
    cc = AESCipher(encoded_key=None)
    dek = cc.getKey()
    logging.info("Generated DEK: " + cc.printKeyInfo())

    # now use the DEK to encrypt the pubsub message
    encrypted_payload = cc.encrypt(
        json.dumps(cleartext_message).encode('utf-8'), associated_data="")
    logging.info("DEK Encrypted Message: " + encrypted_payload)
    # encrypt the DEK with the service account's key
    dek_wrapped = rs.encrypt(dek.encode('utf-8'))
    logging.info("Wrapped DEK " + dek_wrapped.decode('utf-8'))

    # now publish the dek-encrypted message, the encrypted dek
    resp = publisher.publish(topic_name,
                             data=encrypted_payload.encode('utf-8'),
                             service_account=args.recipient,
                             key_id=args.recipient_key_id,
                             dek_wrapped=dek_wrapped)

    # alternatively, dont' bother with the dek; just use the rsa key itself to encrypt the message
    #encrypted_payload = rs.encrypt(json.dumps(cleartext_message).encode('utf-8'))
    #resp=publisher.publish(topic_name, data=json.dumps(encrypted_payload).encode('utf-8'), service_account=args.recipient, key_id=args.recipient_key_id)