Простое и надежное шифрование бэкапов через age
Немного очевидного
Бэкапы надо хранить (лучше - хранить во множестве копий, в том числе, обязательно, где-то снаружи) и их надо шифровать. С этим вроде как все согласны, но на самом деле - мало кто делает, значит, люди делятся на тех, кто еще не шифрует бэкапы (не смогли еще реалистично представить-ощутить возможные риски) и ответственных опытных людей (чьи дикпики видел весь Интернет).
Поэтому, если вы не хотите оказаться звездой следующего The Fappening - надо беречь свои архивы. А тем, кто не так красив как Kate Upton или Jennifer Lawrence тем должно быть особенно неловко от мысли, что они хранят свои архивы без шифрования!
Дисклеймер
Автор не криптограф, и даже не претендует на это звание. А тема шифрования - сложная, и без понимания легко сделать так, что на первый взгляд будет казаться безопасным (например, достаточно хорошо зашифрованым), но фактически будет почти открытым.
Кто не в курсе, рекомендую немного ознакомиться с ECB-пингвином.
Я однажды так влетел (к счастью, ошибку нашел сам). Выбрал режим склейки блоков ECB (они там разные есть ECB, CBC, CTR, GCM, XTS) - я логично решил, что криптостойкость может быть разная, но совсем уж фигни там не будет. И ошибся. Криптография и популярные стандартные крипто-инструменты позволяют выстрелить себе в ногу.
Тем не менее, я не сразу нашел хороший гайд по той задаче, которая мне нужна (уверен, они есть, но мне не попались), поэтому, пусть будет еще один.
Что такое age и можно ли доверять?
age (произносится удобно, по-русски, “аге”, с “г” как в “гиф”) это новый, популярный инструмент шифрования (17k звезд звезд на github). age использует связку алгоритмов ChaCha20 для симметричного шифрования с алгоритмом имитовставки (Message authentication code, MAC, если по нашему) Poly1305 (RFC7539) от D. J. Bernstein. Того самого, который изобрел ed25519, который вы (будем надеяться) использует в ssh ключах. Кстати, этот ed25519 используется так же и в wireguard и в age тоже.
Установить можно просто через apt install age
.
Автор - утилиты (можно ли ей доверять?) Filippo Valsorda работал в крипрографической команде Cloudflare, возглавляет Go security team в Google.
Просто используем!
Сначала - самое простое шифрование, просто паролем, для самых маленьких.
# encrypt
$ age -p -o paris.jpg.age paris.jpg
Enter passphrase (leave empty to autogenerate a secure one):
Confirm passphrase:
# decrypt
$ age -d -o paris-decrypted.jpg paris.jpg.age
Enter passphrase:
Этого уже достаточно, чтобы хранить файлы где-нибудь на яндекс.диске и не бояться, что Яндекс, взломщик или спецслужбы будут их читать.
Но давайте рассмотрим более интересный вариант, который уже не стыдно использовать в продакшне. Мы хотим шифровать бэкапы баз данных перед тем, как загружать их на S3. Тут возникает несколько сложностей:
- Мы не хотим хранить какие-то приватные или симметричные ключи на сервере.
- Расшифровать бэкапы должны мочь несколько человек в компании (“получатели”). Даже если один ушел из команды, кто-то другой должен мочь расшифровать бэкап.
- Мы не хотим использовать какой-то один “супер-ключ” и давать его всем. Как правило, такой ключ быстро утекает (через взломанные мессенджеры, переписки) и что самое плохое - мы даже не можем узнать, от кого он утек. Каждый получатель должен иметь возможность расшифровать своим индивидуальным ключом, который он нигде не светит.
Сначала, чуть-чуть теории, как это работает. Асимметричное шифрование не пригодно для шифрования больших объемов данных. Поэтому генерируется случайный ключ для шифрования, сам файл симметрично шифруется алгоритмом ChaCha20 с использованием этого ключа, а дальше в выходной файл несколько раз добавляется этот ключ, зашифрованный публичным ключом каждого из получателей.
Откуда взять ключи? Первый вариант - сгенерировать их: age-keygen -o key.txt
создаст пару публичных и приватных ed25519 ключей. Но… а зачем? В наше время у всех есть SSH ключ в формате ed25519 ну или на худой конец RSA. Не будем плодить ключи, их и будем использовать, age это умеет! Получателей к шифрованному файлу можно добавлять повторяя аргумент -r KEY
(публичный ключ прямо аргументом передаем), или -R file
- где в файле перечислены публичные ключи. Ваш ~/.ssh/id_ed25519.pub
вполне подходит. Но мы всех получателей запишем в один файл recipients.txt:
# john doe
ssh-ed25519 AAAA....
# my key
ssh-ed25519 AAAA....
Да, пустые строки и решетки - можно. и даже ~/.ssh/authorized_keys вполне подходит в качестве такого файла.
Ну и поехали:
$ age -o paris.jpg.age -R recipients.txt paris.jpg
Полученный paris.jpg.age файл можно свободно заливать в ваш любимый файлообменник, хоть в S3, хоть в дропбокс хоть в skype.
Если же мы вдруг решили восстановиться и хотим расшифровать:
$ age -d -o paris.jpg -i ~/.ssh/id_ed25519 paris.jpg.age
Как видите, все просто, а главное - тут нет лишних непонятных кнопочек и крутилочек, которые можно было бы неправильно нажать.
Почитать по теме и для холиваров age/pgp/openssl
Дискуссии на stackoverflow стоит читать с комментариями
- https://words.filippo.io/dispatches/age-authentication/
- https://latacora.micro.blog/2019/07/16/the-pgp-problem.html
- https://stackoverflow.com/questions/16056135/how-to-use-openssl-to-encrypt-decrypt-files
- https://stackoverflow.com/questions/28247821/openssl-vs-gpg-for-encrypting-off-site-backups
- https://habr.com/ru/articles/786302/