Skip to content

Instantly share code, notes, and snippets.

@mgrabovsky
Last active May 5, 2021 18:28
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgrabovsky/85b57d2601fd1c2b58ab7ec81de0ecfc to your computer and use it in GitHub Desktop.
Save mgrabovsky/85b57d2601fd1c2b58ab7ec81de0ecfc to your computer and use it in GitHub Desktop.
A basic file encryption utility in Python using the cryptography.io library. Uses ChaCha20Poly1305 for authenticated encryption and PBKDF2 with SHA-2 to derive a secure key from a password.
#!/usr/bin/env python
import argparse
from cryptography import exceptions
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers.aead import ChaCha20Poly1305
from cryptography.hazmat.primitives.hashes import SHA256
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from getpass import getpass
import os
import sys
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('filename', metavar='file')
parser.add_argument('-d', '--decrypt', action='store_true')
args = parser.parse_args()
backend = default_backend()
password = bytes(getpass(), encoding='utf-8')
# Decryption
if args.decrypt:
with open(args.filename, 'rb') as f:
token = f.read()
salt = token[:16]
nonce = token[16:28]
ciphertext = token[28:]
kdf = PBKDF2HMAC(salt=salt, length=32, iterations=100000,
algorithm=SHA256, backend=backend)
key = kdf.derive(password)
cipher = ChaCha20Poly1305(key)
try:
plaintext = cipher.decrypt(nonce, ciphertext, None)
except exceptions.InvalidTag:
print('Error: Decryption failed', file=sys.stderr)
exit(1)
sys.stdout.buffer.write(plaintext)
# Encryption
else:
message = sys.stdin.buffer.read()
salt = os.urandom(16)
kdf = PBKDF2HMAC(salt=salt, length=32, iterations=100000,
algorithm=SHA256, backend=backend)
key = kdf.derive(password)
cipher = ChaCha20Poly1305(key)
nonce = os.urandom(12)
ciphertext = cipher.encrypt(nonce, message, None)
token = salt + nonce + ciphertext
with open(args.filename, 'wb') as f:
f.write(token)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment