python 读取加密(使用 gnupg)zipfile 的内容而不将文件解密到文件系​​统

python read contents of encrypted(using gnupg) zipfile without decrypting the file to filesystem

在 zipfile.ZipFile 的帮助下,我能够 access/read zip 文件中的文件,而无需实际解压缩到文件夹中。

with zipfile.ZipFile('data.zip', 'rb') as zfile:
    with zfile.open('fil.dat', 'r') as dfile:
        csv_data = io.TextIOWrapper(dfile, encoding='utf-8')
        ....
        ....

现在,是否可以 read/access 加密 zip 文件中的文件? zip 文件使用 gnupg
加密 我有一个解决方法来解密和读取 zip 的内容,如下所示

import gnupg
gpg = gnupg.GPG()
with open('key.asc') as kfile:
    key = kfile.read()

gpg.import_keys(key)
with open('data.zip.gpg', 'rb') as gfile:
    gpg.decrypt_file(gfile, passphrase='password', output='data.zip')

这将在文件系统上创建一个新的解密 zip 文件,允许我在 zip 文件中包含 read/access 个文件,每次使用后必须删除该文件。
是否可以将 zip 文件解密为类文件对象并访问内容,而无需在文件系统上实际创建解密的 zip 文件?
我尝试了类似下面的方法,但失败了。

import gnupg
gpg = gnupg.GPG()
with open('key.asc') as kfile:
    key = kfile.read()
gpg.import_keys(key)

zip_file_obj = io.BytesIO()

with open('data.zip.gpg', 'rb') as gfile:
    gpg.decrypt_file(gfile, passphrase='password', output=zip_file_obj)

以上代码失败并出现错误 BytesIO type is not a valid input。
对于我的用例,有没有办法完成这个或任何其他 python wrapper/package?
注意:我正在使用 python 3.6

错误:

Traceback (most recent call last):
  File "gptester.py", line 15, in <module>
    gpg.decrypt_file(gfile, passphrase='TESTTESTTEST', output=zip_file_obj)
  File "/usr/local/lib/python3.6/site-packages/gnupg/gnupg.py", line 1093, in decrypt_file
    if os.path.exists(output):
  File "/usr/local/lib/python3.6/genericpath.py", line 19, in exists
    os.stat(path)
TypeError: stat: path should be string, bytes, os.PathLike or integer, not _io.BytesIO


编辑 - II
我根据提供的建议尝试了这段代码

from io import BytesIO
from zipfile import ZipFile
import gnupg

with open('worker/key.asc') as kfile:
    key = kfile.read()

gpg = gnupg.GPG()
gpg.import_keys(key)
zip_file_obj = BytesIO()

with open('data.zip.gpg', 'rb') as gfile:
    decrypt_data = gpg.decrypt_file(gfile, passphrase='password')

zip_file_obj = BytesIO(decrypt_data)

错误:

Exception in thread Thread-2:
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.6/threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.6/site-packages/gnupg/_meta.py", line 650, in _read_response
    result._handle_status(keyword, value)
  File "/usr/local/lib/python3.6/site-packages/gnupg/_parsers.py", line 1294, in _handle_status
    raise ValueError("Unknown status message: %r" % key)
ValueError: Unknown status message: 'PINENTRY_LAUNCHED'

Traceback (most recent call last):
  File "gptester.py", line 17, in <module>
    zip_file_obj = BytesIO(decrypt_data)
TypeError: a bytes-like object is required, not 'Crypt'

Documentation 表明你可以做到

decrypted_data = gpg.decrypt_file(gfile, passphrase='password')

无需写入文件即可获取。

要创建类文件对象,您需要 decrypted_data.data

zip_file_obj = io.BytesIO(decrypted_data.data)

文档还提到 str(decrypted_data) 作为获取数据的方法。