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

时间:2015-07-19 12:28:03

标签: 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)

我想将_file加密为字符串,以便将其作为加密文件用于上传请求 使用gnupg库的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

您可以使用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()

现在我不是这种方法安全性的专家,但是,将密码直接写入子进程&#39;使用communicate()的stdin比在命令行上回显密码更好 - 任何可以运行ps或等效的人都可以看到。

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

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

您可能最好不要使用公钥加密。