Совсем недавно встала задача передать свой приватный ключ от 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/