Вопрос

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
Это было полезно?

Решение

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'))
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top