Encrypting to Multiple Keys

Encrypting to multiple keys essentially just expands upon the key selection process and the recipients from the previous examples.

The following example encrypts a message (text) to everyone with an email address on the gnupg.org domain,You probably don't really want to do this. Searching the keyservers for "gnupg.org" produces over 400 results, the majority of which aren't actually at the gnupg.org domain, but just included a comment regarding the project in their key somewhere. but does not encrypt to a default key or other key which is configured to normally encrypt to.

import gpg text = b"""Oh look, another test message. The same rules apply as with the previous example and more likely than not, the message will actually be drawn from reading the contents of a file or, maybe, from entering data at an input() prompt. Since the text in this case must be bytes, it is most likely that the input form will be a separate file which is opened with "rb" as this is the simplest method of obtaining the correct data format. """ c = gpg.Context(armor=True) rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) logrus = [] for i in range(len(rpattern)): if rpattern[i].can_encrypt == 1: logrus.append(rpattern[i]) ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, sign=False, always_trust=True) with open("secret_plans.txt.asc", "wb") as f: f.write(ciphertext)

All it would take to change the above example to sign the message and also encrypt the message to any configured default keys would be to change the c.encrypt line to this:

ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, always_trust=True, add_encrypt_to=True)

The only keyword arguments requiring modification are those for which the default values are changing. The default value of sign is True, the default of always_trust is False, the default of add_encrypt_to is False.

If always_trust is not set to True and any of the recipient keys are not trusted (e.g. not signed or locally signed) then the encryption will raise an error. It is possible to mitigate this somewhat with something more like this:

import gpg with open("secret_plans.txt.asc", "rb") as f: text = f.read() c = gpg.Context(armor=True) rpattern = list(c.keylist(pattern="@gnupg.org", secret=False)) logrus = [] for i in range(len(rpattern)): if rpattern[i].can_encrypt == 1: logrus.append(rpattern[i]) try: ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True) except gpg.errors.InvalidRecipients as e: for i in range(len(e.recipients)): for n in range(len(logrus)): if logrus[n].fpr == e.recipients[i].fpr: logrus.remove(logrus[n]) else: pass try: ciphertext, result, sign_result = c.encrypt(text, recipients=logrus, add_encrypt_to=True) except: pass with open("secret_plans.txt.asc", "wb") as f: f.write(ciphertext)

This will attempt to encrypt to all the keys searched for, then remove invalid recipients if it fails and try again.