Decrypting PGP using gnupg in Python - python

I am trying to decrypt a PGP file using this module:
http://packages.python.org/python-gnupg/
Here is my code snippet:
#!/usr/bin/python
import gnupg
gpg = gnupg.GPG(gnupghome='C:\\Users\\GSquire\\Desktop\\GnuPG',
gpgbinary='C:\\Users\\GSquire\\Desktop\\GnuPG\\pub\\gpg.exe',
keyring='C:\\Users\\GSquire\\Desktop\\GnuPG\\secring.skr')
with open('.\\tranx08022012.txt.pgp', 'rb') as f:
status = gpg.decrypt_file(f, passphrase='passphrase', output='out.txt')
I am using the latest version of the module, and Python 2.6.6. I thought I could just use the secure ring file to decrypt it because that is obviously needed by the file. It outputs this when I run the script:
ok: False
status:
stderr:
gpg: expected public key but found secret key - must stop
Isn't it true that the secure key is what decrypts the file? Thanks for the help!

The error you're getting is because you're passing the secret keyring's filename in the keyring parameter. That parameter is only for the public keyring. Unfortunately, there doesn't seem to be an alternative parameter to specify a secret keyring file.
By default, GnuPG will look for secret keys in secring.gpg in the gnupghome folder you specify, so you can probably rename your secret key file and get it to work.

Related

Decrypt using BCPGP private key in python

How do I read BouncingCastle PGP key and decrypt message using Python.?
This private key is generated using GoAnywhere OpenPGP Studio, password is Test#123
Below is the key blob and the error I'm getting. I'm getting same error when I read from file(.asc) as well
test_key_pvt = """-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: BCPG v1.48
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
/+ldLYPLUjczvK+qk1dbU89Grv7h/w==
=Uo6i
-----END PGP PRIVATE KEY BLOCK-----
"""
pvt_key, _ = pgpy.PGPKey.from_blob(test_key_pvt)
Error: pgpy.errors.PGPError: 6 is not a valid SymmetricKeyAlgorithm
Another error for different key: pgpy.errors.PGPError: 112 is not a valid CompressionAlgorithm
Not able to arrive at any solution, I'm trying to automate a very small transfer and its really annoying that I'm not able to find anything for this in python. PGPY library doesn't have a lot of documentation.
TIA

ValueError("Expected: ASCII-armored PGP data") when using pgp_key.from_blob(key_string)

I am getting ValueError("Expected: ASCII-armored PGP data") when using pgp_key.from_blob(key_string) when trying to parse the key.
pgp_key = pgpy.PGPKey()
key = pgp_key.from_blob(key_string);
I tried using parse method as well but getting the same error.
I fixed this error by:
With your key as a file, run base64 /path/to/file_name new_encoded_file_name
Put your encoded key in your desired place (AWS Secrets Manager in my case)
Within your program, add the following line BEFORE getting your pgp key:
key_string = base64.decode(key_string)
Now key = pgp_key.from_blob(key_string) will no longer throw an error as the decoded string will be an ASCII-armored bytearray.

How to check if a key is already encrypted while using Fernet

I am trying to encrypt sensible values in my environment file using a python script. I am using Fernet. I want to encrypt only those values which are not already encrypted, making sure that there isn't any multi-level encryption.
How can I know that a value is already encrypted or decrypted in this case?
Simply attempt decryption with a TTL of None (the default). If it succeeds, then you don't need to do anything more. If it fails an InvalidToken exception will be raised which you can catch. Inside the except block you can then encrypt the file, as in the following example:
import base64
from pathlib import Path
from cryptography.fernet import Fernet, InvalidToken
key = Fernet.generate_key()
f = Fernet(key)
encrypted = f.encrypt(b'Hello world')
p1, p2 = Path('file1'), Path('file2')
p1.write_bytes(encrypted)
p2.write_bytes(base64.urlsafe_b64encode(b'\x80not encrypted'))
for example in (p1, p2):
try:
data = example.read_bytes()
f.decrypt(data, None)
except InvalidToken:
example.write_bytes(f.encrypt(data))

python gnupg not encrypting file

I am trying to encrypt a file with a GPG key but the output is keeps being empty:
>>> import gnupg
>>> home_dir = '~/.gnupg'
>>> pgp = gnupg.GPG(gnupghome=home_dir)
>>> key = open('ff.asc', 'rb')
>>> fp = open('test.txt', 'rb')
>>> res = pgp.import_keys(key.read())
>>> res.results
[{'fingerprint': 'C3...', 'text': 'Not actually changed\n', 'ok': '0'}]
>>> enc = pgp.encrypt_file(fp, 'C3...')
>>> enc.data
b''
What am I missing here?
Also, is it possible to pass the public GPG key directly to the encryption function from a string without having to import it?
The problem may be that the imported key is not trusted. From the documentation of gnupg:
Note:
Any public key provided for encryption should be trusted, otherwise
encryption fails but without any warning. This is because gpg just
prints a message to the console, but does not provide a specific error
indication that the Python wrapper can use.
The simplest solution is to use the always_trust keyword argument of encryption functions:
always_trust (defaults to False) - Skip key validation and
assume that used keys are always fully trusted.
Thus your encryption statement should read
enc = pgp.encrypt_file(fp, 'C3...', always_trust=True)

python gnupg sign, and verify

I am trying to see if I can get the python-gnupg module working to sign and verify a file using a python script. I have the following code, which does not interpret any errors when called.
However the code prints "unverified" at the end, when I thought that I had signed the file (example.txt).
I must be missing something in the documentation but after I read it this is what I came up with for signing and verifying. Any help please?
import gnupg
gpg = gnupg.GPG(gnupghome="/home/myname")
stream = open("example.txt", "rb")
signed_data = gpg.sign_file(stream)
verified = gpg.verify_file(stream)
print "Verified" if verified else "Unverified"
There are a few issues with your code,
1.) gpg = gnupg.GPG(gnupghome="/home/myname") needs to be gpg = gnupg.GPG(gnupghome="/home/myname/.gnupg")
2.) You are attempting to verify the stream, using verify_file(stream), however the stream is still a handle to the original, unsigned file. You would first need to either write the signed data to a new file and call verify_file() against a handle to that file, or verify the result sign_file.
Below is a working example of your demo, using the result of sign_file - but before we get to that, the way to troubleshoot what is happening in your script, you can review the output of stderr on the returned object of the gnupg methods. for example, you can review the result of the signed data by printing out signed_data.stderr. Likewise for return of the verify_file method.
On to the code -
import gnupg
gpg = gnupg.GPG(gnupghome="/home/myname/.gnupg")
stream = open("example.txt", "rb")
signed_data = gpg.sign_file(stream)
verified = gpg.verify(signed_data.data)
print "Verified" if verified else "Unverified"
I hope this helps!

Categories