Open chrishinds opened 9 years ago
Thanks. I had the same issue.
How decrypt ?
gpg = gnupg.GPG()
x = gpg.encrypt("foo", symmetric=True, passphrase='bar', encrypt=False)
gpg.decrypt(x.data, symmetric=True, passphrase='bar')
TypeError Traceback (most recent call last)
in () 1 gpg = gnupg.GPG() 2 x = gpg.encrypt("foo", symmetric=True, passphrase='bar', encrypt=False) ----> 3 gpg.decrypt(x.data, symmetric=True, passphrase='bar') /home/tadashi/anaconda3/lib/python3.5/site-packages/gnupg/gnupg.py in decrypt(self, message, **kwargs) 985 """ 986 stream = _make_binary_stream(message, self._encoding) --> 987 result = self.decrypt_file(stream, **kwargs) 988 stream.close() 989 return result TypeError: decrypt_file() got an unexpected keyword argument 'symmetric'
Hi @chrishinds! Thanks for the suggestion! I agree that the API needs some work there. I'm happy to take a patch for this change, but since it would break backwards compatibility, I'd have to start a branch for python-gnupg 3.x.x and possibly maintain two sets of bug patches. It's be nice to group this together with any other API fixes which are non-backwards-compatible.
@zanjibar
gpg.decrypt(x.data, passphrase='bar', output='/path/to/write/file')
thank you @bradleyhurley
import gnupg
gpg = gnupg.GPG()
x = gpg.encrypt("foo", symmetric=True, passphrase='bar', encrypt=False)
y = gpg.decrypt(x.data, passphrase='bar')
y.data.decode('utf-8')
I get a ValueError when I run the code @zanjibar posted above with Python 3.6.2
import gnupg
gpg = gnupg.GPG()
x = gpg.encrypt("foo", symmetric=True, passphrase='bar', encrypt=False)
y = gpg.decrypt(x.data, passphrase='bar')
y.data.decode('utf-8')
Exception in thread Thread-5: Traceback (most recent call last): File "/usr/lib/python3.6/threading.py", line 916, in _bootstrap_inner self.run() File "/usr/lib/python3.6/threading.py", line 864, in run self._target(*self._args, **self._kwargs) File "/usr/lib/python3.6/site-packages/gnupg/_meta.py", line 650, in _read_response result._handle_status(keyword, value) File "/usr/lib/python3.6/site-packages/gnupg/_parsers.py", line 1715, in _handle_status super(Crypt, self)._handle_status(key, value) File "/usr/lib/python3.6/site-packages/gnupg/_parsers.py", line 1628, in _handle_status raise ValueError("Unknown status message: %r" % key) ValueError: Unknown status message: 'DECRYPTION_COMPLIANCE_MODE'
I get the same with Python 2.7.13, but at least (in both versions) the returned object contains the decrypted data.
It also seems gpg.decrypt_file() has no way of decrypting symmetrically encrypted files:
$ echo "foo" | gpg --symmetric > bar.gpg # password; 12345
$ gpg --decrypt bar.gpg
gpg: AES encrypted data gpg: encrypted with 1 passphrase foo
import gnupg
gpg = gnupg.GPG()
with open('bar.gpg', 'rb') as f:
y = gpg.decrypt_file(f, passphrase='12345')
y.data
b''
Or maybe I'm doing something wrong? Is there another/temporary solution for this?
Ah also just for records sake, I installed gnupg with pip on both Python 2 and 3; gnupg==2.3.0
Vinjay's python-gpg worked for me (version 0.4.3, GnuPG 2.2.4):
>>> import gnupg
>>> gpg = gnupg.GPG()
>>> x = gpg.encrypt("message", [], symmetric=True, passphrase='1234')
>>> y = gpg.decrypt(x.data, passphrase='1234')
>>> y.data
b'message'
>>>
Many many thx. I have a ancient encryption/decryption GUI app i built years ago, and it suddenly stopped working. It looked complicated and i was ready to say goodbye to it and all my encrypted texts because i have not used python for many years and have forgotten even where to start. Turns out after finding this post it was just one added argument.
Am bringing forward some software which used an older version of gnupg. This newer version with the vulnerability fix is really great. However, one of the differences that confused me was as follows:
the old api allowed:
but on 2.0.2 this yields:
ValueError: Unknown status message: u'NO_RECP'
the new version needs an extra encrypt=False, eg:
Maybe others are smarter, but I wasn't able to figure this out from the docs. This is clearly a pretty minor issue, but perhaps in writing it up I'll save someone else an hour of faff. In sum, I get that the encrypt=False refers to the recipients that I'm not supplying, but fwiw, the older api seems more intuitive to me!