Last active
July 24, 2018 21:03
-
-
Save rezemika/8f45485b3a9c6cfe31920e6ee356891f to your computer and use it in GitHub Desktop.
Outil de chiffrement et signature de message par GPG en ligne de commande
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Un petit script pour rendre plus intuitif le chiffrement et/ou | |
la signature d'un message avec GPG. | |
Dépendances : | |
$ pip3 install python-gnupg npyscreen humanfriendly | |
""" | |
# To package this into a standalone program, see "pyinstaller" (https://www.pyinstaller.org/): `pyinstaller easycrypt.py`. | |
from sys import exit | |
import gnupg | |
import npyscreen | |
import humanfriendly | |
class EncryptionAndSignatureForm(npyscreen.Form): | |
def __init__(self, *args, public_keys=None, private_keys=None, **kwargs): | |
if public_keys is None: | |
public_keys = [] | |
if private_keys is None: | |
private_keys = [] | |
self.public_keys = public_keys | |
self.private_keys = private_keys | |
super().__init__(*args, **kwargs) | |
def create(self): | |
self.public_keys = self.add( | |
npyscreen.TitleMultiSelect, | |
name="Clés publiques à utiliser pour le chiffrement", | |
values=self.public_keys, | |
max_height=4, | |
scroll_exit=True | |
) | |
self.signing_key = self.add( | |
npyscreen.TitleSelectOne, | |
name="Clé privée à utiliser pour la signature", | |
values=self.private_keys, | |
max_height=4, | |
scroll_exit=True | |
) | |
self.passphrase = self.add(npyscreen.TitlePassword, name="Phrase de passe pour la signature") | |
self.separator = self.add(npyscreen.TitleText, name="Message") | |
self.message = self.add(npyscreen.MultiLineEdit) | |
def encrypt_and_sign(*args): | |
gpg = gnupg.GPG() | |
public_keys = [ | |
(k["uids"][0] + ' - ' + k["keyid"], k["fingerprint"]) for k in gpg.list_keys() | |
] | |
private_keys = [ | |
(k["uids"][0] + ' - ' + k["keyid"], k["fingerprint"]) for k in gpg.list_keys(True) | |
] | |
F = EncryptionAndSignatureForm( | |
name="Message à chiffrer et signer", | |
public_keys=[k[0] for k in public_keys], | |
private_keys=[k[0] for k in private_keys] | |
) | |
while True: | |
F.edit() | |
message = F.message.value | |
public_keys_fingerprints = [public_keys[pk][1] for pk in F.public_keys.value] | |
private_key_fingerprint = private_keys[F.signing_key.value[0]][1] | |
output = '' | |
if not public_keys_fingerprints: | |
npyscreen.notify_confirm( | |
"Vous devez choisir au moins une clé publique.", | |
title="Erreur" | |
) | |
continue | |
encrypted_message = gpg.encrypt( | |
message, | |
recipients=public_keys_fingerprints, | |
sign=private_key_fingerprint, | |
passphrase=F.passphrase.value, | |
armor=True, | |
always_trust=True | |
) | |
if encrypted_message.status == "encryption ok": | |
return str(encrypted_message) | |
elif encrypted_message.status == "key expired": | |
npyscreen.notify_confirm( | |
"Une des clés publiques choisies est expirée.", | |
title="Erreur" | |
) | |
else: | |
F.message.value = message | |
F.passphrase.value = '' | |
npyscreen.notify_confirm( | |
"Phrase de passe incorrecte !", | |
title="Erreur" | |
) | |
class EncryptionForm(npyscreen.Form): | |
def __init__(self, *args, public_keys=None, **kwargs): | |
if public_keys is None: | |
public_keys = [] | |
self.public_keys = public_keys | |
super().__init__(*args, **kwargs) | |
def create(self): | |
self.public_keys = self.add( | |
npyscreen.TitleMultiSelect, | |
name="Clés publiques à utiliser pour le chiffrement", | |
values=self.public_keys, | |
max_height=4, | |
scroll_exit=True | |
) | |
self.separator = self.add(npyscreen.TitleText, name="Message") | |
self.message = self.add(npyscreen.MultiLineEdit) | |
def encrypt(*args): | |
gpg = gnupg.GPG() | |
public_keys = [ | |
(k["uids"][0] + ' - ' + k["keyid"], k["fingerprint"]) for k in gpg.list_keys() | |
] | |
F = EncryptionForm( | |
name="Message à chiffrer", | |
public_keys=[k[0] for k in public_keys] | |
) | |
while True: | |
F.edit() | |
message = F.message.value | |
public_keys_fingerprints = [public_keys[pk][1] for pk in F.public_keys.value] | |
encrypted_message = gpg.encrypt( | |
message, | |
recipients=public_keys_fingerprints, | |
armor=True, | |
always_trust=True | |
) | |
if encrypted_message.status == "key expired": | |
npyscreen.notify_confirm( | |
"Une des clés publiques choisies est expirée.", | |
title="Erreur" | |
) | |
else: | |
return str(encrypted_message) | |
class SignForm(npyscreen.Form): | |
def __init__(self, *args, private_keys=None, **kwargs): | |
if private_keys is None: | |
private_keys = [] | |
self.private_keys = private_keys | |
super().__init__(*args, **kwargs) | |
def create(self): | |
self.signing_key = self.add( | |
npyscreen.TitleSelectOne, | |
name="Clé privée à utiliser pour la signature", | |
values=self.private_keys, | |
max_height=4, | |
scroll_exit=True | |
) | |
self.passphrase = self.add(npyscreen.TitlePassword, name="Phrase de passe pour la signature") | |
self.separator = self.add(npyscreen.TitleText, name="Message") | |
self.message = self.add(npyscreen.MultiLineEdit) | |
def sign(*args): | |
gpg = gnupg.GPG() | |
private_keys = [ | |
(k["uids"][0] + ' - ' + k["keyid"], k["keyid"]) for k in gpg.list_keys(True) | |
] | |
F = SignForm( | |
name="Message à signer", | |
private_keys=[k[0] for k in private_keys] | |
) | |
while True: | |
F.edit() | |
message = F.message.value | |
private_key_id = private_keys[F.signing_key.value[0]][1] | |
signed_message = gpg.sign( | |
message, | |
keyid=private_key_id, | |
passphrase=F.passphrase.value, | |
clearsign=True | |
) | |
if signed_message.status == "signature created": | |
return str(signed_message) | |
else: | |
F.message.value = message | |
F.passphrase.value = '' | |
npyscreen.notify_confirm( | |
"Phrase de passe incorrecte !", | |
title="Erreur" | |
) | |
HELP_MSG = """\ | |
Déchiffrer (et vérifier si besoin) : 'gpg --decrypt --verify' | |
Vérifier : 'gpg --verify'""" | |
def help_msg(): | |
humanfriendly.terminal.show_pager(HELP_MSG) | |
def main(): | |
actions = { | |
"Chiffrer et signer": encrypt_and_sign, | |
"Chiffrer": encrypt, | |
"Signer": sign, | |
"Aide": help_msg | |
} | |
action_name = humanfriendly.prompts.prompt_for_choice( | |
sorted(list(actions.keys())) | |
) | |
if action_name == "Aide": | |
help_msg() | |
exit(0) | |
print(chr(27) + "[2J") | |
gpg = gnupg.GPG() | |
public_keys = gpg.list_keys() | |
if not public_keys: | |
print("No public key found. Aborting.") | |
exit(1) | |
action_function = actions[action_name] | |
try: | |
print(npyscreen.wrapper_basic(action_function)) | |
except KeyboardInterrupt: | |
pass | |
exit(0) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment