Шифруем свои файлы удалённо через телеграм. Python 3.8

Я уже давно перестал доверять Дурову и его детищу. Слишком много слухов и подозрений витает вокруг. Тем не менее, Телеграм остается удобной програмой для общения и непревзойденным по функционалу клиентом.

Давайте на очень простом примере попробуем улучшить нашу безопасность, а заодно и разберемся с шифрованием в Python.

Каждый человек, который пользуется компьютером или смартфоном, ежедневно сталкивается с криптографией: начиная от работы в интернете по протоколу HTTPS и заканчивая печально известными вирусами-шифровальщиками. Однако далеко не все понимают, как работает криптография. Давайте попробуем в этом разобраться на конкретном примере.

Википедия гласит:

Криптогра́фия (от др.-греч. κρυπτός — скрытый и γράφω — пишу) — наука о методах обеспечения конфиденциальности (невозможности прочтения информации посторонним), целостности данных (невозможности незаметного изменения информации), аутентификации (проверки подлинности авторства или иных свойств объекта), а также невозможности отказа от авторства.

Одним из разделов криптографии является наука о шифровании. В процессе шифрования происходит обратимое изменение информации с помощью некоего секрета, что делает информацию недоступной для тех, кто секретом не владеет. Базовые принципы шифрования мы и рассмотрим в этой статье.

Если вам не хочется разбираться в коде, вот ссылка на репозиторий с TeleCrypTOR:

https://github.com/f4rber/TeleCrypT0R

Теперь перейдем непосредственно к коду и его работе

Сегодня мы будем использовать модуль cryptography для создания ключа и шифрования файлов, pyTelegramBotApi для создания бота Cryptodome для RSA шифрования.

pip install pyTelegramBotAPI
pip install cryptography
pip install pycryptodome 
Если вы используете Windows, то pip install pucryptodomex

Создание ключа

Создаем файл GenerateKey.py и пишем туда следующее:

from cryptography.fernet import Fernet  # Импортируем библиотеку для генерации ключей

logo = r'''
▄ •▄ ▄▄▄ . ▄· ▄▌     ▄▄ • ▄▄▄ . ▐ ▄ ▄▄▄ .▄▄▄   ▄▄▄· ▄▄▄▄▄      ▄▄▄  
█▌▄▌▪▀▄.▀·▐█▪██▌    ▐█ ▀ ▪▀▄.▀·•█▌▐█▀▄.▀·▀▄ █·▐█ ▀█ •██  ▪     ▀▄ █·
▐▀▀▄·▐▀▀▪▄▐█▌▐█▪    ▄█ ▀█▄▐▀▀▪▄▐█▐▐▌▐▀▀▪▄▐▀▀▄ ▄█▀▀█  ▐█.▪ ▄█▀▄ ▐▀▀▄ 
▐█.█▌▐█▄▄▌ ▐█▀·.    ▐█▄▪▐█▐█▄▄▌██▐█▌▐█▄▄▌▐█•█▌▐█ ▪▐▌ ▐█▌·▐█▌.▐▌▐█•█▌
·▀  ▀ ▀▀▀   ▀ •     ·▀▀▀▀  ▀▀▀ ▀▀ █▪ ▀▀▀ .▀  ▀ ▀  ▀  ▀▀▀  ▀█▄▀▪.▀  ▀                                                                  
'''

print(logo)  # Выводим на экран логотип

Сделаем try/catch для того, что бы в случае возникновения ошибки, программа нам об этом сообщила:

try:
    key = Fernet.generate_key()  # Переменная с ключём

    file = open('key.key', 'wb')  # Открываем файл / Open file
    file.write(key)  # Записываем ключ в файл / Write key to the file
    file.close()  # Закрываем файл / Close the file

    # Если всё прошло успешно пишем что ключ сгенерирован
    # If everything is ok print message
    print("KEY GENERATED SUCCESSFULLY")

except Exception as ex:
    # Если что-то пошло не так пишем сообщение
    # If something goes wrong print message
    print("KEY WASN`T GENERATED SUCCESSFULLY\n" + str(ex))

except Exception as ex – создаем переменную в которой содержиться сообщение об ошибке (если она будет), в дальнейшем мы выводим его в print(“…” + str(ex)), str() нужен для конвертации ex в строку. Теперь нужно написать генератор ключей для AES шифрования:

try:
    key = RSA.generate(2048)  # Переменная с приватным ключём
    private_key = key.export_key()  # Экспортируем ключ
    file_out = open("private.pem", "wb")  # Название файла
    file_out.write(private_key)  # Записываем в файл
    print("private_key generated")

    public_key = key.publickey().export_key()  # Переменная с публичным ключём
    file_out = open("receiver.pem", "wb")  # Название файла
    file_out.write(public_key)  # Записываем в файл
    print("public_key generated")
except Exception as ex:
    print("KEY WASN`T GENERATED SUCCESSFULLY\n" + str(ex))

