{"id":21536670,"url":"https://github.com/kartmaan/filecrypt","last_synced_at":"2025-06-15T22:14:05.339Z","repository":{"id":159237359,"uuid":"634516120","full_name":"Kartmaan/filecrypt","owner":"Kartmaan","description":"Python script to encrypt and decrypt files","archived":false,"fork":false,"pushed_at":"2025-05-29T12:13:10.000Z","size":170,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-29T13:42:12.612Z","etag":null,"topics":["aes","aes-128","argparse","argparser","command","command-line","cryptography","cryptography-library","cryptography-tools","decryption","encryption","encryption-decryption","fernet","files","script","sha-256"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kartmaan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-04-30T11:38:55.000Z","updated_at":"2025-05-29T12:13:15.000Z","dependencies_parsed_at":"2024-12-01T18:24:40.456Z","dependency_job_id":"19108078-bdbc-4f21-932d-cd35c073989b","html_url":"https://github.com/Kartmaan/filecrypt","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Kartmaan/filecrypt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kartmaan%2Ffilecrypt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kartmaan%2Ffilecrypt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kartmaan%2Ffilecrypt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kartmaan%2Ffilecrypt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kartmaan","download_url":"https://codeload.github.com/Kartmaan/filecrypt/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kartmaan%2Ffilecrypt/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260059507,"owners_count":22953055,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aes","aes-128","argparse","argparser","command","command-line","cryptography","cryptography-library","cryptography-tools","decryption","encryption","encryption-decryption","fernet","files","script","sha-256"],"created_at":"2024-11-24T03:20:52.544Z","updated_at":"2025-06-15T22:14:05.332Z","avatar_url":"https://github.com/Kartmaan.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"- [Filecrypt](#filecrypt)\n  - [Compatibility](#compatibility)\n  - [How to use it](#how-to-use-it)\n- [Commands](#commands)\n  - ['encrypt' command](#encrypt-command)\n    - [overwrite option](#overwrite-option)\n    - [Examples](#examples)\n      - [**Method 1** : By generating a random filekey in the current folder](#method-1--by-generating-a-random-filekey-in-the-current-folder)\n      - [**Method 2** : By using a filekey already present in the current folder](#method-2--by-using-a-filekey-already-present-in-the-current-folder)\n      - [**Method 3** : By using a password and optionally a salt value](#method-3--by-using-a-password-and-optionally-a-salt-value)\n        - [Without salt](#without-salt)\n        - [With salt](#with-salt)\n  - ['decrypt' command](#decrypt-command)\n    - [Examples](#examples-1)\n      - [**Method 1** : By using a filekey present in the current folder](#method-1--by-using-a-filekey-present-in-the-current-folder)\n      - [**Method 2** : By using a password and a salt](#method-2--by-using-a-password-and-a-salt)\n  - ['install' command](#install-command)\n    - [Example](#example)\n  - ['salt' command](#salt-command)\n    - [Example](#example-1)\n  - ['psw' command](#psw-command)\n    - [Example](#example-2)\n  - ['read' command](#read-command)\n    - [Example](#example-3)\n  - ['create' command](#create-command)\n    - [Example](#example-4)\n  - ['timestamp' command](#timestamp-command)\n    - [Example](#example-5)\n      - [Method 1 : By using a file encrypted with a filekey](#method-1--by-using-a-file-encrypted-with-a-filekey)\n      - [Method 2 : By using a file encrypted with a password and a salt](#method-2--by-using-a-file-encrypted-with-a-password-and-a-salt)\n  - ['clean' command](#clean-command)\n    - [Example](#example-6)\n  - ['delete' command](#delete-command)\n    - ['shuffle' option](#shuffle-option)\n    - [Examples](#examples-2)\n  - ['zip' command](#zip-command)\n    - ['delete' option](#delete-option)\n    - [Examples](#examples-3)\n  - ['unzip' command](#unzip-command)\n    - [Example](#example-7)\n- [Some technical details](#some-technical-details)\n  - [What's Fernet ?](#whats-fernet-)\n  - [What level of security?](#what-level-of-security)\n  - [Key and token](#key-and-token)\n    - [Key](#key)\n    - [Token](#token)\n  - [Script SAFE\\_MODE](#script-safe_mode)\n\n# Filecrypt\n![filecrypt_logo](https://github.com/user-attachments/assets/5a178628-cb63-41b5-ae31-07195d5673ff)\n\nThis Python script encrypts/decrypts files located in the script's current folder. The program is based on **Fernet**, an implementation of the AES-128 algorithm.\n\n\u003e For security reasons, the script can only be placed in a non-sensitive area of the system, and can only access its current folder. If the script is placed in a sensitive area, SAFE_MODE is activated, preventing the call of any file-modifying function (see 'Some technical details' section for more information).\n\n## Compatibility\nThe script has been tested on **Windows** and **Linux**\n\n## How to use it\nTo use this script, simply :\n1. Place this script (*or a copy*) in the folder containing the files to be encrypted or decrypted.\n2. Go to this folder from the terminal.\n3. Call the script followed by the desired command. For example: \n\n    `C:\\Users\\Bob\\Pictures\u003e python filecrypt.py encrypt image.jpg -ow`\n\nFor a reminder of commands in the script: `python filecrypt.py --help` \n\n# Commands\n## 'encrypt' command\nEncrypts a file present in the current folder using three different methods :\n1. By generating a random filekey in the current folder\n2. By using a valid filekey already present in the current folder\n3. By using a password and optionally a salt value\n\nThese three methods are mutually exclusive, but **must** include the name of the file to be encrypted and the `overwrite` option.\n\n### overwrite option\n- `-ow` / `--overwrite` : the file will be overwritten by its encrypted version (*in the case of an image file for example, it will therefore become corrupted*)\n- `-c` / `--copy` : The plaintext file will be copied before being overwritten by its encrypted version.\n\n### Examples\n#### **Method 1** : By generating a random filekey in the current folder\nLet's suppose we want to encrypt a file named `psw.txt` by overwriting it :\n\n`python filecrypt.py encrypt psw.txt -ow`\n\nSame thing, but first copy the file to the current folder before encrypting it.\n\n`python filecrypt.py encrypt psw.txt -c`\n\nA filekey named `filekey.key` will be created in the current folder.\n\n\u003e **Note 1**: For standardization reasons and to avoid unfortunate modifications to a .txt format, all generated filekeys are in .`key` format.\n\n\u003e **Note 2**: The filekey **doesn't contain the ciphertext but only the secret key**. It should be kept in a safe place.\n\n#### **Method 2** : By using a filekey already present in the current folder\nThe `-f`/`--filekey` option lets us specify the filekey to be used\n\n`python filecrypt.py encrypt psw.txt -f filekey.key -ow`\n\n#### **Method 3** : By using a password and optionally a salt value\n\nFernet can also generate keys from : \n- a password : `-p` / `--password`\n- and a salt value : `-s` / `--salt`\n\n##### Without salt\nWhen no salt value is entered, the script will automatically generate one in the form of 16 random bytes (generated by `os.urandom()`). This value will be encoded in base64 urlsafe so that it can be easily displayed to the user and kept in a safe place.\n\n\u003e **Caution**: It's crutial to keep both the password AND the salt in a safe place. If the file is encrypted again without specifying a salt value, a new one will be randomly generated, making the old one obsolete. If the user attempts to encrypt a file in overwrite mode without specifying a salt, a confirmation message will be displayed.  \n\nLet's say we have an image named `image.jpg` in the current folder and we want to encrypt it with the password: `notastrongpsw` (*an honest password*): \n\n`python filecrypt.py encrypt image.jpg -p -ow`\n\nA confidential input field appears to receive the password:\n\n`\u003e Password: *************`\n\nSince no salt has been entered, the value will be generated automatically. The file has been encrypted inplace and the random generated salt is displayed on the terminal :\n\n```\n- - - - SALT (KEEP IT SAFE) - - - - -\nzhWYYqNubPOb0aH_AAGV3Q==\n- - - - - - - - - - - - - - - - - - -\n```\nWhen the time comes to decrypt the file, the password AND this salt will be required.\n\n\u003e **Note**: When the user attempts overwriting encryption with a password and without entering a salt (random generation), a confirmation message is displayed to the user.\n\n##### With salt\nNow let's say we want to encrypt the same file, but this time with a salt we already own. \n\n`python filecrypt.py encrypt image.jpg -p -s -ow`\n\nA first confidential input field appears to receive the password:\n\n`\u003e Password: *************`\n\nAnd a second one for the salt :\n\n`\u003e Salt: ************************`\n\n\u003e **Note** : It's recommended to use salt values generated directly from this script to ensure compliance with standardization. For example, using the `salt` command.\n\n## 'decrypt' command\nDecrypts a file present in the current folder using two different methods :\n1. By using a filekey present in the current folder\n2. By using a known password and a salt\n\n### Examples\n#### **Method 1** : By using a filekey present in the current folder\n\nDecryption of a file named `psw.txt` using a filkey named `filekey.key` present in the current folder :\n\n`python filecrypt.py decrypt psw.txt filekey.key`\n\n\u003e **Note** : For standardization reasons and to avoid unfortunate modifications to a .txt format, all filekeys must be in `.key`.\n\n#### **Method 2** : By using a password and a salt\nThis method is used to decrypt a file that has been encrypted using a password and a salt value known to the user.\n\nHere we decrypt the file `image.jpg`, encrypted in our example in the 'encrypt command' section with the password `notastrongpsw` and the salt `zhWYYqNubPOb0aH_AAGV3Q==` :\n\n`python filecrypt.py decrypt image.jpg -p -s`\n\nA first confidential input field appears to receive the password:\n\n`\u003e Password: *************`\n\nAnd a second one for the salt :\n\n`\u003e Salt: ************************`\n\n\u003e **Note**: Unlike the `encrypt` command, where the `--salt` option was optional for encrypting with a password, here, the `--password` AND `--salt` options must both be set.\n\n## 'install' command\nInstalls all non built-in modules and their dependencies via the pip command.\n\n\u003e Note: When the script is launched, if the import of a non built-in module encounters an ImportError, a request is made to the user to automatically install the missing modules.\n\n### Example\n`python filecrypt.py install`\n\n## 'salt' command\nGenerates and print a b64-urlsafe salt value that can be used to encrypt files.\n\n### Example\n```\npython filecrypt.py salt\n\u003e rxOvfSGn14oB3bBqz8lfvQ==\n```\n\n## 'psw' command\nGenerates a strong password and print it, so that it can be used to encrypt files. By default, the password is 12 characters long, made up of : \n- Upper letters\n- Lower letters \n- Digits\n- Symbols\n\nTo avoid syntax conflicts in the terminal, generated passwords don't include symbols. To compensate for this, the length of the password word is set to 17, in order to obtain an entropy greater than 100 bits. \n\n\u003e **Password entropy** \n\u003e \n\u003e In information theory, entropy measures the degree of uncertainty (*or randomness*) associated with a random variable. The higher the entropy, the more unpredictable the variable. Applied to passwords, entropy quantifies the difficulty for an attacker to guess the password. The password entropy value, expressed in bits, is defined by the following formula :\n\u003e  \n\u003e $E = L \\cdot \\log_{2}(R)$\n\u003e \n\u003e Where L is the length of the password and R is the possible range of character types in the password (In other words, the number of possible states for each character).\n\u003e\n\u003e Typically, a strong or high-entropy password is at least 80 bits. Anything less than 50 bits is relatively easy for a machine to crack, for example, a password with a length of 6 and composed entirely of numbers has an entropy of 20, which is easily cracked by brute force. In our case we have 94 possible states for each character of the password :\n\u003e - 26 upper letters\n\u003e - 26 lower letters\n\u003e - 10 digits\n\u003e - 32 symbols\n\u003e \n\u003e Applying the formula for a password length of 17, we have :\n\u003e\n\u003e $E = 17 \\cdot \\log_{2}(94) = 111.42$\n\u003e\n\u003e The passwords generated by the command will therefore have an entropy of slightly more than **111 bits**, which satisfies most safety recommendations.\n\n### Example\n```\npython filecrypt.py psw\n\u003e rv1rX\\L!4m=v=[u0c\n```\n\n## 'read' command\nDisplays the Base64 code present in a filekey\n\n### Example\n```\npython filecrypt.py read filekey.key\n\u003e MWpYeBrqiaVVZIOZrJFntiF2K0_ZYZZ2eCxBQ1_CuAI=\n```\n\n## 'create' command\nCreates a filekey in the current folder by providing the desired name and the key (*base64 urlsafe*). \n\n**Practical example**: after encrypting a file, for security reasons we don't want to keep the filekey on the computer, so we can extract its key using the `read` command, copy/paste it somewhere else (or even copy it onto paper) and delete the filekey. When we want to decrypt this file, the filekey can be recreated using the `create` command.\n\n### Example\nCreate a file named 'secretkey' :\n\n`python filecrypt.py create secretkey`\n\nA confidential input field appears to receive the key:\n\n`\u003e Key: ***************************`\n\nThe command creates a filekey in the current folder, named `secret.key`, with the supplied key.\n\n\u003e**Note** : You don't need to specify the filekey extension, as it will automatically be saved in .key format for standardization reasons. Only the name is required.\n\n## 'timestamp' command\nThis command extracts the timestamp of a Fernet token (*from an encrypted file*), i.e. the timestamp at which the file was encrypted. To do this, the command needs the name of the encrypted file in the current folder as well as the filekey used to encrypt it or the password and salt.\n\n### Example\nHere are examples of the two different methods: \n1. By using a file encrypted with a filekey\n2. By using a file encrypted with a password and a salt\n\nHere, we want to extract the timestamp from an encrypted file named `image.jpg`\n\n#### Method 1 : By using a file encrypted with a filekey\n`python filecrypt.py timestamp image.jpg -f filekey.key`\n\n#### Method 2 : By using a file encrypted with a password and a salt\n`python filecrypt.py timestamp image.jpg -p`\n\n\u003e **Note**: It's not necessary to add the `--salt` / `-s` option, since if the `--password` option is enabled, a salt value will always be requested. \n\nA first confidential input field appears to receive the password:\n\n`\u003e Password: *************`\n\nAnd a second one for the salt :\n\n`\u003e Salt: ************************`\n\n**Output** :\n```\n- - - - - - - - - - - - - - - - - - - -\nimage.jpg was encrypted at : 2024-12-01 18:35:59\nSince 2 hours, 9 minutes, 3 seconds\nTimestamp : 1733074559\n- - - - - - - - - - - - - - - - - - - -\n```\n\n## 'clean' command\nThe command replaces the current clipboard with an empty entry to reduce the risk of confidential data such as passwords or salt values leaking out, as the user may eventually have to copy/paste these values.\n\n### Example\n```\npython filecrypt.py clean\n\u003e The clipboard has been erased\n```\n\n## 'delete' command\nThe command is used to **securely delete** a file from the current folder. To achieve this, before being removed by the `os.remove` method, the file is blindly encrypted several times (*without the keys being communicated*) with a new random key on each pass. After this, the file is truncated to its original size.\n\n\u003e **Secure deletion**: Secure deletion most often means overwriting the contents of a file several times with random data before deleting it, making recovery much more difficult. This involves different procedures for Linux and Windows. While Linux has a special command for this kind of operation (`shred`), Windows requires the installation of a specific Microsoft utility (`sdelete`). To compensate for this and preserve the script's portability and lightness, the command uses the encryption functions already present in the script to make the file unreadable before deletion, even for the user.\n\n\u003e **Note**: All deletions must be explicitly confirmed by the user, but filekeys are treated in a special way: the user is asked to ensure that he has kept a copy of the key in a safe place.\n\n\u003e **Encryption passes**: The file size will temporarily increase with each encryption pass. Even if the file returns to its initial size after the truncation phase, setting the number of passes to 2 seems a more than acceptable compromise, particularly for large files.\n\n### 'shuffle' option\nOptionally, file bytes can also be shuffled just before the deletion by activating the `-s` / `--shuffle` option.\n\n\u003e **Note**: The operation can be long for large files (approx. 2 min on a standard PC for a 100MB file).\n\n### Examples\nLet's suppose we want to delete the file 'image.jpg' in the current folder :\n```\npython filecrypt.py delete image.jpg\n\u003e You are about to irreversibly delete the file 'image.jpg'\n\u003e File size: 39.64 ko\n\u003e From: C:\\Users\\Bob\\Code\\image.jpg\n\u003e Do you confirm this operation? (y/n): y # user input\n\u003e Encryption...\n\u003e Pass 1/2 completed.\n\u003e Pass 2/2 completed.\n\u003e Resizing...\n\u003e 'brain.jpg' has been deleted.\n```\nSame example with the `-s` \\ `--shuffle` option:\n```\npython filecrypt.py delete image.jpg -s\n\u003e You are about to irreversibly delete the file 'image.jpg'\n\u003e File size: 39.64 ko\n\u003e From: C:\\Users\\Bob\\Code\\image.jpg\n\u003e Do you confirm this operation? (y/n): y # user input\n\u003e \u003e Encryption...\n\u003e Pass 1/2 completed.\n\u003e Pass 2/2 completed.\n\u003e Resizing...\n\u003e Shuffling...\n\u003e 'filekey.key' has been deleted.\n```\n\n## 'zip' command\nThe command is used to compress files or folders in the current folder into `.zip` format. The command may be useful if the user wants to encrypt an entire folder.\n\n### 'delete' option\nThe `-d` / `--delete` option securely deletes the original file/folder after compression, after user confirmation.\n\n### Examples\nLet's suppose we want to zip the file 'image.jpg'.\n```\npython filecrypt.py zip image.jpg\n\u003e Zipping...\n\u003e Added : image.jpg\n\u003e 'brain.jpg' compressed successfully.\n```\nA zip archive named 'image.zip' is created in the current folder. Since the `--delete` option isn't enabled, the original file remains in the current folder.\n\nNow let's suppose we want to compress a folder called 'secret' with this tree structure.\n\n```\nsecret/\n├─ fold1/\n│  ├─ psw.txt\n│  ├─ salt.txt\n├─ fold2/\n│  ├─ ciphertext.txt\n│  ├─ key.txt\n\n```\nWe also want this folder to be securely deleted after compression, so we activate the `-d` / `--delete` option :\n\n```\npython filecrypt.py zip secret -d\n\u003e Compression will delete the 'secret' folder.\n\u003e From: C:\\Users\\Bob\\Code\\secret\n\u003e Do you confirm the operation ? (y/n): y # User input\n\u003e Zipping...\n\u003e Added: secret\\fold1\\psw.txt\n\u003e Added: secret\\fold1\\salt.txt\n\u003e Added: secret\\fold2\\ciphertext.txt\n\u003e Added: secret\\fold2\\key.txt\n\u003e Deleting files...\n\u003e File deletion 1/4\n\u003e File deletion 2/4\n\u003e File deletion 3/4\n\u003e File deletion 4/4\n\u003e 'secret' compressed successfully. \n```\n\n## 'unzip' command\nThe command unzips zip archives in the current folder.\n\n### Example\nUnzipping the 'secret.zip' archive :\n```\npython filecrypt.py unzip secret.zip\n\u003e Unzipping secret.zip...\n\u003e secret.zip extracted successfully.\n```\n\n# Some technical details\n## What's Fernet ?\nFernet (from `cryptography` module) is an implementation of the AES algorithm using a 128-bit key. Fernet offers an abstraction that allows developers to encrypt and decrypt data without having to worry about the complexities of implementing AES and other security mechanisms.\n\n## What level of security?\n* **AES** : Data is encrypted using AES (**A**dvanced **E**ncryption **S**tandard), a symmetrical encryption algorithm that encrypts data in blocks of a fixed size.\n\n\n* **128-bits** : This is the size of the secret key. It offers a high level of security, making brute-force attacks extremely difficult ($2^{128}$ possible combinations).\n\n\n* **CBC mode** : The **C**ipher **B**lock **C**haining links the encryption of each block to the previous one. Each block of plaintext data is XOR'd with the preceding encrypted block before being encrypted. So if a bit is modified in the ciphertext, this will affect not only the decryption of this block, but also of all subsequent blocks.\n\n\n* **Initialisation Vector (IV)** : Since the first block has no precedent, it's subjected to a random initialization vector: a series of randomly generated bits of the same size as the block, which acts as the “previous block”. This randomness masks repetitions in the code, even if the plain text begins with the same data in several sessions.\n\n\n* **Crypto secure RNG** : The secret key and the initialisation vector are randomly generated using `os.urandom()`, which relies on the operating system's entropy (*harware interupts, network data, running processes...*) to make generation as unpredictable as possible (CSPRNG).\n\n\n* **Padding PKCS7** : This technique ensures that the data to be encrypted always occupies an integer number of blocks, as required by the AES algorithm. To do this, the function adds padding bytes to the end of the plaintext data if it isn't a multiple of the desired block size.\n\n\n* **HMAC** : **H**ash-based **M**essage **A**uthentication **C**ode is a cryptographic function used to verify the integrity and authenticity of a message (Token), it's calculated on the basis of the encrypted data. **If the integrity of the encrypted file is compromised, it becomes impossible to decrypt it**.\n\n\n* **SHA-256** : A cryptographic hash function that produces a 256-bit hash value. It's used to generate the **M**essage **A**uthentication **C**ode.\n\n\n* **Password \u0026 Salt** : Data can be encrypted using a user-memorable password, which is **derived** to be 128 bits long key. This password is also “mixed” with a sequence of random bits called “**salt**” before being hashed. The `psw` command (*see above*) allows the user to generate secure passwords.\n\n\n* **Key derivation** : principle of using a single secret key (*often called the master key, represented here by our password*) to generate several different keys of any desired length (*using an algorithm, PBKDF2 in our case*). To create these new keys, we generally use cryptographic hash functions. These functions take as input the master key (*our password*) and other information, such as the salt, to produce as output a unique and difficult-to-invert value, which will be our new key. This method has several advantages:\n  - **Security** : By having several derived keys, we limit the risks if one key is compromised. If an attacker discovers one of the derived keys, he won't have access to the master key and therefore to the other keys\n  - **Flexibility** : We can generate specific keys for different operations, allowing to tailor our security system to our needs.\n  - **Efficiency** : Instead of storing and managing several independent keys, we can store a single master key and generate the other keys as needed.\n  - **Practicality** : Since we can't decently ask the user to enter a memorable 128-bit password from memory, key derivation overcomes this problem by matching the inserted password to the required security standards.\n\n\n* **Salt** : Imagine you want to preserve a dish with a unique taste. To make it inimitable, you can add a pinch of specific salt to your recipe. This salt, unique to your dish, will make it impossible for anyone else to reproduce exactly the same taste using the same basic ingredients. In cryptography, the “salt” plays a similar role. It's a random string of characters added to a password before it's hashed. This hash, i.e. the transformation of the password into a fixed-length string of characters, is used to store the password securely.\n\n\n\u003e \u003cspan style=\"color:red\"\u003e\u003cb\u003eSafety reminder\u003c/b\u003e\u003c/span\u003e : If the password alone isn't enough to decrypt a message, that doesn't mean it shouldn't be kept safe. Although the attacker cannot decrypt the message directly without salt, he can use the password to derive the key, and with the derived key, the attacker can try to guess the salt by brute force. So **even without salt, an attacker in possession of the password has a significant advantage** and can, with relatively modest effort, compromise the confidentiality of encrypted data. So **the password AND the salt must be treated with the same care**.\n\n## Key and token\nThe key and the token are two key concepts used by Fernet to encrypt and decrypt data.\n\n### Key\nA 256-bit key (32 bytes), randomly generated and used to encrypt and decrypt data. The key is divided into two parts: an **encryption key** and a **signing key**, each 128 bits (16 bytes) long. This division is at the heart of Fernet's cryptographic mechanism, which combines encryption and authentication.\n\n* **Key format** : A base64url key with the following fields:\n  * **Signing-key, (128 bits)** : used to calculate cryptographic authentication (HMAC) on the token (*the encrypted data*). Indeed, token authentication is based not only on the ciphertext (*and other metadata*), but also on the signing-key. This ensures that the person decrypting the file actually owns the original key.\n\n  * **Encryption-key, (128 bits)** : used by the AES algorithm in CBC (Cipher Block Chaining) mode to transform plaintext data into ciphertext data.\n  \n  So, if the encryption-key part is modified, decryption becomes impossible, and if the signing-key part is modified, the token's HMAC is no longer valid, and here again, decryption is impossible.\n\n### Token\nA data container encapsulating everything needed to decrypt the data or verify its integrity.\n\n* **Token format** : Coded in base64 urlsafe, it contains the following fields:\n\n  * **Version, (8 bits)** : denotes which version of the format is being used by the token. Currently there is only one version defined, with the value 128 (0x80)\n\n  * **Timestamp, (64 bits)** : a 64-bit unsigned big-endian integer. It records the number of seconds elapsed between January 1, 1970 UTC and the time the token was created\n\n  * **Initialisation Vector (IV), (128 bits)** : the 128-bit Initialization Vector (see above) used in AES encryption and decryption of the Ciphertext. When generating new fernet tokens, the IV must be chosen uniquely for every token. With a high-quality source of entropy, random selection will do this with high probability.\n\n  * **Ciphertext, variable length, (multiple of 128 bits)** : has variable size, but is always a multiple of 128 bits, the AES block size. It contains the original input message, padded and encrypted.\n\n  * **HMAC, (256 bits)** : (**H**ash-based **M**essage **A**uthentication **C**ode) used to authenticate the token, i.e. the header (*version and timestamp*), the ciphertext and the IV. This authentication key is calculated using the signing-key as the secret key. Thus, HMAC ensures not only integrity, but also authenticity.\n\n## Script SAFE_MODE\nThe script is able to modify or even deleting files/folders, so its use is controlled to reduce the risk of inadvertent manipulation. To do this, the script checks whether its location corresponds to a **sensitive area of the system**. If this is the case, SAFE_MODE mode is activated, preventing the call of file/folder modifying functions. In addition, the script can only access files/folder located in its current folder, in this way, even if the script is in a “safe” area of the system, it cannot reach a path outside its current folder.\n\n\u003e Zones considered “sensitive” depend on the user operating system and are defined in the `in_danger_zone` function.\n\nCommands **not accessible** in SAFE_MODE :\n- encrypt\n- decrypt\n- delete\n- zip\n- unzip\n- create\n\nCommands **still accessible** in SAFE_MODE :\n- install\n- salt\n- psw\n- read\n- timestamp\n- clean\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkartmaan%2Ffilecrypt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkartmaan%2Ffilecrypt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkartmaan%2Ffilecrypt/lists"}