您可以使用
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)
p = Popen(shlex.split(cmd), stdout=PIPE, stdin=PIPE, stderr=PIPE)
encrypted_data = p.communicate(passphrase.encode())[0]
import os
r, w = os.pipe()
try:
os.set_inheritable(r, True)
except AttributeError:
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)
f = os.fdopen(w, 'w')
f.write(passphrase + '\n')
f.close()
decrypted_data, stderr = p.communicate(encrypted_data)
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)
open(w, 'w').write(passphrase)
decrypted_data, stderr = p.communicate(encrypted_data)
assert open(source_filename).read() == decrypted_data.decode()
现在我并不是关于此方法安全性的专家,然而,使用
communicate()
将口令直接写入子进程的stdin比在命令行上回显口令更好——因为这样做会对任何能运行
ps
或等效命令的人可见。
另外,依赖于您的命令的shell级IO重定向需要
shell=True
参数传递给Popen,这可能会有其他安全隐患(请参阅
Popen()
文档中的警告)。
在我的
gpg
命令中,我假设您打算使用对称加密(您的示例没有暗示其他)。如果远程服务器需要能够解密加密文件内容,那么您将如何共享生成的口令?
您最好考虑使用公钥加密。