在python 3中使用子进程在GPG中加密文件 [英] Encrypt file with GPG in python 3 with subprocess
问题描述
如何使用子进程加密文件,所以输出将是字符串.
How do I encrypt file with subprocess, so the output will be string.
password = '%030x' % random.randrange(16**30)
encrypted_file = subprocess.geststatusoutput("echo "+password+
"|gpg --password-fd 0 < "+ name_of_selected_file)
我想将_file加密为字符串,这样我就可以将其用作加密文件,并通过发布请求进行上传.
使用gnupg库的最佳方法是什么?
I want to encrypted _file to be a string so I could use it as encrypted file to upload with post request.
What is the best way to do it with gnupg library?
推荐答案
You can use subprocess.Popen()
to execute a gpg command like this:
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解密:
Or, decryption for Python 3 only:
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()
Now I am not an expert on the security of this method, however, writing the passphrase directly to the child process' stdin with communicate()
is better than echoing the passphrase on the command line - which would be visible to anybody that could run ps
or equivalent.
此外,依赖于命令的Shell级IO重定向,将需要Popen的shell=True
参数,这可能会带来其他安全隐患(请参见Popen()
文档中的警告).
Also, relying on the shell level IO redirection of your command would require the shell=True
argument to Popen which might have other security implications (see the warning in the Popen()
documentation).
我在我的gpg
命令中假设您打算使用对称加密(您的示例没有其他建议).如果远程服务器需要能够解密加密的文件内容,您将如何共享生成的密码?
I have assumed in my gpg
command that you are intending to use a symmetric encryption (your example does not suggest otherwise). If the remote server needs to be able to decrypt the encrypted file content, how are you going to share the generated passphrase?
您最好改用公钥加密.
这篇关于在python 3中使用子进程在GPG中加密文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!