'Error setting home directory when using python-gnupg
I just installed python-gnupg (with "pip install python-gnupg" witn a Conda terminal); I installed it both on the base environment and also on the environment I'm running) and I'm trying to generate a key. I'm following instructions from https://docs.red-dove.com/python-gnupg/#before-you-start
My code is this:
import gnupg
gpg = gnupg.GPG(gnupghome='C:/Users/danil/OneDrive/Python_projects/')
gpg.encoding = 'utf-8'
input_data = gpg.gen_key_input(key_type="RSA",
key_length=1024)
key =gpg.gen_key(input_data)
print(key)
However, I get this error message:
runfile('C:/Users/danil/OneDrive/Python_projects/Canvas/Canvas 18.py', wdir='C:/Users/danil/OneDrive/Python_projects/Canvas', current_namespace=True) Traceback (most recent call last):
File "C:\Users\danil\anaconda3\envs\spyder-5.2.2\lib\site-packages\gnupg.py", line 881, in init p = self._open_subprocess(["--version"])
File "C:\Users\danil\anaconda3\envs\spyder-5.2.2\lib\site-packages\gnupg.py", line 961, in _open_subprocess result = Popen(cmd, shell=False, stdin=PIPE, stdout=PIPE, stderr=PIPE,
File "C:\Users\danil\anaconda3\envs\spyder-5.2.2\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 108, in init super(SubprocessPopen, self).init(*args, **kwargs)
File "C:\Users\danil\anaconda3\envs\spyder-5.2.2\lib\subprocess.py", line 951, in init self._execute_child(args, executable, preexec_fn, close_fds,
File "C:\Users\danil\anaconda3\envs\spyder-5.2.2\lib\subprocess.py", line 1420, in _execute_child hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] The system cannot find the file specified
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\danil\OneDrive\Python_projects\Canvas\Canvas 18.py", line 6, in gpg = gnupg.GPG(gnupghome='C:/Users/danil/OneDrive/Python_projects')
File "C:\Users\danil\anaconda3\envs\spyder-5.2.2\lib\site-packages\gnupg.py", line 885, in init raise OSError(msg)
OSError: Unable to run gpg (gpg) - it may not be available.
The directory specified exists. I tried different ways of passing the directory (e.g., 'C:\Users\danil\OneDrive\Python') but it didn't work. It appears to start with a "fine not found" issue. I'm using a Windows 10 machine - so I checked for some sort of restricted access for Windows Defender but didn't see any new allerts.
What am I missing?
Solution 1:[1]
What am I missing?
Accorindg to python-gnupg home page
Apart from a recent-enough version of Python, in order to use this module you need to have access to a compatible version of the GnuPG executable. The system has been tested with GnuPG v1.4.9 on Windows and Ubuntu. On a Linux platform, this will typically be installed via your distribution’s package manager (e.g.
apt-geton Debian/Ubuntu). Windows binaries are available here – use one of thegnupg-w32cli-1.4.x.exeinstallers for the simplest deployment options.
Solution 2:[2]
Thank you @Daweo for pointing me in the right direction. Here are a few details on how to install the correct .exe file:
- Go to the official project website: https://www.gnupg.org/index.html
- Click on Downloads
- Scroll down to "GnuPG binary releases"
- Download the "Simple installer for the current GnuPG" - when I did so, I got the file "GnuPG-w32-2.3.4_20211220.exe". This should be sufficient for most needs.
- If you scroll down a little further in the page you will see a list with "End-of-life announcements" - note that the 1.4 version is a legacy version. For most people, I believe they are looking for the latest version available.
After I downloaded the .exe file and installed it on my Windows 10 machine, everything works seamlessly.
Since some of the examples I found online were not fully complete, I decided to share below a series of tests. I hope it helps some beginners. I now can receive an encrypted .csv file (encrypted with a public key I generated) and decrypt it, which was my objective.
The sample code:
# GPG key pair generation and encryption and decryption
# Some usefull reference:
# https://docs.red-dove.com/python-gnupg/
# https://www.gnupg.org/index.html
gpg_path = 'C:/Users/username/GPG_keys/' # the folder you want to work with
#%% generate key
import gnupg
gen_key = False # set to true to generate key; included to avoid generating multiple keys when pressing F5 accidentaly
if gen_key:
gpg = gnupg.GPG(gnupghome=gpg_path)
#gpg.encoding = 'utf-8'
input_data = gpg.gen_key_input(key_type = "RSA",
key_length = 2048,
expire_date = 0,
passphrase = 'your_pass_phrase',
name_real = 'Your Name Here',
name_email = '[email protected]')
key = gpg.gen_key(input_data)
print('Key fingerprint: '+ str(key))
#%% list keys
import gnupg
from pprint import pprint
gpg = gnupg.GPG(gnupghome=gpg_path)
public_keys = gpg.list_keys()
private_keys = gpg.list_keys(secret=True)
print ('public keys:')
pprint(public_keys)
print ('private keys:')
pprint(private_keys)
#%% export key to asc file; in this case export the first key read above
ascii_public_keys = gpg.export_keys(public_keys[0]['keyid'])
ascii_private_keys = gpg.export_keys(private_keys[0]['keyid'], secret=True, passphrase='your_pass_phrase')
with open(gpg_path+'mykeyfile.asc', 'w') as f:
f.write(ascii_public_keys)
f.write(ascii_private_keys)
#%% import keys
import gnupg
from pprint import pprint
gpg = gnupg.GPG(gnupghome=gpg_path)
key_data = open(gpg_path+'mykeyfile.asc').read()
import_result = gpg.import_keys(key_data)
pprint(import_result.results)
#%% deleting a key
delete_key = False # set to True to delete a specific key
if delete_key:
fp = '563E115BB1BA5FA76FDEC1A48AA909D50093CAA7' # fingerprint of key to be deleted
str(gpg.delete_keys(fp, secret=True, passphrase='your_pass_phrase')) # must delete private key first
str(gpg.delete_keys(fp))
#%% encrypt text
data = 'test 123, test 123'
fp = '563E115BB1BA5FA76FDEC1A48AA909D50093CAA7' # fingerprint of key to be used
encrypted_ascii_data = gpg.encrypt(data, fp)
print("Test data: " + data + '\n')
print (encrypted_ascii_data)
#%% decrypt text
print('Data received: ' + str(encrypted_ascii_data))
decrypted_data = gpg.decrypt(encrypted_ascii_data.data, passphrase='your_pass_phrase')
print ('Decrypted data: ' + str(decrypted_data))
#%% encrypt a file
filename = gpg_path + 'original_test_file.csv' # test .csv file you want to use
stream = open(filename, 'rb')
encrypted_ascii_data = gpg.encrypt_file(stream, fp)
with open(gpg_path+'ascii_test_file.asc', 'w') as f:
f.write(str(encrypted_ascii_data))
#%% decrypt a file
filename = gpg_path + 'ascii_test_file.asc'
stream = open(filename, 'rb')
decrypted_file_data = gpg.decrypt_file(stream, passphrase='your_pass_phrase')
with open(gpg_path+'decrypted_test_file.csv', 'w', newline='') as f:
f.write(str(decrypted_file_data))
Solution 3:[3]
Has this code worked. I am not able to run this from aws lambda. {"message":"Exception_Message : 'NoneType' object has no attribute 'groups'"
["File : /var/task/lambda_function.py , Line : 24, Func.Name : lambda_handler, Message : gpg = gnupg.GPG(homedir='/mnt/tmp/gnupg_home/.gnupg', binary='/mnt/tmp/python/gpg', verbose=False)", 'File : /opt/python/gnupg/gnupg.py , Line : 162, Func.Name : init, Message : self.create_trustdb()', 'File : /opt/python/gnupg/gnupg.py , Line : 172, Func.Name : create_trustdb, Message : if self.is_gpg2():', 'File : /opt/python/gnupg/gnupg.py , Line : 212, Func.Name : is_gpg2, Message : return _util._is_gpg2(self.binary_version)', 'File : /opt/python/gnupg/_util.py , Line : 531, Func.Name : _is_gpg2, Message : (major, minor, micro) = _match_version_string(version)', 'File : /opt/python/gnupg/_util.py , Line : 617, Func.Name : _match_version_string, Message : g = matched.groups()']
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Daweo |
| Solution 2 | Rational-IM |
| Solution 3 | Rubiya |
