from gpg import Context
import sys
pp = sys.argv[1] # passphrase
enc = sys.argv[2] # input file (assumed to be encrypted)
dec = sys.argv[3] # output file
with open(enc, 'rb') as reader, open(dec, 'wb') as writer, Context() as ctx:
try:
ctx.decrypt(reader, sink=writer, passphrase=pp)
except Exception as e:
print(str(e), file=sys.stderr)
这种解密方式在提供正确密码的情况下可以正常工作,但显然会缓存这个正确密码,因此任何随后的解密尝试都将成功,而不管提供的密码是否正确。(我在本帖末尾给出了更详细的说明和版本细节。)
显然,这里有一些密码缓存正在进行,但我真的不理解细节。
我想知道的是:我如何修改Python脚本,以便禁用密码短语缓存?请注意,我不关心如何在脚本外部禁用密码短语缓存! 我希望脚本能够自主禁用密码短语缓存。 这可能吗?
以下是上述内容的详细示例。 文件"./demo.py"是我上面列出源代码的文件。 重要提示:仅当我从命令行执行时,才会像下面显示的那样运行。 如果我将其放在文件中并作为脚本执行(或源化),则所有使用错误密码的解密都会失败,无论之前的正确密码解密是否成功。
# Prologue: preparation
# First, define some variables
% ORIGINAL=/tmp/original.txt
% ENCRYPTED=/tmp/encrypted.gpg
% DECRYPTED=/tmp/decrypted.txt
% PASSPHRASE=yowzayowzayowza
# Next, create a cleartext original:
% echo 'Cool story, bro!' > "$ORIGINAL"
# Next, encrypt the original using /usr/bin/gpg
% rm -f "$ENCRYPTED"
% /usr/bin/gpg --batch --symmetric --cipher-algo=AES256 --compress-algo=zlib --passphrase="$PASSPHRASE" --output="$ENCRYPTED" "$ORIGINAL"
# Confirm encryption
% od -c "$ENCRYPTED"
0000000 214 \r 004 \t 003 002 304 006 020 % q 353 335 212 361 322
0000020 U 001 w 350 335 K 347 320 260 224 227 025 275 274 033 X
0000040 020 352 002 006 254 331 374 300 221 265 021 376 254 9 $ <
0000060 233 275 361 226 340 177 330 ! c 372 017 & 300 352 $ k
0000100 252 205 244 336 222 N 027 200 | 211 371 r Z ] 353 6
0000120 261 177 b 336 026 023 367 220 354 210 265 002 : r 262 037
0000140 367 L H 262 370
0000146
# Now, the demonstration proper.
# Initially, decryption with the wrong passphrase fails:
% rm -f "$DECRYPTED"
% python ./demo.py "certainly the wrong $PASSPHRASE" "$ENCRYPTED" "$DECRYPTED"
gpgme_op_decrypt_verify: GPGME: Decryption failed
# Decryption with the right passphrase succeeds:
% rm -f "$DECRYPTED"
% python ./demo.py "$PASSPHRASE" "$ENCRYPTED" "$DECRYPTED"
% od -c "$DECRYPTED"
0000000 C o o l s t o r y , b r o !
0000020 \n
0000021
# After the first successful decryption with the right
# passphrase, decryption with the wrong passphrase always
# succeeds:
% rm -f "$DECRYPTED"
% python ./demo.py "certainly the wrong $PASSPHRASE" "$ENCRYPTED" "$DECRYPTED"
% od -c "$DECRYPTED"
0000000 C o o l s t o r y , b r o !
0000020 \n
0000021
# Some relevant version info
% python -c 'import gpg; print((gpg.version.versionstr, gpg.version.gpgme_versionstr))'
('1.10.0', '1.8.0')
% 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 later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Home: /home/kj146/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
% python --version
Python 3.5.3
% uname -ar
Linux parakeet 3.16.0-4-amd64 #1 SMP Debian 3.16.43-2 (2017-04-30) x86_64 GNU/Linux
print(dir(ctx))
显示什么? - Nick Vithapygpgme_context_init
中使用self->ctx->no_symkey_cache = 1;
来安装 pygpgme。我在我的回答中添加了一个注释,说明如何操作。 - Filip Dimitrovski