- Вопрос или проблема
- Вам может потребоваться добавить опцию --batch:
- Также, если вы используете ключевую пару получателя, вам, возможно, придется добавить --pinentry-mode loopback.
- Полный пример файла ключа получателя:
- Сначала создайте временную среду
- Получить ID ключа
- Шифрование
- Дешифрование
- Просто нужно добавить некоторые флаги
- Ответ или решение
- Основная проблема: запрос пароля
- Решения проблемы
- Заключение
Вопрос или проблема
Я ожидаю, что следующая команда извлечет файл gpg без запроса пароля:
gpg --passphrase 1234 file.gpg
Но он запрашивает пароль. Почему?
Эта команда также ведет себя так же:
gpg --passphrase-file passfile.txt file.gpg
Я использую Ubuntu с Gnome 3 и помню, что это работало в Fedora.
Я нахожусь в той же ситуации (это работало в Fedora, но не в Ubuntu). Вот очевидное решение, которое я обнаружил:
echo your_password | gpg --batch --yes --passphrase-fd 0 your_file.gpg
Объяснение: Передача 0
заставляет --passphrase-fd
считывать из STDIN, а не из файла. Таким образом, передача пароля позволяет --passphrase-fd
принять указанную вами строку пароля.
Обновлено 2017-12-04. (Добавление –batch для предотвращения запроса пароля)
Вам может потребоваться добавить опцию --batch
:
Также, если вы используете ключевую пару получателя, вам, возможно, придется добавить --pinentry-mode loopback
.
С версии 2 GPG
опция --batch
необходима для предотвращения запроса…
Ладно, посмотрим на это:
$ gpg --version
gpg (GnuPG) 2.1.18
libgcrypt 1.7.6-beta
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or позже <https://gnu.org/licenses/gpl.html>
Это бесплатное программное обеспечение: вы можете изменять и перераспределять его.
Гарантий НЕТ, в той мере, в какой это разрешено законом.
Домашний каталог: /home/user/.gnupg
Поддерживаемые алгоритмы:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Шифр: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Хеш: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Сжатие: Непосредственное, ZIP, ZLIB, BZIP2
Попробуем:
$ newdir=$(mktemp -d)
$ cd $newdir
$ seq 1 10 | gpg -c --batch --passphrase 1234 -o file.gpg -
$ ls -ltr
total 4
-rw-r--r-- 1 user user 91 Dec 4 15:42 file.gpg
$ hd file.gpg
00000000 8c 0d 04 07 03 02 ea fa d0 d3 2b 9a ea 06 df d2 |..........+.....|
00000010 4a 01 ed 50 74 ff 27 45 0e 6c 94 74 db e9 8a a5 |J..Pt.'E.l.t....|
00000020 03 9f 67 a0 73 97 e9 15 6b 56 a0 f0 88 71 85 a8 |..g.s...kV...q..|
00000030 dc 41 71 9f fa 3b f9 9d af ac 80 eb f4 f7 28 19 |.Aq..;........(.|
00000040 9f be 75 47 e6 d8 00 3e f6 60 f1 00 5e 63 57 ef |..uG...>.`..^cW.|
00000050 14 c3 4b 20 ff 94 03 03 c1 fc 98 |..K .......|
0000005b
здорово! Итак:
$ gpg -d --batch --passphrase 1234 file.gpg
gpg: AES encrypted data
gpg: encrypted with 1 passphrase
1
2
3
4
5
6
7
8
9
10
Если не указан параметр -d
(та же синтаксис, что и в вопросе SO), расшифрованные данные из file.gpg
будут извлечены в новый file
:
$ gpg --batch --passphrase 1234 file.gpg
gpg: WARNING: no command supplied. Trying to guess what you mean ...
gpg: AES encrypted data
gpg: encrypted with 1 passphrase
$ ls -ltr
total 8
-rw-r--r-- 1 user user 91 Dec 4 15:42 file.gpg
-rw-r--r-- 1 user user 21 Dec 4 15:44 file
$ cat file
1
2
3
4
5
6
7
8
9
10
Это работает хорошо!
$ cd -
$ rm -fR $newdir
$ unset newdir
Полный пример файла ключа получателя:
Сначала создайте временную среду
newdir=$(mktemp -d)
cd $newdir
export GNUPGHOME=$newdir
echo YourPassword >password.txt
gpgconf --kill gpg-agent # Требуется, если agent_genkey не удалось...
gpg --generate-key --batch <<eoGpgConf
%echo Started!
Key-Type: default
Key-Length: default
Subkey-Type: default
Name-Real: Полное Имя Тут
Name-Comment: Что-то смешное
Name-Email: [email protected]
Expire-Date: 0
Passphrase: $(<password.txt)
%commit
%echo Done.
eoGpgConf
gpg: keybox '/tmp/tmp.xU5Ldyr4iB/pubring.kbx' created
gpg: Started!
gpg: agent_genkey failed: No such file or directory
gpg: key generation failed: No such file or directory
gpg: Done.
Хмм.
gpgconf --kill gpg-agent
gpg --generate-key --batch <<eoGpgConf
%echo Started!
...
eoGpgConf
gpg: Started!
gpg: key 43E6B96CAFABDEDF marked as ultimately trusted
gpg: directory '/tmp/tmp.xU5Ldyr4iB/openpgp-revocs.d' created
gpg: revocation certificate stored as '/tmp/tmp.xU5Ldyr4iB/openpgp-revocs.d/DF223E1612CF917DC3BD42AA43E6B96CAFABDEDF.rev'
gpg: Done.
Получить ID ключа
Теперь
gpg -k
/tmp/tmp.xU5Ldyr4iB/pubring.kbx
-------------------------------
pub rsa3072 2020-06-19 [SC]
DF223E1612CF917DC3BD42AA43E6B96CAFABDEDF
uid [ultimate] Полное Имя Тут (Что-то смешное) <[email protected]>
sub rsa3072 2020-06-19 [E]
( Последние 8 символов из отпечатка публикации могут использоваться как псевдоним ключа. )
gpg -k [email protected]| sed -e '/^pub/{N;s/.*\(.\{16\}\)/\1/;p;s/^.\{8\}//;q};d'
43E6B96CAFABDEDF
AFABDEDF
Или даже восстановление в bash переменную, используя --with-colons
.
while IFS=: read -r typeOfRec _ _ _ keyId _; do
case $typeOfRec in pub ) break ;; esac
done < <(gpg --with-colons -k [email protected] )
declare -p keyId
declare -- keyId="43E6B96CAFABDEDF"
Шифрование
Хорошо, теперь!
seq -f "%'8g" 990 5 1015 |
gpg --batch --armor --recipient "$keyId" --encrypt --output file.gpg
Даст что-то вроде:
cat file.gpg
-----BEGIN PGP MESSAGE-----
hQEOA5BNpEVKPGsfEAP/XutJp7ME3I1MqG0vZyIS8w+npPQMPicIpQUwM4OVO1rX
2lhrymp0zGqxAH7s9Dh9YJNRA/9zYCO4/vghtnnl/zg10vILs9btgLXY+aupgoQ9
nifnVC8JJ1DC+hZZrIHyzS73BsjufWhpbwURYc7EgIMGKu2TRiy5I8+0aZ4zAtID
/ApL0sTBQ9hqmIatzaYbX9ajmDf1vvtE2/s3MUFA/hIqew2MVMhlb4RjyT7ix03P
LmCH2Mfy88VGr59eSUoZq+CPMDSZpXxbE2LfyPHYsObraO+a6FdVHhj2xcw/tnDO
TcNHTKnTRJSb9sfLAtJmE9eaxebkl27T+UvqyJUG4dgu0lABadboNaEidlrCYLNi
icR19UX0G7E50+i3iKvw0u81YtciYyOnpHvgazb5QbqJNN5P8izC4J3FqW7HaTDI
xnf+8IaX2Vqrq5+k4qLR7h5Vcw==
=1fb5
-----END PGP MESSAGE-----
Примечание: Начиная с версии >=2.2
gpg``--batch
больше не требуется:
seq -f "%'8g" 990 5 1015 |
gpg -aer "$keyId" >file.gpg
Сделает почти тот же эффект.
Дешифрование
Затем
gpg --decrypt --pinentry-mode loopback --passphrase-file password.txt --batch file.gpg
или
gpg -d --pinentry-mode loopback --passphrase-file password.txt --batch file.gpg
даст:
gpg: encrypted with 3072-bit RSA key, ID 58020687E0746339, created 2020-06-19
"Полное Имя Тут (Что-то смешное) <[email protected]>"
990
995
1'000
1'005
1'010
1'015
Но, начиная с версии >=2.2
gpg
, вы можете использовать:
gpg -qd --passphrase "$(<password.txt)" file.gpg
990
995
1'000
1'005
1'010
1'015
Для версии gpg 2.x вам не нужно использовать --batch
, просто
--pinentry-mode loopback
работает с --passphrase
и --passphrase-file
, и позволит вам вводить новую информацию, в случае конфликтов имен файлов, например:
gpg --pinentry-mode loopback --passphrase-file=file encrypted.gpg
...
Файл 'encrypted' существует. Перезаписать? (y/N)n
Введите новое имя файла: f2
в отличие от --batch
, который быстро выдаст ошибку, заявляя ...failed: File exists
(тестировалось на gpg 2.1.18 Debian Stable/Stretch. Это поведение игнорирования важных опций --passphrase
действительно следует считать багом, если это еще не так)
Похоже, вы используете gpg2. Вам также нужно добавить опцию --batch
. (Если вы планируете добавить это в скрипт, вам также нужно будет добавить --no-tty
и, вероятно, --yes
.)
Если использовать gpg (GnuPG) 2.2.7
Согласно странице man,
–passphrase-fd n
Считывать пароль из дескриптора файла n. Будет считана только первая строка из дескриптора файла n. Если вы используете 0 для n, пароль будет считан из STDIN. Это можно использовать только если предоставлен только один пароль.
–passphrase-file file
Считывать пароль из файла file. Будет считана только первая строка из файла file. Это можно использовать только если предоставлен только один пароль. Очевидно, что пароль, сохраненный в файле, представляет собой сомнительную безопасность, если другие пользователи могут прочитать этот файл. Не используйте эту опцию, если можно ее избежать.
–passphrase string
Использовать строку в качестве пароля. Это можно использовать только если предоставлен только один пароль. Очевидно, что это очень сомнительная безопасность в многопользовательской системе. Не используйте эту опцию, если можно ее избежать.
добавьте --pinentry-mode loopback
, чтобы это работало
Обратите внимание, что начиная с версии 2.0 этот пароль используется только в том случае, если также была указана опция –batch. Начиная с версии 2.1, режим –pinentry также необходимо установить на loopback.
Например:
gpg --batch --yes --passphrase="pw" --pinentry-mode loopback -o out -d in
для меня добавление “–no-use-agent” решило эту проблему для “gpg (GnuPG) 1.4.16”:
date > foo
echo pass > passphrase
# без --no-use-agent
> rm -f foo.gpg; gpg --cipher-algo aes256 --output foo.gpg --passphrase-file ./passphrase --batch --yes --symmetric foo
gpg: gpg-agent is not available in this session
gpg: can't query passphrase in batch mode
gpg: error creating passphrase: invalid passphrase
gpg: symmetric encryption of `foo' failed: invalid passphrase
> rm -f foo.gpg; gpg --cipher-algo aes256 --output foo.gpg --passphrase-file ./passphrase --batch --yes --no-use-agent --symmetric foo
> ls -al
total 20
drwxr-xr-x 2 root root 4096 Aug 22 13:59 .
drwx------ 18 root root 4096 Aug 22 13:58 ..
-rw-r--r-- 1 root root 30 Aug 22 13:58 foo
-rw-r--r-- 1 root root 103 Aug 22 13:59 foo.gpg
-rw-r--r-- 1 root root 5 Aug 22 13:58 passphrase
read -sp "Введите пароль: " pass
echo "${pass}" | gpg --batch --no-tty --yes --passphrase-fd 0 --symmetric -o /path/to/saved/file.jpg.gpg /path/to/file.jpg
echo "${pass}" | gpg --batch --no-tty --yes --passphrase-fd 0 --decrypt -o /path/to/decrypted/file.jpg /path/to/encrypted/file.jpg.gpg
Это сработало как по волшебству для меня:
echo "YOUR_PASS_PHRASE" | gpg --batch --yes --passphrase-fd 0 /home/somewhere/your_file.pgp
вы пробовали сделать:
gpg --batch --passphrase-fd 0 --decrypt-files *.gpg
gpg --passphrase-fd 0 1234 file.gpg
Источник: Здесь
Как упоминалось в man gpg, можно использовать следующую опцию
–pinentry-mode mode
Установить режим pinentry на mode. Допустимые значения для mode:
default
Использовать значение по умолчанию для агента, которое запрашивает.
ask Принудить использовать Pinentry.
cancel Эмулировать использование кнопки отмены Pinentry.
error Вернуть ошибку Pinentry (``No Pinentry'').
loopback
Перенаправить запросы Pinentry к вызывающему. Обратите внимание, что в отличие от Pinentry пользователь не будет запрашиваться повторно, если он введет неправильный пароль.
Таким образом, поведение gpg по умолчанию заключается в том, что оно запрашивает у пользователя пароль, если изменить этот режим пользовательского агента на ” –pinentry-mode loopback “, это работает совершенно нормально. Полная команда
gpg --pinentry-mode loopback --passphrase <пароль> -d <файл для расшифровки>
Я думаю, что довольно безопасный метод передать пароль в командной строке — это:
gpg --passphrase-file <(echo password) --batch --output outfile -c file
Что это сделает, так это создаст команду “echo” и передаст дескриптор файла в качестве имени пути в gpg (например, /dev/fd/63). Затем gpg будет считывать ключ оттуда. Тем временем команда echo должна работать параллельно и закончится мгновенно, оставив ключ в буфере дескриптора файла.
Преимущества:
- Команда gpg не будет иметь пароль в своей командной строке
- Команда echo будет недолговечной. Фактически, она должна завершиться почти мгновенно
- Пароль никогда не будет находиться на диске, не будет файла, который нужно будет удалить, и если команда будет прервана, не останется остатков
Это работает на Ubuntu 20.04 и может быть использовано в скриптах bash
echo "password" | gpg -c --pinentry-mode loopback --passphrase-fd 0 ./file_to_encrypt
и дает в выводе
./file_to_encrypt.gpg
Тестировалось с использованием gpg (GnuPG) 2.2.19 и libgcrypt 1.8.5
Вы не поверите мне, когда я скажу, что на ubuntu gpg пытается спросить у вас пароль, если $DISPLAY установлен, и берет его из командной строки –password, если вы его снимете.
Это работает как ожидалось:
DISPLAY= gpg --symmetric --passphrase pass --batch
Просто еще один пример избыточного проектирования, как я полагаю.
Вот ссылка на ответ stackoverflow, который, возможно, будет полезен; у меня есть проект, который занимается массовым дешифрованием/шифрованием, и из-за того, что GnuPG очень строг в отношении паролей, я трудным путем узнал, что --passphrase
работает только в редких случаях. Вместо этого рассмотрите использование опции --passphrase-fd
как более надежной.
Этот скрипт делает правильное использование опции --passphrase -fd
, и был публично протестирован через Travis-CI, где вы можете найти логи его работы.
Теперь я не собираюсь просто публиковать ссылки на ответ, не предоставив некоторый пример кода, так что вот обновленный “самостоятельный” скрипт, с которым вы можете поиграть:
#!/usr/bin/env bash
# Установите некоторые переменные для удобного редактирования
Var_fd='9'
Var_pass="/path/to/passphrase.file"
Var_gpg_opts="--passphrase-fd ${Var_fd} --decrypt"
Var_output_location="out.txt"
Arr_string=( "$@" )
# Откройте дескриптор файла и вставьте файл пароля в него
if [ -f "${Var_pass}" ]; then
exec ${Var_fd}<"${Var_pass}"
else
exec ${Var_fd}<(echo "${Var_pass}")
fi
# Пропустите входной массив через gpg и добавьте к выходному файлу
cat <<<"${Arr_string[*]}" | $(which gpg) ${Var_gpg_opts} >> ${Var_output_location}
# Не забудьте закрыть дескриптор файла
exec ${Var_fd}>&-
Хотя вышеозначенное не так красиво, как защищенная ссылка на GitHub, оно должно быть даже более функциональным, чем ответ, связанный в начале этого поста.
Счастливого взлома.
Один простой метод, который я нашел работающим на машине с linux, это:
1) импортировать ключ в gpg :=>
shell> gpg —import private_key.key
2) расшифровать, указав имя выходного файла :=>
shell> gpg —output -d
2.1) Ввод вышеуказанной команды запрашивает у вас ввод пароля. Введите пароль, и он расшифрует файл gpg.
gpg2 -se --passphrase yourpassword --batch --yes -r [email protected] filename
Добавьте в конец ~/.gnupg/gpg.conf
:
use-agent
pinentry-mode loopback
Добавьте в конец (возможно, нового) файла ~/.gnupg/gpg-agent.conf
:
allow-loopback-pinentry
А затем выполните эту команду:
echo RELOADAGENT | gpg-connect-agent
Теперь вы можете выполнять это без запроса пароля:
echo "$1" | gpg2 --trust-model always --clearsign --batch --no-tty --quiet --no-verbose --yes -u $2 --digest-algo SHA512
--s2k-digest-algo SHA512 --passphrase "$3"
Где $1 это текст для шифрования, $2 это идентификатор пользователя, а $3 — пароль.
Примечание: не помню, почему это работает, но это работает. Если вы знаете детали, пожалуйста, отредактируйте и вставьте сюда.
для Ubuntu 18.04 это сработало для меня-
шифрование:
pass="123"
gpg -c --batch --passphrase "$pass" some-file.tgz
дешифрование:
gpg some-file.tgz.gpg
Даже я сталкивался с той же проблемой. Но ни одна из команд, упомянутых здесь, не сработала, и я также проверял разные ответы с разными командами, но ничего не сработало.
Я был на Ubuntu 20.04.1 LTS
После множества попыток и экспериментов как-то это
gpg --pinentry-mode loopback --passphrase-file=passphrase.txt --decrypt-files my-encrypted-gpg-file.gpg
файл passphrase.txt
содержит ваш пароль, очевидно.
Надеюсь, это поможет.
Вы можете предварительно установить пароль с помощью gpg-preset-passphrase
(полезно для --sign
, --clearsign
и т.д.):
apt install -y gpg gpg-agent
mkdir -p ~/.gnupg
echo allow-preset-passphrase| tee -a ~/.gnupg/gpg-agent.conf
gpg-agent --daemon || gpg-connect-agent reloadagent /bye # может уже работать
/usr/lib/gnupg2/gpg-preset-passphrase -P MyS3Cr3T -c AD91A6ADEA004BDB931317707EE9C281717EE410 # кэширование пароля
gpg --import --allow-secret-key --batch my_secret_key.gpg # импорт работает с кэшированным паролем
gpg --output signed_file.gpg -u E4D76E372E6B3E413D6C9B1DAD6AE9137402C881 --clearsign file_to_sign.txt # подпись работает с кэшированным паролем
С следующими материалами ключа:
gpg -K --with-keygrip
/root/.gnupg/pubring.kbx
------------------------
sec rsa4096 2021-09-27 [SC]
E4D76E372E6B3E413D6C9B1DAD6AE9137402C881
Keygrip = AD91A6ADEA004BDB931317707EE9C281717EE410
uid [ unknown] my super key <[email protected]>
ssb rsa4096 2021-09-27 [E]
Keygrip = 11981E8164AE2A66B09D14E14A83791A9BCDE9BF
Просто нужно добавить некоторые флаги
вы можете добавить --pinentry-mode loopback
или --batch
, и это должно сработать!
Ответ или решение
При работе с GnuPG (GPG), пользователи часто сталкиваются с проблемой, когда команда, предполагающая использование параметра --passphrase
, не работает как ожидается и продолжает запрашивать ввод пароля. В данной статье мы разберем возможные причины данной проблемы и предложим решения, которые могут помочь избежать ввода пароля вручную.
Основная проблема: запрос пароля
Вы можете столкнуться с ситуацией, когда выполняете следующую команду для расшифровки файла:
gpg --passphrase 1234 file.gpg
Или, используя файл с паролем:
gpg --passphrase-file passfile.txt file.gpg
Однако GPG продолжает запрашивать пароль. Причины могут быть следующими:
-
Режимы работы GPG: Начиная с версии 2.1 GPG, были внедрены определённые изменения в обработку паролей и автоматический режим работы. Если вы не укажете параметр
--batch
, GPG автоматически будет ожидать интерактивного ввода, что приведет к запрашиванию пароля, даже если вы передали его через командную строку. -
Проблемы с
pinentry
: GPG используетpinentry
для запроса пароля в случае необходимости. Если вы используете графический интерфейс, иDISPLAY
установлен, GPG будет использовать этот режим, что может привести к необходимости ввода пароля даже при указании его в командной строке или файле. -
Отсутствие полномочий для сплошной автоматизации ввода пароля: Если ваш вопрос касается автоматизации и выполнения команд в пакетном режиме (batch mode), вам необходимо явно указать параметр
--pinentry-mode loopback
в сочетании с--batch
и--no-tty
.
Решения проблемы
Чтобы решить проблему с GPG и избежать ненужного ввода пароля, выполните следующие действия:
-
Используйте параметр
--batch
: Обязательно включите этот параметр, чтобы GPG работал в пакетном режиме. Полная команда может выглядеть следующим образом:gpg --batch --yes --passphrase "1234" -d file.gpg
-
Enable loopback pinentry mode: Добавление этого параметра позволяет использовать ввод пароля напрямую:
gpg --batch --yes --pinentry-mode loopback --passphrase "1234" -d file.gpg
-
Чтение пароля из стандартного ввода: В качестве альтернативы, вы можете перенаправить ввод пароля через стандартный ввод. Например:
echo "1234" | gpg --batch --passphrase-fd 0 -d file.gpg
Либо, используя файл с паролем:
gpg --batch --pinentry-mode loopback --passphrase-file passfile.txt -d file.gpg
-
Настройка конфигурации GPG: Для более глубокой настройки вы можете изменить файлы конфигурации GPG. В файле
~/.gnupg/gpg.conf
добавьте строку:use-agent pinentry-mode loopback
А в
~/.gnupg/gpg-agent.conf
добавьте:allow-loopback-pinentry
После этого выполните команду:
echo RELOADAGENT | gpg-connect-agent
Заключение
Используя вышеуказанные методы, вы сможете успешно обойти запрос пароля при использовании GPG для обработки зашифрованных файлов. Эти настройки особенно полезны для автоматизации процессов и упрощения работы с шифрованием в скриптах. Важно помнить о безопасности используемых вами паролей и следить за тем, чтобы они не были доступны другим пользователям системы.