Posted: July 10, 2021 - Updated: April 10, 2024
В этой статье будут более практичные сценарии использования gpg. Предполагается, что у нас уже установлены набор утилит gnupg2
и сгенерирована пара личных ключей. Если нет, то все можно сделать быстро вот так, только подставить свои данные:
:
sudo apt install gnupg2
export GPG_TTY=$(tty)
gpg --batch --gen-key <<EOF
Key-Type: default
Key-Length: 4096
Subkey-Type: default
Subkey-Length: 4096
Name-Real: Artem Ivanov
Name-Email: wl07xo34yq@crepeau12.com
Expire-Date: 0
Passphrase: abc
EOF
Ну или прочитав детальную статью об этом и все настроив под свои потребности.
Типичный вызов утилиты выглядит так:
> gpg [опции] [входной файл]
Если входной файл опущен, на вход утилиты подается стандартный ввод. Среди множества опций есть группа опций, отвечающих за режим работыЧто и зачем Шифрование с помощью gpg бывает:
-c
(--symmetric
) - ассимметрическное (шифрование паролем. Вниманию критиков и параноиков: паролем шифруется не само сообщение, а сеансовый ключ симметрического шифрования, которым уже защищается сообщение-e
(--encrypt
) - асимметрическое шифрование публичным ключем получателя. Режим совместим с -c
и тогда сообщение можно будет расшифровать одним из способов. Вместе с этой опцией чаще всего указывают:
-r <recipient>
- получатель, чей ключ использовать-R <recipient>
- аналогичная команда с туется публичным ключом, расшифровывается приватным)-d
- расшифровка. Логично что это не совместимо с режимами -c
и -e
.-s
(--sign
) - создание подписи приватным ключем, которую можно будет проверить публичным. Этот режим можно использовать как самостоятельно, так и в комбинации с любым из шифрований. В том случае подпись будет добавлена в зашифрованное сообщеой)Еще шифрование можно совмещать с подписыванием файла. Еще зашифровать можно одним или более публичными ключами.
--verify
- проверка подписи, если такая накладна на файл. Работает как самостоятельная команда, так и с режимом расшифровки.Вообще опций очень много. Если вам нужно что-то сделать нестандартное, скорее всего для этого уже есть опция. Просто поверьте мне, ну или посмотрите на их список. Тем не менее есть некоторые из них, которыми прийдется пользоваться чаще всего:
-a
- по умолчанию ответ утилиты таки бинарный, но эта опция переупакует его в текстовом представлении(ascii-armored). Есть еще отдельно команда для упаковывания файла в PGP ASCII armor: gpg --enarmor < filename.bin > filename.txt
и соответственная обратная операция: gpg --dearmor < filename.txt > filename.bin
-o <outFileName>
(--output
) - записывает вывод в указанный файл вместо стандартного вывода, по сути команда эквивалент перенаправлении стандартного вывода, но не всегда, так как отладочные сообщения существуютля
Параметр один. Это имя файла, который нужно зашифровать/расшифровать. Но если этот аргумент опущен, то данные берутся из стандартного ввода. Пример команд с популярными опциями выглядит так:
> gpg -c -a --pinentry-mode loopback --passphrase mypassw file.txt
Аргументы:
--cipher-algo <algo>
- устанавливает алгоритм, который будет использован в данной команде. Список доступных можно узнать выполнив gpg --version
. разные алгоритмы для разных задач.
IDEA
, 3DES
, CAST5
, BLOWFISH
, AES
(он же AES128
), AES192
, AES256
, TWOFISH
, CAMELLIA128
, CAMELLIA192
и CAMELLIA256
RSA
, ELG
, DSA
, ECDH
, ECDSA
и EDDSA
- симметрическое шифрования:
SHA1,
RIPEMD160,
SHA256,
SHA384,
SHA512 и
SHA224`Uncompressed
, ZIP
, ZLIB
и BZIP2
--try-all-secrets
- если ты не знаешь чьим приватным ключем расшифровывать, оное-a
- ответ в текстовом переберет все наличныедставлении--pinentry-mode loopback
- включает режим упрощенного ввода паролей с консоли. К использованию этого режима нужно относиться с пониманием, так как тут удобство повышается за счет безопасности. С ответа в одной из рабочих групп по gpg: “loopback mode is a hack to bypass the standard way of asking for passphrases and to allow a simpler thing”. Без этого ключа по умолчанию используется ввод пароля с помощью библиотеки pinentry-curses, которая гарантирует что пароль нигде не будет сохранен. Дополнительные опции:
--passphrase <password>
- ввод пароля как аргумент--passphrase-file <password-file>
- ввод файла с паролем как аргументGpg позволяет шифровать файлы такими способами:
Gpg позволяет подписывать файлы, и соответственно верифицировать подпись на файлах. Еще шифрование можно совмещать с подписыванием файла. И еще зашифровать можно одним или более публичными ключами.
Это шифрование, когда сообщение шифруется и расшифровывается одним и тем же паролем. Простейший пример шифрования сообщения,
--passphrase <password>
- ввод пароля как аргумент--passphrase-file <password-file>
- ввод файла с паролем как аргументПри выполнении этой команды пароль будет запрошен в интерактивном режиме:
> echo "message" | gpg -c -a --cipher-algo AES
-----BEGIN PGP MESSAGE-----
jA0ECQMC+qVtCU87epf/0j0Bmp6SWatIOwGEUb5+u85P0ZzOjsMRjrxgqm8gnPhe
quv87PIs/iHsGpsGPOr1rY3LhnoYQO3ZjaBZdw/g
=DSZ/
-----END PGP MESSAGE-----
Для того чтоб задать пароль в виде аргументов, можно использовать --pinentry-mode loopback
и тогда опции --passphrase
и --passphrase-file
будут работать:
> > echo "message" | gpg -c -a --pinentry-mode loopback --passphrase password
-----BEGIN PGP MESSAGE-----
jA0ECQMClRzymhTUUp7/0j0BYRI63DEYYjh8R45k2+U0GJBh5Wr8BiKYUFAPxfHx
t+zqHuTMSE2AtJ3/zBL4+q7vE5dnBGoGvFMhjNIZ
=KE8q
-----END PGP MESSAGE-----
Для расшифровки сообщений выше можно воспользоваться этими командами:
read -r -d '' mess <<-EOF
-----BEGIN PGP MESSAGE-----
jA0ECQMClRzymhTUUp7/0j0BYRI63DEYYjh8R45k2+U0GJBh5Wr8BiKYUFAPxfHx
t+zqHuTMSE2AtJ3/zBL4+q7vE5dnBGoGvFMhjNIZ
=KE8q
-----END PGP MESSAGE-----
EOF
> echo "$mess" | gpg -d --pinentry-mode loopback --passphrase password
Вообще, данные можно подать на вход разными способами, например(пароль 123
):
cat <<DATA | gpg --decrypt
-----BEGIN PGP MESSAGE-----
jA0ECQMCeqYI5XWTG0f/0sALAXTTjLlpuZXLHZRtIKMwEN9XNKPkemq/yv91fCGP
LRnZIGzyJKZ1G+xRKbFxrhbqo3laW4p29DOcTgQmBAr3+0OtMk1+vhDUJcEo675O
nBUY4Z8nitI2+wzG6L/JWL1/NtVCGa6pFiWqgyBzAu2bCINMmoS24/bxGuANq1XW
KKq2YMx/oFA+6EWqih+XT5R3vocBMD2OX6HM4zKvaCEvsuwz2vziza13nQK4T6MY
7/rsxsEhJr+NgMV5YepLhNscwjkv5scpAsqYjI4=
=cCk/
-----END PGP MESSAGE-----
DATA
Еще вариант: подать их на вход в виде файла
# файл в бинарном представлении
gpg --decrypt doc.gpg
# если не работает потому что файл в текстовом представлении,
# можно сначала конвертировать текст в бинарные данные назад
gpg --dearmor -o- doc.gpg | gpg --decrypt
# где -o- это -o -, т.е. вывод в stdout ("--output -" тоже работает)
На самом деле ты не всегда знаешь какой алгоритм использовался. Но в самом сообщение об этом пишут и можно узнать не зная пароля(и не введя его, просто нажать “Cancel”):
> gpg -vv --show-session-key --list-packets encrypted_file.asc
.......
gpg: AES256 encrypted data
.......
или так:
> gpg --list-only -d encrypted_file.asc
gpg: AES256 encrypted data
gpg: encrypted with 1 passphrase
Это шифрование, когда сообщение шифруется публичным ключем получателя и расшифровать его может только получатель своим приватным ключем. За этот оежим отвечает -e
(--encrypt
) параметр, который часто идет в паре с -r <получатель>
(--recepient
)
Для эксперимента например скачаем и установим мой публичный ключ:
> curl -sSL https://k.co.ua/pubkey.pgp | gpg --import -
> gpg --sign-key 'Vasyl Khrystiuk' # подписать для себя мой ключ, чтоб повысить уровень доверия к нему
Пример команды:
echo message | gpg -e -a -r "Vasyl Khrystiuk"
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 1 trust: 0-, 0q, 0n, 0m, 0f, 1u
gpg: depth: 1 valid: 1 signed: 0 trust: 1-, 0q, 0n, 0m, 0f, 0u
-----BEGIN PGP MESSAGE-----
hQEMA0dEe+lKxwSUAQf9HRp67GwrylsyMZzrL1cAtb4dQSs9Q/aEPRxN396bP4C7
uym/AX53CqdIDJVgdY0Sd2b2M3IKDrr+2NslB1+aIpa+AWXD2XOhAnbvmxCdwwCL
6om96IheQ2L2cZ5euJ0GMHR+sLiLNy2VbET+hjxWRv6GYG74K5U+or4jD/QlD4nI
DQnd2i1D6b52TYlVdWKbirmQAQZti200Jea54c/j6VcaUh7uafpR8YDxLq9JoF4G
wuwVEbqZqWR2+JsssDoyM3Ab56kXHmsajp/Ee0oJywa8SLXpjHlGxMJI6OQeUZja
CWzWDQBa4Zz9mfQw5dWwi3vstWMBBQQLkT0RUgShsdJDAanzVxgtFu6QGMPZw4sR
f36E3h4MEg2K7d8iNvnp6wac2vC4leU5FLYL7/DAaUGh7QdMTqro00PzD6tkuhiT
7R5U3A==
=PS7o
-----END PGP MESSAGE-----
Для расшифровки используется все тот же -d
параметр с вводом пароля:
cat <<DATA | gpg --decrypt
> -----BEGIN PGP MESSAGE-----
>
> hQEMA0dEe+lKxwSUAQf9HRp67GwrylsyMZzrL1cAtb4dQSs9Q/aEPRxN396bP4C7
> uym/AX53CqdIDJVgdY0Sd2b2M3IKDrr+2NslB1+aIpa+AWXD2XOhAnbvmxCdwwCL
> 6om96IheQ2L2cZ5euJ0GMHR+sLiLNy2VbET+hjxWRv6GYG74K5U+or4jD/QlD4nI
> DQnd2i1D6b52TYlVdWKbirmQAQZti200Jea54c/j6VcaUh7uafpR8YDxLq9JoF4G
> wuwVEbqZqWR2+JsssDoyM3Ab56kXHmsajp/Ee0oJywa8SLXpjHlGxMJI6OQeUZja
> CWzWDQBa4Zz9mfQw5dWwi3vstWMBBQQLkT0RUgShsdJDAanzVxgtFu6QGMPZw4sR
> f36E3h4MEg2K7d8iNvnp6wac2vC4leU5FLYL7/DAaUGh7QdMTqro00PzD6tkuhiT
> 7R5U3A==
>
> -----END PGP MESSAGE-----
> DATA
gpg: encrypted with 2048-bit RSA key, ID 47447BE94AC70494, created 2021-03-17
"Vasyl Khrystiuk <h6.msangel@gmail.com>"
message
Для подписи файла используется приватный ключ. Так как приватный (секретный) ключ хранится (очевидно же) в секрете владельцем, то исходя из предположения, что никто кроме владельца не имеет доступ к приватному ключу, мы можем быть уверены, что файл, который подписан этим приватным ключом, исходит от этого определённого лица. Если файл как либо после подписи был изменён, то эта подпись перестаёт быть верной (валидной) для данного файла. Поэтому, проверка подписи позволяет гарантировать:
Для проверки подписи определённого лица у вас должен быть публичный ключ этого лица.
Соединение подписанной версии файла вместе с ключем в бинарном формате:
> gpg --sign speech.txt
# создаст speech.txt.gpg
Соединение подписи внутри файла в изначальном(чаще всего текстовом) формате:
> gpg --clear-sign speech.txt
# создаст speech.txt.asc
> cat speech.txt.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512
This is sample text I going to proove it is mine using signing.
-----BEGIN PGP SIGNATURE-----
iQEzBAEBCgAdFiEEULZwqN4fPNiVg4lSQcuY8zsGFG4FAmF0s4gACgkQQcuY8zsG
FG6pyAgAiIVG3Am3QIxrBgwYDlB44QyRr4yh62C6BcbqTZdG0ljzK8HyKs4qTFZz
Il67UpLfPvziI35WNcJMaoZwdVUT9BpRPGZTSH3yIk9KNHjEz2oh99PUwXBNGYMq
iXr+W2XL+ZjXk4fsk9DzADrFGR7NbQHz+1wyWNOJmtLN4LwDMk4o4RvuiSpwQdw0
SHDpefczD5rkC2Z0cD+BL6imHSa8pER4o79qOPiujxuKCtbJZGZf2qTMNJNV8l6S
PpDUoE7ycmlpmkOi1JnSBO/NfFiV2kA9FIhn4Tk9hyjEE8WWWQxEK2msKCDuKl5m
sS141HaDk7LmODcz8MzmpbEdpthXUQ==
=x2TL
-----END PGP SIGNATURE-----
Создание подписи для файла в виде отдельного файла подписи параметром -b
(--detach-sign
):
> gpg --sign -b speech.txt
# создаст speech.txt.sig
Этот вариант создания подписи используется чаще всего, так как большинству пользователей не интересна эта электронная подпись и они не хотят извлекать оригинальный файл из закодированного сообщения. Потому подпись и оригинальный файл разделены. Ну а если кто-то задастся целью проверить подпись, то это все еще будет доступно.
Если файл и подпись в одном файле, то проверить подпись можно так:
> gpg --verify speech.txt.asc
gpg: Signature made нд, 24-жов-2021 04:21:29 +0300 EEST
gpg: using RSA key 50B670A8DE1F3CD89583895241CB98F33B06146E
gpg: Good signature from "Vasyl Khrystiuk <h6.msangel@gmail.com>" [ultimate]
Если файл и подпись в отдельных файлах, то так:
> gpg --verify speech.txt.sig speech.txt
gpg: Signature made нд, 24-жов-2021 04:21:29 +0300 EEST
gpg: using RSA key 50B670A8DE1F3CD89583895241CB98F33B06146E
gpg: Good signature from "Vasyl Khrystiuk <h6.msangel@gmail.com>" [ultimate]
Извлечь оригинальный файл из подписанного все той же командой decode -d
(-o
используется чтоб не смешивать вывод верификации и контент файла):
> gpg -d -o original_speech.txt speech.txt.gpg
gpg: Signature made нд, 24-жов-2021 04:40:22 +0300 EEST
gpg: using RSA key 50B670A8DE1F3CD89583895241CB98F33B06146E
gpg: Good signature from "Vasyl Khrystiuk <h6.msangel@gmail.com>" [ultimate]
# будет воссоздан original_speech.txt из зашифрованного файла
С одной стороны, система публичных ключей гарантирует, что прочитать защищенное сообщение сможет только человек, который его сгенерировал публичный ключ вместе с соответствующим ему приватный. С другой стороны, вообще нет никакой гарантии, что тот ключ, который вы нашли в интернете, сгенерировал именно тот человек, чье имя на нем написано. Ничто не мешает мне назваться именем Линуса Торвальдса и отправить такой ключ на публичный сервер. Именно для того существует система доверия к публичным ключам. Работает она кстати довольно просто. У каждого локального публичного ключа есть один из соответственных ему уровней доверия:
Уровни доверия каждый пользователь определяет для себя. Можно как вручную установить этот атрибут ключа локально, так и подписать этот ключ своим, что сделает ключ доверенным для себя, а в случае публикации такого измененного ключа даст всем знать, что вот лично вы этому ключу доверяете. И потому люди, которые доверяют вам, частично(marginal) тоже будут доверять этому ключу. Такая вот незадачливая реализация сети доверия. Установка уровня доверия вручную:
gpg --edit-key 39499BDB
> trust
(5 = ultimate trust)
> save
Подписывание публичного ключа своим приватным:
> gpg --sign-key 'Vasyl Khrystiuk'
--export-secretsubkeys
gpg --gen-random 1 16 | gpg --enarmor | sed -n 4p
tar -cf - these files here | gpg -c > these-files-here.tgp
. Обратная операция: gpg < these-files-here.tgp | tar -xvf -
In the process: https://hackware.ru/?p=8215
Пример так(файл опускаем и вводим из консоли): gpg -armor -c –cipher-algo AES256 —–BEGIN PGP MESSAGE—–
jA0ECQMCeFG3G8AAfe3/0jwBz66lvQy4M4xBRAWz+dq4u3oB/KpddERVuwIJyniq rU+sz6ohLR7m1cihP6/y8TZhDpuh9ntLRe9iDnc= =OMF0 —–END PGP MESSAGE—–
чтоб расшифровать это, надо: для докера(надо же где-то проводить эксперименты): export GPG_TTY=$(tty) ну и само расшифрование:
cat «DATA | gpg –decrypt –allow-multiple-messages —–BEGIN PGP MESSAGE—–
jA0ECQMCeFG3G8AAfe3/0jwBz66lvQy4M4xBRAWz+dq4u3oB/KpddERVuwIJyniq rU+sz6ohLR7m1cihP6/y8TZhDpuh9ntLRe9iDnc= =OMF0 —–END PGP MESSAGE—– DATA Хорошие пароли можно сгенерировать на месте: gpg –gen-random 1 16 | gpg –enarmor | sed -n 5p или gpg –gen-random 1 32 | gpg –enarmor | sed -n 4p А узнать чем зашифровано вот так: https://superuser.com/questions/1538456/how-to-find-out-symmetric-encryption-algorithm-used-in-pgp-encryption-with-gpg
in progress: https://hackware.ru/?p=8215
Тут все просто - шифруем публичным ключем получателя, расшифровать сможет только он например (файл опущен, данные считываются с stdin): gpg –output doc.gpg –encrypt –recipient python273 <файл> или в ASCII: gpg --output doc.gpg --encrypt --armor --recipient "Vasyl Khrystiuk"файл>
Расшифровка документов: gpg –output doc –decrypt doc.gpg или из ASCII gpg –dearmor -o- doc.gpg | gpg –decrypt где -o- это -o -, т.е. вывод в stdout (“–output -“ тоже работает)
Т.е. конвертация с бинарного в ascii встроена. Можно и явно в несколько шагов: To wrap a file in PGP ASCII armor, type: $ gpg –enarmor < filename.bin > filename.txt To unwrap a file already in PGP ASCII armor, type: $ gpg –dearmor < filename.txt > filename.bin Можно создавать шифрованные архивы: tar -cf - these files here | gpg -c > these-files-here.tgp И разархивировать: gpg < these-files-here.tgp | tar -xvf -
Считать сигнатуру https://serverfault.com/questions/896228/how-to-verify-a-file-using-an-asc-signature-file Считать сигнатуру на примере https://s01.oss.sonatype.org/service/local/repo_groups/staging/content/ua/co/k/strftime4j/1.0.5/strftime4j-1.0.5-javadoc.jar.asc
Сначала публичный ключ подписавшего должен быть импортирован.
Протом просто проверяешь подпись, где параметры сначала подпись, потом файл. gpg –verify strftime4j-1.0.5-javadoc.jar.asc strftime4j-1.0.5-javadoc.jar
Подписывание работает вот так gpg –sign file # produces file.gpg gpg –clear-sign file # produces file.asc gpg –detach-sign file # produces file.sig
подпись упакована с докумендом Подписываем приватным ключем, верифицируем публичным. Команда очень проста: gpg –output doc.sig –sign doc (если не указать –output, то по умолчанию берется оригинальное имя файла и добавляется .gpg )
The document is compressed before being signed, and the output is in binary format. Декодировать и проверить сигнатуру, верификация: gpg –output doc –decrypt doc.sig
подпись добавлена к документу Подпись: gpg –clearsign doc Результат:
—–BEGIN PGP SIGNED MESSAGE—– Hash: SHA512
привіт —–BEGIN PGP SIGNATURE—–
iQEzBAEBCgAdFiEEV47yHNOagvp8kQ+4vI4poQ6+AJ4FAmBRczEACgkQvI4poQ6+ AJ5gCAf/Vr1eFfGpQY5rrwTmmpDQrZeJTXzX5E3RtfHxjQOxVN725vgSDnTV5Vm/ BEPKrECD/E/DCH75oezXwnogtzWB/I55Ki3hOzKiO1N2etg3mwXPx0PbJa5GSR+P jpkWAR0m7G1haQMixX7RgjKo/7lqInsbzYDmscSVAWfoGX1G1gQnxkQFLCS0jocq 8oSDYYBYiykAShmXMVirgjPeKhlgSwK6IUxuIB9oyzan0xJ3Eix9bypKjodZ+qs/ rddCQwnV31dfDRvHgVucpXMJ3rDSkH6jOuDr8qGfVfZCqTzNqpEd4J7HH09IQ26w AxvRk/OQ/d8ApMonx3YC8CjAzres6Q== =2FcN —–END PGP SIGNATURE—– Верификация: gpg –verify doc.asc gpg: Signature made ср, 17-бер-2021 05:16:49 +0200 EET gpg: using RSA key 578EF21CD39A82FA7C910FB8BC8E29A10EBE009E gpg: Good signature from “Vasyl Khrystiuk (nb7 1st gen) h6.msangel@gmail.com” [ultimate]
отдельно добавлена подпись: gpg –output doc.sig –detach-sig doc или gpg -a –output doc.sig –detach-sig doc
Верификация: gpg –verify doc.sig doc
--export-secretsubkeys
gpg --edit-key EB0069AC
> adduid
> uid <number>
> trust
(5 = ultimate trust)
> uid <number>
> primary
(для выбора основного идентификатора)
> save