gpg – passphrase-fd no funciona con el subproceso Python 3

La siguiente secuencia de comandos encrypt_me.py ( modificada de otra publicación ) se cifra con gpg e imprime el texto cifrado en forma blindada.

Sin embargo, solo funciona en python2.7 pero no en python3? ¿Tienes idea de lo que está mal cuando se ejecuta en 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) 

Con 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----- 

Con 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 

close_fds=True en los sistemas POSIX en Python 3. Use pass_fds para pasar el descriptor de archivo de la tubería de entrada:

 #!/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) 

También puede pasar la contraseña a través de 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'))