在Python3中使用GPG加密文件,并使用子进程

在Python3中使用GPG加密文件,并使用子进程,python,python-3.x,encryption,subprocess,gnupg,Python,Python 3.x,Encryption,Subprocess,Gnupg,如何使用子进程加密文件,以便输出为字符串 password = '%030x' % random.randrange(16**30) encrypted_file = subprocess.geststatusoutput("echo "+password+ "|gpg --password-fd 0 < "+ name_of_selected_file) password='%030x'%random.randrange(16**30) 加密的_文件=subprocess.ges

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

 password = '%030x' % random.randrange(16**30)
 encrypted_file = subprocess.geststatusoutput("echo "+password+
 "|gpg --password-fd 0 < "+ name_of_selected_file)
password='%030x'%random.randrange(16**30)
加密的_文件=subprocess.geststatusoutput(“echo”+密码+
“| gpg--密码fd 0<”+所选文件的名称)
我想将加密的_文件设置为字符串,这样我就可以使用它作为加密文件,通过post请求进行上传。
使用gnupg库执行此操作的最佳方法是什么?

您可以使用以下方法执行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()
现在我不是该方法安全性方面的专家,但是,使用直接将密码短语写入子进程的stdin比在命令行上回显密码短语要好——任何可以运行
ps
或等效程序的人都可以看到该密码短语

此外,依赖命令的shell级别IO重定向将需要Popen的
shell=True
参数,这可能会产生其他安全影响(请参阅
Popen()
文档中的警告)


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


您最好改用公钥加密。

我从未尝试过它-但gpg有一个python库:。我不想仅仅为了一些可以简单编写脚本的东西而使用另一个外部库。有很好的理由不手动连接GnuPG。像您一样传递密码短语是其中之一,当GnuPG通过读取命令行参数工作时,系统中的每个人都能够读取它。它还解决了可能发生和将要发生的一系列其他问题,包括正确的错误处理。相关:“你打算如何共享生成的密码短语?”这是一个很好的观点。我主要在上传文件的工具中使用它,因此文件的链接将是,然后用类似的方法解密文件。@J.F.Sebastian是对的,这段代码不起作用。现在我真的在考虑用gnupg库找到一个解决方案。解密是非常相似的。但是,由于加密数据被发送到子系统的stdin,因此需要通过新管道将密码短语从父系统发送到子系统。我已经在我的答案中添加了一个通用的Python解决方案以及一个只有Python 3的版本<代码>加密的\u数据通过
communicate()
传递给gpg子进程。这是去孩子的酒吧。