Example #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()
Example #2
0
        def decrypt_data():
            aes_cipher = AESCipher(client.secret_key)
            encrypted_uri = self.handler.request.headers.get(
                'X-Api-Encrypted-Uri')
            if encrypted_uri:
                request.uri = aes_cipher.decrypt(utf8(encrypted_uri))
                logger.debug('decrypted uri %s' % request.uri)

            encrypted_headers = self.handler.request.headers.get(
                'X-Api-Encrypted-Headers')

            if encrypted_headers:
                headers_str = aes_cipher.decrypt(utf8(encrypted_headers))
                headers = dict(json.loads(headers_str))
                logger.debug('raw headers %s' % request.headers)
                for k, v in headers.iteritems():
                    # 要全部使用 text_type,否则会出现有的为 str,有的为 unicode
                    # 导致422错误
                    request.headers[text_type(k)] = text_type(v)

                logger.debug('decrypted headers %s' % request.headers)

            if request.body and len(request.body) > 0:
                logger.debug('解密 body')
                logger.debug(request.body)
                request.body = aes_cipher.decrypt(utf8(request.body))
Example #3
0
        def decrypt_data():
            aes_cipher = AESCipher(client.secret_key)
            encrypted_uri = self.handler.request.headers.get('X-Api-Encrypted-Uri')
            if encrypted_uri:
                request.uri = aes_cipher.decrypt(utf8(encrypted_uri))
                logger.debug('decrypted uri %s' % request.uri)
                # 因为修改了 uri,需要重新生成 query_arguments
                request.path, sep, request.query = request.uri.partition('?')
                request.arguments = parse_qs_bytes(request.query, keep_blank_values=True)
                request.query_arguments = copy.deepcopy(request.arguments)

            encrypted_headers = self.handler.request.headers.get('X-Api-Encrypted-Headers')

            if encrypted_headers:
                headers_str = aes_cipher.decrypt(utf8(encrypted_headers))
                headers = dict(json_decode(headers_str))
                # logger.debug('raw headers %s' % request.headers)
                for k, v in iteritems(headers):
                    # 要全部使用 text_type,否则会出现有的为 str,有的为 unicode
                    # 导致422错误
                    request.headers[text_type(k)] = text_type(v)

                # logger.debug('decrypted headers %s' % request.headers)

            if request.body and len(request.body) > 0:
                logger.debug('解密 body')
                logger.debug(request.body)
                request.body = aes_cipher.decrypt(utf8(request.body))
                # 因为修改了 body,需要重新 _parse_body
                request._parse_body()
Example #4
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')
Example #5
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')
Example #6
0
 def getKey(self, cmd=False):
     if os.path.isfile('wallets/' + self.name + '.privkey'):
         with open('wallets/' + self.name + '.privkey',
                   'r',
                   encoding='utf-8') as key:
             encKey = key.read()
             enc = AESCipher(self.phrase)
             try:
                 self.key = enc.decrypt(encKey)
             except UnicodeDecodeError:
                 print(color.E('\nIncorrect passphrase for wallet!\n'))
     else:
         self.key = False
         print(color.E('\nWallet not found!\n'))
Example #7
0
    def decrypt_data(self, body):
        try:
            aes_cipher = AESCipher(self.secret_key)
            if body and len(body) > 0:
                logger.debug('解密 body')
                logger.debug(body.encode('hex'))
                body = aes_cipher.decrypt(utf8(body))
                # logger.debug(body.decode('hex'))
        except Exception as e:
            logger.error('解密数据出错')
            logger.error(e)
            logger.error(traceback.format_exc())
            return None

        return body
Example #8
0
    def decrypt_data(self, body):
        try:
            aes_cipher = AESCipher(self.secret_key)
            if body and len(body) > 0:
                logger.debug('解密 body')
                logger.debug(body.encode('hex'))
                body = aes_cipher.decrypt(utf8(body))
                # logger.debug(body.decode('hex'))
        except Exception as e:
            logger.error('解密数据出错')
            logger.error(e)
            logger.error(traceback.format_exc())
            return None

        return body
Example #9
0
    def decrypt_data(self, body):
        try:
            aes_cipher = AESCipher(self.secret_key)
            if body and len(body) > 0:
                logger.debug('解密 body')
                body = aes_cipher.decrypt(utf8(body))
                # logger.debug(body.decode('hex'))
        except Exception as e:
            logger.error('解密数据出错')
            logger.error(e)
            logger.error(traceback.format_exc())
            return None

        # 由于 requests 的 content 不是 unicode 类型, 为了兼容, 这里改成 utf8
        if isinstance(body, text_type):
            body = body.encode('utf-8')

        return body
