From 0ee61fed3474661dd2111b33c241d6465a7cd3c6 Mon Sep 17 00:00:00 2001 From: Eli Ribble Date: Mon, 6 Nov 2023 11:52:48 -0700 Subject: [PATCH] Add extremely naive implementations of boxing and unboxing a message. I took the 'box' term from some other project. --- gongor/aegis.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/gongor/aegis.py b/gongor/aegis.py index ee8488c..091f9bd 100644 --- a/gongor/aegis.py +++ b/gongor/aegis.py @@ -1,13 +1,47 @@ import argparse +import os from pathlib import Path import subprocess from cryptography import x509 from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.ciphers import aead from cryptography.hazmat.primitives.serialization import pkcs12 from cryptography.hazmat.primitives.asymmetric import ec, ed25519, padding MAX_HUMAN_AGE = 365 * 200 +def box(): + "Take a message, put it in a box, encrypt the contents using a public key." + parser = argparse.ArgumentParser() + parser.add_argument("aegis_cert_pem", type=Path, help="The file for the PEM-encoded aegis public cert.") + parser.add_argument("message", type=Path, help="The file containing the message to box.") + parser.add_argument("output", type=Path, help="The path to the file where the output will go.") + args = parser.parse_args() + + with open(args.aegis_cert_pem, "rb") as f: + certificate = x509.load_pem_x509_certificate( + data=f.read(), + ) + with open(args.message, "rb") as f: + data = f.read() + + aad = b"authenticated but unencrypted data" + key = aead.ChaCha20Poly1305.generate_key() + with open("encryption.key", "wb") as f: + f.write(key) + print("Wrote encryption key to 'encryption.key'") + chacha = aead.ChaCha20Poly1305(key) + nonce = os.urandom(12) + with open("nonce", "wb") as f: + f.write(nonce) + print("Wrote nonce to 'nonce'") + ct = chacha.encrypt(nonce, data, aad) + with open(args.output, "wb") as f: + f.write(ct) + print(f"Wrote encrypted message to '{args.output}'") + + + def generate(): print("Please name this aegis. You can call it anything. Frequently people use their legal name.") name = input("Name? ") @@ -73,3 +107,32 @@ def validate(): ) print("Signature is valid") +def unbox(): + "Take a message in a box, use a key, open the box, get the message." + parser = argparse.ArgumentParser() + parser.add_argument("aegis_key_pem", type=Path, help="The file for the PEM-encoded aegis key.") + parser.add_argument("ciphertext", type=Path, help="The file containing the boxed ciphertext.") + parser.add_argument("output", type=Path, help="The path to the file where the output will go.") + parser.add_argument("-p", "--password", help="The password to use to open the key file.") + args = parser.parse_args() + + with open(args.aegis_key_pem, "rb") as f: + private_key = serialization.load_pem_private_key( + data=f.read(), + password=args.password.encode("UTF-8"), + ) + with open(args.ciphertext, "rb") as f: + ciphertext = f.read() + aad = b"authenticated but unencrypted data" + + with open("encryption.key", "rb") as f: + key = f.read() + with open("nonce", "rb") as f: + nonce = f.read() + + chacha = aead.ChaCha20Poly1305(key) + message = chacha.decrypt(nonce, ciphertext, aad) + with open(args.output, "wb") as f: + f.write(message) + print(f"Wrote unboxed message to '{args.output}'") + diff --git a/pyproject.toml b/pyproject.toml index c3b3185..74c4918 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ aegis-generate = "gongor.aegis:generate" aegis-sign = "gongor.aegis:sign" aegis-validate-signature = "gongor.aegis:validate" aegis-box = "gongor.aegis:box" -aegis-unbox = "gongor.cipher:unbox" +aegis-unbox = "gongor.aegis:unbox" [build-system] requires = ["setuptools >= 61.0.0"]