Приватный ключ нужно сохранить на флешку! Им мы будем расшифровывать файлы, такая “система” надежнее чем первый вариант в разы.

Теперь запускаем наш файл:

python3 GenerateKey.py

Если вы увидели строку KEY GENERATED SUCCESSFULLY, значит файл с ключём сгенерировался и теперь вам нужно скопировать его на флешку или же отдать доверенному лицу, что бы в дальнейшем расшифровать файлы.

Создание Телеграм бота

Прежде чем начинать разработку, бота необходимо зарегистрировать и получить его уникальный id, являющийся одновременно и токеном. Для этого в Telegram существует специальный бот — @BotFather.

Пишем ему /start и получаем список всех его команд.

Первая и главная — /newbot — отправляем ему и бот просит придумать имя нашему новому боту. Единственное ограничение на имя — оно должно оканчиваться на «bot». В случае успеха BotFather возвращает токен бота и ссылку для быстрого добавления бота в контакты, иначе придется поломать голову над именем.

Для начала работы этого уже достаточно. Особо педантичные могут уже здесь присвоить боту аватар, описание и приветственное сообщение.

Начинаем разработку

Импортируем библиотеки:

# Для АЕS шифрования
from Cryptodome.PublicKey import RSA
from Cryptodome.Random import get_random_bytes
from Cryptodome.Cipher import AES, PKCS1_OAEP
# Для удаления файлов, списка файлов, перезапуска/выключения компьютера
from os import path, remove, listdir, system
# Для создания бота
import telebot
# Для шифрования файла первым способом
from cryptography.fernet import Fernet

Время создать переменные в которых будет содержаться название файла и ключ(удалиться после зашифровки файла, так что код можно назвать “последним шансом”):

input_file = ''   # Файл для шифрования. Лучше всего использовать zip или rar, что бы зашифровать не 1 файл, а архив файлов
output_file = 'file.encrypted'  # Файл который мы получаем на выходе

key_file = open('key.key', 'rb')  # Открываем файл с ключём для чтения
key = key_file.read()  # Читаем содержимое файла с ключём
key_file.close()  # Зыкрываем файл с ключём

bot_token = "your_token"  # Токен бота, получаем у @BotFather
chat_id = "Your_id"  # Наш айди, получаем у @userinfobot
bot = telebot.TeleBot(bot_token)

bot.send_message(chat_id, "Bot started successfully!")# Бот отправит сообщение, "Bot started successfully!"

Приступим к написанию команд

Крепить команды к боту будем через @bot.message_handler.

/start

# /start
@bot.message_handler(commands=['start', 'Start'])  # Указываем с чего должна начинаться команда 
def start(message):
    bot.send_message(chat_id, "Telegram CrypT0R by F4RB3R" + "\n\nUse /help to see commands") 

Если мы напишем боту /start, он отправит нам сообщение:

Telegram CrypT0R by F4RB3R

/help to see commands

/help

# Initiate command /help
@bot.message_handler(commands=['help', 'commands', 'Help', 'Commands'])
def send_help(message):
    help_info = r'''
------------------------------
<Welcome to Help>
------------------------------
Bot Commands:
[01] Start
[ /] /start
[02] Help.
[ /] /help
[03] Encrypting one file.
[ /] /encryptone
[03] Encrypting all data.
[ /] /encryptall
[04] Shutdown PC.
[ /] /shutdown
[05] Restart PC.
[ /] /restart
------------------------------
<Created by F4RB3R>
------------------------------
'''
    bot.send_message(chat_id, help_info)

/restart и /shutdown

# Initiate command /shutdown
@bot.message_handler(commands=["shutdown", "/shutdown", "/Shutdown"])
def shutdown(self):
    bot.send_message(chat_id, "Shutdown Successfully!")
    system("shutdown /s /t 1")  # Выключение компьютера (/s обозначает выключение, /t время до действия)


# Initiate command /restart
@bot.message_handler(commands=["restart", "/restart", "/Restart"])
def restart(self):
    bot.send_message(chat_id, "Restart Successfully!")
    system("shutdown /r /t 1")  # Перезагрузка компьютера (/r обозначает перезапуск, /t время до действия)

/encryptone

# /encryptone - шифрует один файл, путь к файлу мы указывали выше
@bot.message_handler(commands=["encryptone", "/encryptone"])
def encrypt(self):
    try:
        with open(input_file, 'rb') as f:
            data = f.read()  # Читаем исходный файл 

        fernet = Fernet(key)  # Переменная с ключём для шифрования 
        encrypted = fernet.encrypt(data)  # Зашифровываем файл 

        with open(output_file, 'wb') as f:
            f.write(encrypted)  # Записываем информацию в зашифрованный файл
        remove(input_file)  # Удаляем исходный файл 
        remove("key.key")  # Удаляем файл с ключём 
    except Exception as ex:  # Бот отправит нам сообщение с ошибкой (если она будет)
        bot.send_message(chat_id, "Something went wrong!\n" + str(ex))

