gpg --passphrase-fd not working with python 3 subprocess
gnupg, python, subprocess
Solution
`close_fds=True` on POSIX systems on Python 3. Use `pass_fds` to pass input pipe file descriptor:
#!/usr/bin/env python3
import os
import shlex
import sys
from subprocess import Popen
passphrase = 'passsssphrase'
file_to_encrypt = sys.argv[1] if len(sys.argv) > 1 else 'encrypt_me.py'
in_fd, out_fd = os.pipe()
cmd = 'gpg --passphrase-fd {fd} -c --armor -o -'.format(fd=in_fd)
with Popen(shlex.split(cmd) + [file_to_encrypt], pass_fds=[in_fd]):
os.close(in_fd) # unused in the parent
with open(out_fd, 'w', encoding='utf-8') as out_file:
out_file.write(passphrase)
You could also pass the passphrase via stdin:
#!/usr/bin/env python3
import sys
from subprocess import PIPE, Popen
passphrase = 'passsssphrase'
file_to_encrypt = sys.argv[1] if len(sys.argv) > 1 else __file__
cmd = 'gpg --passphrase-fd 0 -c --armor -o -'.split()
with Popen(cmd + [file_to_encrypt], stdin=PIPE) as process:
process.stdin.write(passphrase.encode('utf-8'))
Problem
The following script `encrypt_me.py` (modified from another post) encrypts itself with gpg and prints out the ciphertext in armored form. However it only works on python2.7 but not python3? Do you have any idea what's wrong when it's running on python3? ``` import subprocess import shlex import os import sys in_fd, out_fd = os.pipe() passphrase = 'passsssphrase' os.write(out_fd, passphrase.encode('utf-8')) os.close(out_fd) cmd = 'gpg --passphrase-fd {fd} -c --armor'.format(fd=in_fd) with open(__file__,'r') as stdin_fh: proc=subprocess.Popen(shlex.split(cmd), stdin=stdin_fh, stdout=sys.stdout) proc.communicate() os.close(in_fd) ``` With python2.7: ``` $ python encrypt_me.py Reading passphrase from file descriptor 3 -----BEGIN PGP MESSAGE----- Version: GnuPG v1.4.12 (GNU/Linux) jA0EAwMCXrbnOPX+CipgycBD3ErAKmba6UvtA35mjomOlbiOHX2M0bULbV+v8q8U AJ+sTQcFZK+NoauMgUFm39/ZcNoI7W5u78x8dj5B1N6jLk11C7MgmkNmT5CiliQO kl/el0fDAMnksrqGFpUC6+4ECOTJPpj0Z/Cn/3/62kLHkkbAxs+wyS8lGxXEIEKH XFl3OLRlVmCbvtwzrNMFLiD/St6NHu3Wh9S2xt8fe0PAEAZoYlWWx8lnEQEKewq9 EzLlkLldZaDNja3ePzWZ8Z6AeDtowBa8kj+8x/HjxfKLGheBBNQuaeBdcSHgE/OW esS/tEesQUlfUgqrZc2uBalLTV9xwyIpcV4cg8BubPWFCcBrDQ== =iziW -----END PGP MESSAGE----- ``` With python3: ``` $ python3 encrypt_me.py Reading passphrase from file descriptor 3 ... gpg: error creating passphrase: invalid passphrase gpg: symmetric encryption of `[stdin]' failed: invalid passphrase ```