def encrypt_queue_message(message, key_encryption_key, version):
    '''
    Encrypts the given plain text message using the given protocol version.
    Wraps the generated content-encryption-key using the user-provided key-encryption-key (kek).
    Returns a json-formatted string containing the encrypted message and the encryption metadata.

    :param object message:
        The plain text message to be encrypted.
    :param object key_encryption_key:
        The user-provided key-encryption-key. Must implement the following methods:
        wrap_key(key)--wraps the specified key using an algorithm of the user's choice.
        get_key_wrap_algorithm()--returns the algorithm used to wrap the specified symmetric key.
        get_kid()--returns a string key id for this key-encryption-key.
    :param str version: The client encryption version to use.
    :return: A json-formatted string containing the encrypted message and the encryption metadata.
    :rtype: str
    '''

    _validate_not_none('message', message)
    _validate_not_none('key_encryption_key', key_encryption_key)
    _validate_key_encryption_key_wrap(key_encryption_key)

    # Queue encoding functions all return unicode strings, and encryption should
    # operate on binary strings.
    message = message.encode('utf-8')

    if version == _ENCRYPTION_PROTOCOL_V1:
        # AES256 CBC uses 256 bit (32 byte) keys and always with 16 byte blocks
        content_encryption_key = os.urandom(32)
        initialization_vector = os.urandom(16)

        cipher = _generate_AES_CBC_cipher(content_encryption_key, initialization_vector)

        # PKCS7 with 16 byte blocks ensures compatibility with AES.
        padder = PKCS7(128).padder()
        padded_data = padder.update(message) + padder.finalize()

        # Encrypt the data.
        encryptor = cipher.encryptor()
        encrypted_data = encryptor.update(padded_data) + encryptor.finalize()

    elif version == _ENCRYPTION_PROTOCOL_V2:
        # AES256 GCM uses 256 bit (32 byte) keys and a 12 byte nonce.
        content_encryption_key = os.urandom(32)
        initialization_vector = None

        # The nonce MUST be different for each key
        nonce = os.urandom(12)
        aesgcm = AESGCM(content_encryption_key)

        # Returns ciphertext + tag
        ciphertext_with_tag = aesgcm.encrypt(nonce, message, None)
        encrypted_data = nonce + ciphertext_with_tag

    else:
        raise ValueError("Invalid encryption version specified.")

    # Build the dictionary structure.
    queue_message = {'EncryptedMessageContents': encode_base64(encrypted_data),
                     'EncryptionData': _generate_encryption_data_dict(key_encryption_key,
                                                                      content_encryption_key,
                                                                      initialization_vector,
                                                                      version)}

    return dumps(queue_message)

    Encrypts the given plain text message using the given protocol version.
    Wraps the generated content-encryption-key using the user-provided key-encryption-key (kek).
    Returns a json-formatted string containing the encrypted message and the encryption metadata.

    :param object message:
        The plain text message to be encrypted.
    :param object key_encryption_key:
        The user-provided key-encryption-key. Must implement the following methods:
        wrap_key(key)--wraps the specified key using an algorithm of the user's choice.
        get_key_wrap_algorithm()--returns the algorithm used to wrap the specified symmetric key.
        get_kid()--returns a string key id for this key-encryption-key.
    :param str version: The client encryption version to use.
    :return: A json-formatted string containing the encrypted message and the encryption metadata.
    :rtype: str
    
Solutions/CyberArkAudit/Data Connectors/.python_packages/lib/site-packages/azure/storage/blob/_encryption.py