Теперь самое интересное, зашифровывание всех файлов в папке: /encryptall

# /encryptall
@bot.message_handler(commands=["encryptgall", "/encryptall"])
def encrypt(self):
  try:
        def crypt(file):
            f = open(file, "rb")
            data = f.read()
            f.close()

            file_out = open(str(file) + ".bin", "wb")

            recipient_key = RSA.import_key(open('receiver.pem').read())
            session_key = get_random_bytes(16)

            cipher_rsa = PKCS1_OAEP.new(recipient_key)
            enc_session_key = cipher_rsa.encrypt(session_key)

            cipher_aes = AES.new(session_key, AES.MODE_EAX)
            ciphertext, tag = cipher_aes.encrypt_and_digest(data)

            

[file_out.write(x) for x in (enc_session_key, cipher_aes.nonce, tag, ciphertext)]

print(file + ” Encoded”) remove(file) def walk(dir): for name in listdir(dir): path_to_file = path.join(dir, name) if path.isfile(path_to_file): crypt(path_to_file) else: walk(path) walk(“C:/Users/User/Desktop/Python_Projects/CrypT0R/aa/”) # Функция смотрит папку аа и шифрует все файлы которые там найдет, вы должны будете указать путь к своей директории, думаю это не нужно объянсять. bot.send_message(chat_id, “Successfully encrypted”) except Exception as ex: # Бот отправит нам сообщение с ошибкой bot.send_message(chat_id, “Something went wrong!\n” + str(ex))

Поскольку мы хотим иметь возможность шифровать произвольный объем данных, мы используем гибридную схему шифрования. Мы используем RSA с PKCS # 1 OAEP для асимметричного шифрования сеансового ключа AES. Затем ключ сеанса может быть использован для шифрования всех фактических данных.

Функция walk(dir) будет “ходить” по указанной папке и смотреть есть ли там файлы, так же, она будет просматривать и другие папки в указанном пути.

В самом конце программы мы добавляем:

bot.polling()

Теперь настало время для дешифрования

Для первого алгоритма:

from cryptography.fernet import Fernet
key_file = open('key.key', 'rb')  # Открываем файл с ключём для чтения 
key = key_file.read()  # Читаем содержимое файла с ключём
key_file.close()  # Зыкрываем файл с ключём
input_file = 'test.encrypted'  # Входной файл
output_file = 'test.txt'  # Дешифрованный файл

with open(input_file, 'rb') as f:
    data = f.read()  # Читаем входной файл

fernet = Fernet(key)  # Переменная с ключём для шифрования

encrypted = fernet.decrypt(data)  # Функция для дешифрования

with open(output_file, 'wb') as f:
    f.write(encrypted)  # Записываем дешифрованный файл

# input_file так же останется после всех манипуляций

Для второго алгоритма:

Вам нужен будет private_key который мы генерировали в начале.

from Cryptodome.PublicKey import RSA
from Cryptodome.Random import get_random_bytes
from Cryptodome.Cipher import AES, PKCS1_OAEP
import os


def decrypt(file):
    file_in = open(file, "rb")
    file_out = open(str(file[:-4]), "wb")
    private_key = RSA.import_key(open("private.pem").read())

    enc_session_key, nonce, tag, ciphertext = \
    

[file_in.read(x) for x in (private_key.size_in_bytes(), 16, 16, -1)]

# Decrypt the session key with the private RSA key cipher_rsa = PKCS1_OAEP.new(private_key) session_key = cipher_rsa.decrypt(enc_session_key) # Decrypt the data with the AES session key cipher_aes = AES.new(session_key, AES.MODE_EAX, nonce) data = cipher_aes.decrypt_and_verify(ciphertext, tag) file_out.write(data) print(data.decode(“utf-8″) + file + ” DECODED”) def walk(dir): for name in os.listdir(dir): path = os.path.join(dir, name) if os.path.isfile(path): decrypt(path) else: walk(path) walk(“your directory”) # Папка с вашими зашифрованными файлами

На последок немного сриншотов:

Подведем Итоги

В данной статье мы изрядно прошлись по поверхности вопроса : «Как, и что делать с пакетами PyCryptodome и cryptography?». Мы рассмотрели всего пару вариантов применения данных пакетов в шифровании и расшифровке файлов. Убедитесь в том, что уделите время документации, перед тем как начать экспериментировать с изложенной в данной статье информацией.

Вас ебали, ебут и будут ебать. Государство, хакеры, чиновники.

Остановить эту свингер-пати невозможно. Но я научу предохраняться. Я покажу и расскажу вам то о чём не пишет журнал “Хакер” и не рассказывают или просто не знают другие каналы. Здесь ты найдешь подборку лучших статей и видеоматериалов на тему кибербезопасности. Все, от аудита Wi-Fi до вскрытия автомобилей (если вы потеряли ключи). А также горячие новости с авторскими коментариями.

Обо всем этом вам расскажу только я на канале @cybersecs