Hướng dẫn python fernet encrypt file


View on Github

crypt.py

from cryptography.fernet import Fernet

def write_key[]:
    """
    Generates a key and save it into a file
    """
    key = Fernet.generate_key[]
    with open["key.key", "wb"] as key_file:
        key_file.write[key]

def load_key[]:
    """
    Loads the key from the current directory named `key.key`
    """
    return open["key.key", "rb"].read[]

def encrypt[filename, key]:
    """
    Given a filename [str] and key [bytes], it encrypts the file and write it
    """
    f = Fernet[key]
    with open[filename, "rb"] as file:
        # read all file data
        file_data = file.read[]
    # encrypt data
    encrypted_data = f.encrypt[file_data]
    # write the encrypted file
    with open[filename, "wb"] as file:
        file.write[encrypted_data]

def decrypt[filename, key]:
    """
    Given a filename [str] and key [bytes], it decrypts the file and write it
    """
    f = Fernet[key]
    with open[filename, "rb"] as file:
        # read the encrypted data
        encrypted_data = file.read[]
    # decrypt data
    decrypted_data = f.decrypt[encrypted_data]
    # write the original file
    with open[filename, "wb"] as file:
        file.write[decrypted_data]


if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser[description="Simple File Encryptor Script"]
    parser.add_argument["file", help="File to encrypt/decrypt"]
    parser.add_argument["-g", "--generate-key", dest="generate_key", action="store_true",
                        help="Whether to generate a new key or use existing"]
    parser.add_argument["-e", "--encrypt", action="store_true",
                        help="Whether to encrypt the file, only -e or -d can be specified."]
    parser.add_argument["-d", "--decrypt", action="store_true",
                        help="Whether to decrypt the file, only -e or -d can be specified."]

    args = parser.parse_args[]
    file = args.file
    generate_key = args.generate_key

    if generate_key:
        write_key[]
    # load the key
    key = load_key[]

    encrypt_ = args.encrypt
    decrypt_ = args.decrypt

    if encrypt_ and decrypt_:
        raise TypeError["Please specify whether you want to encrypt the file or decrypt it."]
    elif encrypt_:
        encrypt[file, key]
    elif decrypt_:
        decrypt[file, key]
    else:
        raise TypeError["Please specify whether you want to encrypt the file or decrypt it."]

crypt_password.py

import cryptography
from cryptography.fernet import Fernet
from cryptography.hazmat.primitives.kdf.scrypt import Scrypt

import secrets
import base64
import getpass


def generate_salt[size=16]:
    """Generate the salt used for key derivation, 
    `size` is the length of the salt to generate"""
    return secrets.token_bytes[size]


def derive_key[salt, password]:
    """Derive the key from the `password` using the passed `salt`"""
    kdf = Scrypt[salt=salt, length=32, n=2**14, r=8, p=1]
    return kdf.derive[password.encode[]]


def load_salt[]:
    # load salt from salt.salt file
    return open["salt.salt", "rb"].read[]


def generate_key[password, salt_size=16, load_existing_salt=False, save_salt=True]:
    """
    Generates a key from a `password` and the salt.
    If `load_existing_salt` is True, it'll load the salt from a file
    in the current directory called "salt.salt".
    If `save_salt` is True, then it will generate a new salt
    and save it to "salt.salt"
    """
    if load_existing_salt:
        # load existing salt
        salt = load_salt[]
    elif save_salt:
        # generate new salt and save it
        salt = generate_salt[salt_size]
        with open["salt.salt", "wb"] as salt_file:
            salt_file.write[salt]
    # generate the key from the salt and the password
    derived_key = derive_key[salt, password]
    # encode it using Base 64 and return it
    return base64.urlsafe_b64encode[derived_key]


def encrypt[filename, key]:
    """
    Given a filename [str] and key [bytes], it encrypts the file and write it
    """
    f = Fernet[key]
    with open[filename, "rb"] as file:
        # read all file data
        file_data = file.read[]
    # encrypt data
    encrypted_data = f.encrypt[file_data]
    # write the encrypted file
    with open[filename, "wb"] as file:
        file.write[encrypted_data]


def decrypt[filename, key]:
    """
    Given a filename [str] and key [bytes], it decrypts the file and write it
    """
    f = Fernet[key]
    with open[filename, "rb"] as file:
        # read the encrypted data
        encrypted_data = file.read[]
    # decrypt data
    try:
        decrypted_data = f.decrypt[encrypted_data]
    except cryptography.fernet.InvalidToken:
        print["Invalid token, most likely the password is incorrect"]
        return
    # write the original file
    with open[filename, "wb"] as file:
        file.write[decrypted_data]
    print["File decrypted successfully"]


if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser[description="File Encryptor Script with a Password"]
    parser.add_argument["file", help="File to encrypt/decrypt"]
    parser.add_argument["-s", "--salt-size", help="If this is set, a new salt with the passed size is generated",
                        type=int]
    parser.add_argument["-e", "--encrypt", action="store_true",
                        help="Whether to encrypt the file, only -e or -d can be specified."]
    parser.add_argument["-d", "--decrypt", action="store_true",
                        help="Whether to decrypt the file, only -e or -d can be specified."]

    args = parser.parse_args[]
    file = args.file

    if args.encrypt:
        password = getpass.getpass["Enter the password for encryption: "]
    elif args.decrypt:
        password = getpass.getpass["Enter the password you used for encryption: "]

    if args.salt_size:
        key = generate_key[password, salt_size=args.salt_size, save_salt=True]
    else:
        key = generate_key[password, load_existing_salt=True]

    encrypt_ = args.encrypt
    decrypt_ = args.decrypt

    if encrypt_ and decrypt_:
        raise TypeError["Please specify whether you want to encrypt the file or decrypt it."]
    elif encrypt_:
        encrypt[file, key]
    elif decrypt_:
        decrypt[file, key]
    else:
        raise TypeError["Please specify whether you want to encrypt the file or decrypt it."]

Chủ Đề