使用子进程在 python 3 中使用 GPG 加密文件

Encrypt file with GPG in python 3 with subprocess

如何使用子进程加密文件,以便输出为字符串。

 password = '%030x' % random.randrange(16**30)
 encrypted_file = subprocess.geststatusoutput("echo "+password+
 "|gpg --password-fd 0 < "+ name_of_selected_file)

我想将 _file 加密成一个字符串,这样我就可以将它用作加密文件,通过 post 请求上传。
使用 gnupg 库的最佳方法是什么?

您可以使用 subprocess.Popen() 来执行这样的 gpg 命令:

import shlex
import random
from subprocess import Popen, PIPE

passphrase = '%030x' % random.randrange(16**30)
source_filename = '/tmp/somefile'
cmd = 'gpg --batch --symmetric --cipher-algo AES256 --passphrase-fd 0 --output - {}'.format(source_filename)

# error handling omitted
p = Popen(shlex.split(cmd), stdout=PIPE, stdin=PIPE, stderr=PIPE)
encrypted_data = p.communicate(passphrase.encode())[0]

# Decryption - should work for Python 2 & 3
import os

r, w = os.pipe()    # pipe for sending passphrase from parent to child
try:
    os.set_inheritable(r, True)
except AttributeError:      # new in version 3.4
    pass
cmd = 'gpg --batch --decrypt --passphrase-fd {}'.format(r)
p = Popen(shlex.split(cmd), stdout=PIPE, stdin=PIPE, stderr=PIPE, close_fds=False)
os.close(r)    # closes fd in parent, child needs it
f = os.fdopen(w, 'w')
f.write(passphrase + '\n')    # '\n' seems required for Python 2 ???
f.close()
decrypted_data, stderr = p.communicate(encrypted_data)

# check that data was successfully roundtripped
assert open(source_filename).read() == decrypted_data.decode()

或者,仅对 Python 3 进行解密:

import os
r, w = os.pipe()
cmd = 'gpg --batch --decrypt --passphrase-fd {}'.format(r)
p = Popen(shlex.split(cmd), stdout=PIPE, stdin=PIPE, stderr=PIPE, pass_fds=(r,))
os.close(r)    # closes fd in parent, child needs it
open(w, 'w').write(passphrase)
decrypted_data, stderr = p.communicate(encrypted_data)

# check that data was successfully roundtripped
assert open(source_filename).read() == decrypted_data.decode()

现在我不是这种方法的安全专家,但是,使用 communicate() 将密码短语直接写入子进程的标准输入优于在命令行上回显密码短语 - 这将是任何人都可以看到 运行 ps 或等价物。

此外,依赖于命令的 shell 级别 IO 重定向将需要 Popen 的 shell=True 参数,这可能具有其他安全隐患(请参阅 Popen() 文档中的警告).

我在我的 gpg 命令中假设您打算使用对称加密(您的示例没有其他建议)。如果远程服务器需要能够解密加密的文件内容,你打算如何共享生成的密码?

您最好还是考虑使用 public 密钥加密。