Example #10
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
Example #11
0
    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 callback(message):
    logging.info("********** Start PubsubMessage ")
    message.ack()
    logging.info('Received message ID: {}'.format(message.message_id))
    logging.info('Received message publish_time: {}'.format(
        message.publish_time))

    if args.mode == 'decrypt':
        try:
            ac = AESCipher(key)
            logging.info("Loaded Key: " + ac.printKeyInfo())
            decrypted_data = ac.decrypt(message.data, associated_data='')
            logging.info('Decrypted data ' + decrypted_data)
            logging.info("ACK message")
            message.ack()
        except Exception as e:
            logging.info("Unable to decrypt message; NACK pubsub message " +
                         str(e))
            message.nack()
        logging.info("End AES decryption")

    if args.mode == 'verify':
        try:
            logging.info("Starting HMAC")
            hmac = message.attributes.get('signature')
            hh = HMACFunctions(key)
            logging.info("Loaded Key: " + hh.printKeyInfo())
            logging.info("Verify message: " + str(message.data))
            logging.info('  With HMAC: ' + str(hmac))
            hashed = hh.hash(message.data)
            if (hh.verify(message.data, base64.b64decode(hashed))):
                logging.info("Message authenticity verified")
                message.ack()
            else:
                logging.error("Unable to verify message")
                message.nack()
        except Exception as e:
            logging.info("Unable to verify message; NACK pubsub message " +
                         str(e))
            message.nack()

    logging.info("********** End PubsubMessage ")
Example #13
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
Example #14
0
    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
Example #15
0
def getcipher(Sessionid):
    Password = memcache.get(Sessionid + ".Password")
    IV = memcache.get(Sessionid + ".IV")
    if Password is None or IV is None:
        q = Endpoint.query(Endpoint.Sessionid == Sessionid)
        for rec in q.fetch(1):
            # logging.warning("Found")
            Password = str(rec.Password)
            IV = rec.IV
            memcache.add(Sessionid + ".Password", Password, 1800)
            memcache.add(Sessionid + ".IV", IV, 1800)
    #print("PASSWORD IS" + repr(Password))
    #print("IV IS" + repr(IV))
    try:

        cipher = AESCipher(Password, IV)
        return cipher
    except Exception:
        logging.warning("Not Found")
        return None
  logging.debug(" with wrapped signature key " + base64.b64encode(sign_key_wrapped).decode('utf-8') )

  logging.debug("End PubSub Publish")
  logging.info(">>>>>>>>>>> END <<<<<<<<<<<")

if args.mode =="encrypt":
    logging.info(">>>>>>>>>>> Start Encryption with locally generated key.  <<<<<<<<<<<")
    ## Send pubsub messages using two different symmetric keys
    ## Note, i'm not using the expiringdict here...i'm just picking a DEK, sending N messages using it
    ## then picking another DEK and sending N messages with that one.
    ## The subscriber will use a cache of DEK values.  If it detects a DEK in the metadata that doesn't 
    ## match whats in its cache, it will use KMS to try to decode it and then keep it in its cache.
    for x in range(30):
        logging.info("Rotating symmetric key")
        
        ac = AESCipher(encoded_key=None)
        dek = ac.getKey().encode()

        logging.debug("Generated dek: " + base64.b64encode(dek).decode() )

        logging.info("Starting KMS encryption API call")

        dek_encrypted = kms_client.encrypt(name=name, plaintext=dek,additional_authenticated_data=tenantID.encode('utf-8'))

        dek_key_wrapped = dek_encrypted.ciphertext
        logging.info("Wrapped dek: " +  base64.b64encode(dek_key_wrapped).decode('utf-8'))
        logging.info("End KMS encryption API call")

        logging.debug("Starting AES encryption")
                
        cleartext_message = {
cleartext_message = {
    "data": "foo".encode(),
    "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)
    msg = ac.encrypt(json.dumps(cleartext_message).encode('utf-8'),
                     associated_data='')
    logging.info("End AES encryption")
    logging.info("Start PubSub Publish")
    publisher.publish(topic_name, data=msg.encode('utf-8'))
    logging.info("Published Message: " + str(msg))
    logging.info("End PubSub Publish")

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

    logging.info("Start PubSub Publish")
Example #18
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)
if args.mode == "encrypt":
    logging.info(
        ">>>>>>>>>>> Start Encryption with locally generated key.  <<<<<<<<<<<"
    )
    ## Send pubsub messages using two different symmetric keys
    ## Note, i'm not using the expiringdict here...i'm just picking a DEK, sending N messages using it
    ## then picking another DEK and sending N messages with that one.
    ## The subscriber will use a cache of DEK values.  If it detects a DEK in the metadata that doesn't
    ## match whats in its cache, it will use KMS to try to decode it and then keep it in its cache.
    for x in range(5):
        logging.info("Rotating symmetric key")

        # create a new TINK AES DEK and encrypt it with KMS.
        #  (i.,e an encrypted tink keyset)
        cc = AESCipher(encoded_key=None)
        dek = cc.getKey()
        logging.info(cc.printKeyInfo())

        logging.debug("Generated dek: " + dek)
        logging.info("Starting KMS encryption API call")
        encrypt_response = kms_client.encrypt(
            request={
                'name': name,
                'plaintext': dek.encode('utf-8'),
                'additional_authenticated_data': tenantID.encode('utf-8')
            })

        dek_encrypted = base64.b64encode(
            encrypt_response.ciphertext).decode('utf-8')
Example #20
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)
Example #21
0
    def client_disconect(self):
        self.client.disconnect()
        return

if __name__ == '__main__':                           

    parser = argparse.ArgumentParser(description='Poc of BEAST attack')
    parser.add_argument('host', help='hostname or IP address "localhost"')
    parser.add_argument('port', type=int, help='TCP port number')
    parser.add_argument('-v', "--verbose", help='debug mode, you need a large screen', action="store_true")
    args = parser.parse_args()

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)

    # this key is unsecure but we doesn't care for the Poc
    cbc = AESCipher('V38lKILOJmtpQMHp')
    server   = Server(args.host, args.port)
    client   = Client(args.host, args.port+1, cbc)
    spy      = Proxy(args.host, args.port+1)
    exploit  = BEAST(client, cbc)

    server.connection()
    spy.connection()

    exploit.run()

    spy.disconnect()
    server.disconnect()
Example #22
0
 def __desencripta(self, dato):
     return AESCipher(self.__salt).decrypt(dato)
Example #23
0
    logging.info(
        ">>>>>>>>>>> Start Encrypt with Service Account Public Key Reference <<<<<<<<<<<"
    )
    logging.info('  Using remote public key_id = ' + args.recipient_key_id)
    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,
cleartext_message = {
    "data": "foo".encode(),
    "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'))
Example #25
0
def callback(message):

    if (args.mode == "verify"):
        try:
            logging.info("********** Start PubsubMessage ")
            logging.info('Received message ID: {}'.format(message.message_id))
            logging.info('Received message publish_time: {}'.format(
                message.publish_time))
            logging.info('Received message attributes["kms_key"]: {}'.format(
                message.attributes['kms_key']))
            logging.debug(
                'Received message attributes["sign_key_wrapped"]: {}'.format(
                    message.attributes['sign_key_wrapped']))
            logging.info('Received message attributes["signature"]: {}'.format(
                message.attributes['signature']))
            signature = message.attributes['signature']
            name = message.attributes['kms_key']
            sign_key_wrapped = message.attributes['sign_key_wrapped']

            try:
                unwrapped_key = cache[sign_key_wrapped]
                logging.info("Using Cached DEK")
            except KeyError:
                logging.info(
                    ">>>>>>>>>>>>>>>>   Starting KMS decryption API call")
                decrypted_message = kms_client.decrypt(
                    request={
                        'name':
                        name,
                        'ciphertext':
                        base64.b64decode(sign_key_wrapped.encode('utf-8')),
                        'additional_authenticated_data':
                        tenantID.encode('utf-8')
                    })
                logging.info("Decrypted HMAC " +
                             decrypted_message.plaintext.decode('utf-8'))

                unwrapped_key = HMACFunctions(
                    encoded_key=decrypted_message.plaintext)
                logging.info(unwrapped_key.printKeyInfo())
                cache[sign_key_wrapped] = unwrapped_key

                logging.info("End KMS decryption API call")
                logging.debug("Verify message: " +
                              message.data.decode('utf-8'))
                logging.debug('  With HMAC: ' + signature)

            sig = unwrapped_key.hash(message.data)

            if (unwrapped_key.verify(message.data, base64.b64decode(sig))):
                logging.info("Message authenticity verified")
                message.ack()
            else:
                logging.error("Unable to verify message")
                message.nack()
            logging.debug("********** End PubsubMessage ")
        except Exception as e:
            logging.info("Unable to decrypt message; NACK pubsub message " +
                         str(e))
            message.nack()

    if (args.mode == "decrypt"):
        try:
            logging.info("********** Start PubsubMessage ")
            logging.info('Received message ID: {}'.format(message.message_id))
            logging.info('Received message publish_time: {}'.format(
                message.publish_time))
            logging.info('Received message attributes["kms_key"]: {}'.format(
                message.attributes['kms_key']))
            logging.info(
                'Received message attributes["dek_wrapped"]: {}'.format(
                    message.attributes['dek_wrapped']))
            dek_wrapped = message.attributes['dek_wrapped']
            name = message.attributes['kms_key']

            try:
                dek = cache[dek_wrapped]
                logging.info("Using Cached DEK")
            except KeyError:
                logging.info(
                    ">>>>>>>>>>>>>>>>   Starting KMS decryption API call")
                decrypted_message = kms_client.decrypt(
                    request={
                        'name': name,
                        'ciphertext': base64.b64decode(
                            dek_wrapped.encode('utf-8')),
                        'additional_authenticated_data': tenantID.encode(
                            'utf-8')
                    })
                logging.info("Decrypted DEK " +
                             decrypted_message.plaintext.decode('utf-8'))

                dek = AESCipher(encoded_key=decrypted_message.plaintext)
                logging.info(dek.printKeyInfo())
                cache[dek_wrapped] = dek

            logging.debug("Starting AES decryption")

            decrypted_data = dek.decrypt(message.data,
                                         associated_data=tenantID)
            logging.debug("End AES decryption")
            logging.info('Decrypted data ' + decrypted_data)
            message.ack()
            logging.debug("ACK message")
            logging.info("********** End PubsubMessage ")
        except Exception as e:
            logging.info("Unable to decrypt message; NACK pubsub message " +
                         str(e))
            message.nack()
Example #26
0
def callback(message):

    logging.info("********** Start PubsubMessage ")
    logging.info('Received message ID: {}'.format(message.message_id))
    logging.info('Received message publish_time: {}'.format(
        message.publish_time))

    if args.mode == "verify":
        try:
            key_id = message.attributes['key_id']
            service_account = message.attributes['service_account']
            signature = message.attributes['signature']

            m = hashlib.sha256()
            m.update(message.data)
            data_to_verify = m.digest()

            logging.info("Attempting to verify message: " + str(message.data))
            logging.info("data_to_verify " +
                         base64.b64encode(data_to_verify).decode('utf-8'))
            logging.info("Verify message with signature: " + str(signature))
            logging.info("  Using service_account/key_id: " + service_account +
                         " " + key_id)

            cert_url = 'https://www.googleapis.com/service_accounts/v1/metadata/x509/' + service_account
            r = requests.get(cert_url)
            pem = r.json().get(key_id)
            v = crypt.RSAVerifier.from_string(pem)

            if v.verify(data_to_verify, base64.b64decode(signature)):
                logging.info("Message integrity verified")
                message.ack()
            else:
                logging.info("Unable to verify message")
                message.nack()
            logging.info("********** End PubsubMessage ")
        except Exception as e:
            logging.info("Unable to verify message; NACK pubsub message " +
                         str(e))
            message.nack()

    if args.mode == "decrypt":
        try:
            key_id = message.attributes['key_id']
            msg_service_account = message.attributes['service_account']

            logging.info("Attempting to decrypt message: " + str(message.data))
            logging.info("  Using service_account/key_id: " +
                         msg_service_account + " " + key_id)

            if args.cert_service_account == None:
                logging.error(
                    "********** cert_service_account must be specified to decrypt "
                )
                message.nack()
                sys.exit()

            credentials = Credentials.from_service_account_file(
                args.cert_service_account)
            key_key_id = credentials._signer._key_id

            key_service_account_email = credentials.service_account_email
            if (msg_service_account != key_service_account_email):
                logging.info(
                    "Service Account specified in command line does not match message payload service account"
                )
                logging.info(msg_service_account + " --- " +
                             args.cert_service_account)
                message.nack()
                return
            else:
                private_key = credentials._signer._key
                rs = RSACipher(private_key=private_key)
                try:
                    logging.debug(
                        'Received message attributes["dek_wrapped"]: {}'.
                        format(message.attributes['dek_wrapped']))
                    dek_wrapped = message.attributes['dek_wrapped']
                    logging.info('Wrapped DEK ' + dek_wrapped)
                    dek_cleartext = rs.decrypt(dek_wrapped)
                    logging.info('Decrypted DEK ' + dek_cleartext)
                    dek = AESCipher(encoded_key=dek_cleartext)
                    logging.info(dek.printKeyInfo())
                    plaintext = dek.decrypt(message.data, associated_data="")
                except ValueError:
                    logging.error(
                        "dek_wrapped not sent, attempting to decrypt with svc account rsa key"
                    )
                    plaintext = rs.decrypt(message.data)
                except Exception as e:
                    logging.error("Error Decrypting payload " + str(e))
                    message.nack()
                    return
                logging.info("Decrypted Message payload: " + plaintext)
                message.ack()
        except Exception as e:
            logging.info("Unable to decrypt message; NACK pubsub message " +
                         str(e))
            message.nack()

        logging.info("********** End PubsubMessage ")
Example #27
0
def callback(message):

    if (args.mode == "verify"):

        logging.info("********** Start PubsubMessage ")
        logging.info('Received message ID: {}'.format(message.message_id))
        logging.info('Received message publish_time: {}'.format(
            message.publish_time))
        logging.info('Received message attributes["kms_key"]: {}'.format(
            message.attributes['kms_key']))
        logging.info(
            'Received message attributes["sign_key_wrapped"]: {}'.format(
                message.attributes['sign_key_wrapped']))
        logging.info('Received message attributes["signature"]: {}'.format(
            message.attributes['signature']))
        signature = message.attributes['signature']
        name = message.attributes['kms_key']
        sign_key_wrapped = message.attributes['sign_key_wrapped']

        try:
            unwrapped_key = cache[sign_key_wrapped]
        except KeyError:
            logging.info("Starting KMS decryption API call")

            name = message.attributes['kms_key']
            unwrapped_key_struct = kms_client.decrypt(
                name=name,
                ciphertext=base64.b64decode(
                    message.attributes['sign_key_wrapped']),
                additional_authenticated_data=tenantID.encode('utf-8'))

            unwrapped_key = unwrapped_key_struct.plaintext

            logging.info("End KMS decryption API call")
            logging.debug("Verify message: " + message.data.decode('utf-8'))
            logging.debug('  With HMAC: ' + signature)
            logging.debug('  With unwrapped key: ' +
                          base64.b64encode(unwrapped_key).decode('utf-8'))
            cache[sign_key_wrapped] = unwrapped_key

        hh = HMACFunctions(unwrapped_key)
        sig = hh.hash(message.data)

        if (hh.verify(message.data, base64.b64decode(sig))):
            logging.info("Message authenticity verified")
            message.ack()
        else:
            logging.error("Unable to verify message")
            message.nack()
        logging.debug("********** End PubsubMessage ")

    if (args.mode == "decrypt"):
        logging.info("********** Start PubsubMessage ")
        logging.info('Received message ID: {}'.format(message.message_id))
        logging.debug('Received message publish_time: {}'.format(
            message.publish_time))
        logging.debug('Received message attributes["kms_key"]: {}'.format(
            message.attributes['kms_key']))
        logging.debug('Received message attributes["dek_wrapped"]: {}'.format(
            message.attributes['dek_wrapped']))
        dek_wrapped = message.attributes['dek_wrapped']
        name = message.attributes['kms_key']

        try:
            dek = cache[dek_wrapped]
        except KeyError:
            logging.info("Starting KMS decryption API call")

            name = message.attributes['kms_key']
            unwrapped_key_struct = kms_client.decrypt(
                name=name,
                ciphertext=base64.b64decode(dek_wrapped),
                additional_authenticated_data=tenantID.encode('utf-8'))

            dek = unwrapped_key_struct.plaintext

            logging.info("End KMS decryption API call")
            logging.info('Received aes_encryption_key : {}'.format(
                base64.b64encode(dek).decode('utf-8')))

            cache[dek_wrapped] = dek

        logging.debug("Starting AES decryption")
        ac = AESCipher(dek)
        decrypted_data = ac.decrypt(message.data, associated_data="")
        logging.debug("End AES decryption")
        logging.info('Decrypted data ' + decrypted_data)
        message.ack()
        logging.debug("ACK message")
        logging.info("********** End PubsubMessage ")