Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python script for msg sender with AES-256-CBC #218

Closed
cfbsks opened this issue Oct 2, 2023 · 0 comments
Closed

Python script for msg sender with AES-256-CBC #218

cfbsks opened this issue Oct 2, 2023 · 0 comments

Comments

@cfbsks
Copy link

cfbsks commented Oct 2, 2023

"""
Bark Notification Script
------------------------

This script allows you to send encrypted notifications using the Bark API.

Usage:
1. Set up your configuration:
   - Set `DEVICE_KEY` to your Bark device key.
   - Set `encryption_key` to your chosen AES key. (Ensure it's secure and kept private.)

2. The `send_notification` function can be used to send notifications. It accepts the following keyword arguments:
   - `title`: The title of the notification.
   - `body`: The body content of the notification.
   - `level`: The urgency level of the notification.
   - `autoCopy`: Whether to automatically copy content.
   - `copy`: The copied content.
   - `sound`: The sound of the notification.
   - `icon`: The icon URL of the notification.
   - `group`: The group of the notification.
   - `isArchive`: Whether the notification is archived.
   - `url`: The URL to open upon clicking the notification.

3. By default, all parameters have `None` value. If you want to set any default values, update the respective constants at the top of the script.

4. Use the `main` function to test or send out notifications as required.

Example:
    send_notification(body='This is a custom message.')
    send_notification(body='Another message', sound='bell', group='new_group')

Note:
Always remember not to hard-code sensitive information like `DEVICE_KEY` and `encryption_key` directly in the script. Consider safer methods like environment variables or secure config files.

"""

import base64
import json
import logging
import random

import requests
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import algorithms, modes, Cipher
from cryptography.hazmat.primitives.ciphers.algorithms import AES

TIMEOUT_REQUEST_SEC = 10
MAX_RETRIES = 3
LOG_LEVEL = logging.WARNING

API_BASE = 'https://api.day.app'
DEVICE_KEY = "this is your device_key"

# Encryption key and IV (Initialization Vector)
encryption_key = '12345678901234567890123456789012'

# Set Default Values
TITLE = None
BODY = None
LEVEL = None
GROUP = None
AUTOCOPY = None
COPY = None
SOUND = None
ICON = None
URL = None
ISARCHIVE = None

# Set up logging
logging.basicConfig(filename='Bark.log', level=LOG_LEVEL,
                    format='%(asctime)s - %(levelname)s - %(message)s')


def encrypt_payload(payload: bytes, aes_key: bytes, aes_iv: bytes):
    """
    Encrypt the given payload using AES-256-CBC with PKCS7 padding.
    """

    # Add padding to the payload
    padder = padding.PKCS7(AES.block_size).padder()
    padded_data = padder.update(payload) + padder.finalize()

    # Create the cipher
    cipher = Cipher(algorithms.AES(aes_key), modes.CBC(aes_iv), backend=default_backend())

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

    # Return the Base64 encoded ciphertext
    return base64.b64encode(encrypted).decode()


def send_notification(**kwargs):
    defaults = {
        'title': TITLE,
        'body': BODY,
        'level': LEVEL,
        'autoCopy': AUTOCOPY,
        'copy': COPY,
        'sound': SOUND,
        'icon': ICON,
        'group': GROUP,
        'isArchive': ISARCHIVE,
        'url': URL
    }

    for key, value in defaults.items():
        defaults[key] = kwargs.get(key, value)
    # Remove keys with empty string values
    cleaned_data = {k: v for k, v in defaults.items() if v}

    for _ in range(MAX_RETRIES):
        try:
            url = API_BASE + "/" + DEVICE_KEY
            headers = {'Content-Type': 'application/x-www-form-urlencoded'}

            json_data = json.dumps(cleaned_data)

            encryption_iv = bytes(random.randint(32, 126) for _ in range(16))
            encrypted_payload = encrypt_payload(json_data.encode(), encryption_key.encode(), encryption_iv)

            payload = {
                'ciphertext': encrypted_payload,
                'iv': encryption_iv.decode()
            }
            response = requests.request("GET", url, headers=headers, data=payload, timeout=TIMEOUT_REQUEST_SEC)

            if response.status_code == 200:
                logging.info(f"Sending notification. Response: {response.text}")
                return
            else:
                logging.warning(
                    f"Retrying notification. Status code: {response.status_code}, Response: {response.text}")
        except requests.RequestException as e:
            logging.warning(f"Retrying due to requests exception: {e}")
        except Exception as e:
            logging.error(f"Error sending notification: {e}")

    logging.error(f"Failed to send notification after {MAX_RETRIES} attempts. Content: {cleaned_data.get('body', '')}")


def main():
    send_notification(body='This is a custom message.')
    send_notification(body='Another message', sound='bell', group='new_group')


if __name__ == '__main__':
    main()

@cfbsks cfbsks changed the title Python script for msg sender Python script for msg sender with AES-256-CBC Oct 2, 2023
@Finb Finb closed this as completed Mar 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants