Last active
September 20, 2025 14:55
-
-
Save faretek1/cefb8b3e1d8707a331154c9fb169ad19 to your computer and use it in GitHub Desktop.
utility script i made that lets you turn strings into fernet keys, generate string-fernet keys, and encrypt/decrypt data with the default key (`AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA`), all from a CLI
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
import warnings | |
import argparse | |
from cryptography.fernet import Fernet | |
from secrets import token_urlsafe | |
from base64 import urlsafe_b64encode | |
from pathlib import Path | |
__file_path__ = Path(__file__).resolve() | |
__pwd__ = __file_path__.parent | |
save_path = __pwd__ / "faretek's fernet-string.py key.txt" | |
_key = save_path.read_text() if save_path.exists() else 'A' * 32 | |
def str_2_key(gen: str) -> bytes: | |
if (length := len(gen)) < 32: | |
warnings.warn(f"Short key length {length}") | |
gen = gen.zfill(32) | |
elif length > 32: | |
warnings.warn(f"Long key length {length}") | |
gen = gen[:32] | |
return urlsafe_b64encode(gen.encode()) | |
fernet = Fernet(str_2_key(_key)) | |
def main(): | |
class Args(argparse.Namespace): | |
command: str | |
content: str | |
native: bool | |
parser = argparse.ArgumentParser(epilog=f"KEY={_key!r}") | |
if command := parser.add_subparsers(dest="command"): | |
if encrypt := command.add_parser("e", help="encrypt"): | |
encrypt.add_argument("content") | |
if decrypt := command.add_parser("d", help="decrypt"): | |
decrypt.add_argument("content") | |
if gen := command.add_parser("g", help="generate key"): | |
... | |
if set_key := command.add_parser("s", help="set key"): | |
set_key.add_argument("content", help="new key") | |
args = parser.parse_args(namespace=Args()) | |
match args.command: | |
case "e": | |
print(fernet.encrypt(args.content.encode()).decode()) | |
case "d": | |
print(fernet.decrypt(args.content.encode()).decode()) | |
case "g": | |
print(token_urlsafe(32)) | |
case "s": | |
print(f"Replacing {_key!r} with {args.content!r}") | |
save_path.write_text(args.content) | |
case _: | |
parser.print_help() | |
if __name__ == "__main__": | |
main() |
This should be changed for clarity:
fernet.generate_key()
-> Fernet.generate_key()
The return type of gen_keystr could be str or bytes, which should be changed. I recommend just using secrets.token_urlsafe(32)[:32]
, which always produces a csprng generated string of base64urlsafe of length 32. (The random module normally produces random numbers which can be predicted)
I would also recommend making it so that the key can be changed via a cli argument.
oops, didnt notice the keystr thibg
ill do that, ok
you should use secrets.token_urlsafe for secure pseudorandomness
i implemented that in the version i put in scratchattach. I also have a separate updated version somewhere which uses secrets too. I will update this gist then
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
i may be obsessed with argparse