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 ")
Пример #2
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 ")
    "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'))
    logging.info("End signature")
    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')

        logging.info("Wrapped dek: " + dek_encrypted)
        logging.info("End KMS encryption API call")
Пример #5
0
        ">>>>>>>>>>> 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,
                             key_id=args.recipient_key_id,
                             dek_wrapped=dek_wrapped)
Пример #6
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()