Skip to content

Instantly share code, notes, and snippets.

@rezemika
Last active July 24, 2018 21:03
Show Gist options
  • Save rezemika/8f45485b3a9c6cfe31920e6ee356891f to your computer and use it in GitHub Desktop.
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
"""
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