Шифрование на Python.

Совсем недавно встала задача передать свой приватный ключ от ssh на другой компьютер, а возможно даже и положить его в приватный git репозиторий. Как быть? Есть несколько вариантов, например, использовать ansible vault, если никогда не слышали об этом почитайте. Полезно. В том числе и для шифрования файлов самого ansible. Но что по мне, так это немного не стойко. ) По этому далее переходим к openssl отличный инструмент, стар как мир, полно алгоритмов и установлен практически везде. По этому рассмотрю этот вариант в качестве командных строчек, которые при желании можно обернуть в bash скрипт например.

Нужно зашифровать файл. Хорошо, идем на официальный сайт, читаем документацию и приходим к следующему:

Зашифровать файл:
# openssl aes-256-cbc -salt -pbkdf2 -in мой_файл.txt -out мой_файл.txt.aes

Расшифровать файл:
# openssl aes-256-cbc -d -salt -pbkdf2 -in  мой_файл.txt.aes -out мой_файл.txt

Почему именно так, не скажем с помощью ключа? Потому что курица рождает яйцо или наоборот? Если мы создадим ключ которым будем шифровать и дешифровать как его передать? Его тоже надо шифровать? По этому в данном случае шифрование происходит с помощью парольной фразы. Пароль проще перенести в голове чем ключ. Но, мне было лень оборачивать это в bash скрипт, по этому в дело вступил мой любимый python. Покопавшись на просторах интернета нашел неплохую и легкую библиотеку: https://pypi.org/project/pyAesCrypt/ в целом все прекрасно описано в документации, по этому остается только написать логику для входного файла. То есть мы берем нашу программу, в качестве первого аргумента подставляем нешифрованный файл и на выходе получаем шифрованный. Для работы не забудьте установить библиотеку.

# pip install pyAesCrypt

Далее привожу листинг программы:

#!/usr/bin/python3.8

import pyAesCrypt
import getpass
import sys
import os

def get_password():
    aes_password_first = getpass.getpass("Enter password: ")
    aes_password_second = getpass.getpass("Enter password again: ")

    if aes_password_first == aes_password_second:
        return aes_password_second
    else:
        print("The entered password does not match, please try again...")
        exit(1)


get_file_name = ""

if len(sys.argv) > 1:
    print("The file you have chosen: " + sys.argv[1])
    get_file_name = sys.argv[1]
    if not os.path.exists(sys.argv[1]):
        print("The file does not exist or the path entered is incorrect.")
        exit(1)
else:
    print("No file selected. Select a file.")
    exit(1)

file_options = input("Enter E/D for encrypt or decrypt file: ")

if file_options == "E":
    print("The file: " + get_file_name + " will be encrypted.")
    try:
        pyAesCrypt.encryptFile(get_file_name, get_file_name + ".aes", get_password())
    except ValueError as encrypting_error:
        print("An error occurred while encrypting the file.")
        print(encrypting_error)
        exit(1)
    else:
        print("File encrypted successfully.")
elif file_options == "D":
    print("The file: " + get_file_name + " will be decrypted.")
    try:
        pyAesCrypt.decryptFile(get_file_name, get_file_name.replace('.aes', ''), get_password())
    except ValueError as decrypt_error:
        print("An error occurred while decrypting the file.")
        print(decrypt_error)
        exit(1)
    else:
        print("File decrypted successfully.")
else:
    print("You entered incorrect values, please try 'E' for encrypt, or 'D' for decrypt.")

Можно запускать и пробовать:

# ./cryptographer.py yakunin.vpn.ovpn 
The file you have chosen: yakunin.vpn.ovpn
Enter E/D for encrypt or decrypt file: E
The file: yakunin.vpn.ovpn will be encrypted.
Enter password: 
Enter password again: 
File encrypted successfully.

# ls

cryptographer.py
yakunin.vpn.ovpn
yakunin.vpn.ovpn.aes

# ./cryptographer.py yakunin.vpn.ovpn.aes 
The file you have chosen: yakunin.vpn.ovpn.aes
Enter E/D for encrypt or decrypt file: D
The file: yakunin.vpn.ovpn.aes will be decrypted.
Enter password: 
Enter password again: 
File decrypted successfully.

Вот собственно и все, можно спокойно передать файл через любой источник не боясь его компрометации. В заключение ссылочка на мой репозиторий: https://git.yakunin.dev/yakunin/python/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *