{"id":22203881,"url":"https://github.com/interglobalmedia/encrypt-decrypt-files-python","last_synced_at":"2026-05-02T15:34:11.034Z","repository":{"id":196267830,"uuid":"695627496","full_name":"interglobalmedia/encrypt-decrypt-files-python","owner":"interglobalmedia","description":null,"archived":false,"fork":false,"pushed_at":"2023-09-24T12:06:20.000Z","size":29,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-30T03:43:44.580Z","etag":null,"topics":["chmod","chown","cli","fernet-encryption","gpg-encryption","macos","python3","symmetric-encryption"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/interglobalmedia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-09-23T18:36:55.000Z","updated_at":"2023-09-24T01:06:27.000Z","dependencies_parsed_at":null,"dependency_job_id":"ad65662f-6578-4957-a7dd-ea3e7c97b33f","html_url":"https://github.com/interglobalmedia/encrypt-decrypt-files-python","commit_stats":{"total_commits":10,"total_committers":1,"mean_commits":10.0,"dds":0.0,"last_synced_commit":"76e3ec2dc7b99ed166f3b33662a7024c93cf56b8"},"previous_names":["interglobalmedia/encrypt-decrypt-files-python"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interglobalmedia%2Fencrypt-decrypt-files-python","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interglobalmedia%2Fencrypt-decrypt-files-python/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interglobalmedia%2Fencrypt-decrypt-files-python/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/interglobalmedia%2Fencrypt-decrypt-files-python/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/interglobalmedia","download_url":"https://codeload.github.com/interglobalmedia/encrypt-decrypt-files-python/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245388748,"owners_count":20607163,"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":["chmod","chown","cli","fernet-encryption","gpg-encryption","macos","python3","symmetric-encryption"],"created_at":"2024-12-02T17:14:55.542Z","updated_at":"2026-05-02T15:34:06.000Z","avatar_url":"https://github.com/interglobalmedia.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Encrypting/Decrypting Files and Strings\n\n## Python vs Command Line (macOS)\n\nIn cybersecurity, we want to be as efficient and swift as possible when executing our tasks. In this scenario, I want to compare encrypting and decrypting files and strings in Python vs doing the same thing via the Command Line.\n\nFirst of all, in my `Python` ***approach*** to `encrypting` and `decrypting` a ***file***, I wanted to make sure that I `modularized` my `task functions`. So I ***created*** the ***following*** `files`:\n\n- create_key.py\n- get_key.py\n- encrypt_file.py\n- decrypt_file.py\n\nAs for `encrypting` and `decrypting` a `string`, I ***created*** the ***following*** `files`:\n\n- encrypt_string.py\n- decrypt_string.py\n\n***Now*** to ***break*** `things` ***down*** and ***explain*** `what` ***each*** `file` ***does***. I ***tried*** to ***create*** `file names` that ***describe*** the `individual tasks` they are ***responsible*** for. I call this `\"task modularization\"`.\n\nThe `create_key.py` file ***creates*** an `encryption key` ***using*** the `Python Fernet` ***symmetric encryption method***. It was ***created*** by `Google` and ***uses*** `128-bit AES keys`. `AES 128-bit encryption` in of ***itself*** is ***safe against*** `brute-force attacks`. ***The only*** `\"wildcard\"` is the ***safety*** of the `key`. I ***would say*** that ***using*** `symmetric encryption` is ***best when*** you are `encrypting` and `decrypting` ***for yourself*** and ***don't need*** to ***share*** the `key` ***with others*** for `successful completion` of the ***process***.\n\nThe `get_key.py` file's `task` is to ***load*** the `key` that has been `generated`. So ***for example***, I ***make*** the ***following*** `import statement` in the `decrypt_file.py`, `decrypt_string.py`, `encrypt_file.py`, `encrypt_string.py`:\n\n```python\nfrom get_key import load_key\n```\n\n***And*** I ***also make*** the ***following*** `import statement` for `Python Fernet` ***in all*** the `files` ***except for*** `get_key.py`:\n\n```python\nfrom get_key import load_key\n```\n\nAll `get_key.py` ***does*** is ***load*** the `key.key` file ***which contains*** the `encryption key` ***itself***, so ***importing*** `Fernet`, or ***anything else*** for ***that matter***, is ***not necessary***.\n\nThe ***difference between*** the `code` for `encrypting` and `decrypting` a ***file*** was ***minimal*** and ***therefore easy*** to ***set*** up ***modularly***. It was a ***bit trickier***, ***however***, with the ***creation*** of the `message_encrypt` and `message_decrypt` functions. ***There***, I ***had*** to ***make sure*** that the `string` which is `encrypted` is the ***same string*** that is then `decrypted`.\n\nIn the `encrypt_string.py` file, I ***had*** to ***make sure*** that I ***created*** a `local variable` ***inside*** the `message_encrypt` ***function*** that I ***would*** be ***able*** to `import` ***into the*** `decrypt_string.py` file and then ***use inside*** the `message_decrypt` ***function***. So:\n\n```python\n# store string in variable\nmessage = 'super secret message'\n# inside the message_encrypt function\n# encrypt data\nmessage_encrypt.message_encrypted = f.encrypt(message.encode())\n```\n\n`message_encrypt` is the ***name*** of the ***function***, and `message_encrypted` is the `variable name`. This ***made*** it ***possible*** to ***include*** the ***following*** `import statement` ***inside*** the `decrypt_string.py` file:\n\n```python\nfrom encrypt_string import message_encrypt\n```\n\n***And this*** then ***made it*** possible ***to add*** the ***following*** inside the `message_decrypt` function ***thereby linking*** the `encrypted message` ***created*** in `encrypt_string.py` to the `encrypted message` ***imported from*** the `encrypt_string.py` file into `decrypt_string.py`, which ***resulted in*** the ***successful***  `decryption` ***of the*** `encrypted message` (`string`):\n\n```python\nfrom encrypt_string import message_encrypt\n# inside the message_decrypt function\nmessage_encrypt.message_encrypted = f.decrypt(message_encrypt.message_encrypted.decode())\n```\n\nThe above ***prevents*** the ***following*** `error` ***from*** `taking place` in `Terminal` ***when running*** the ***string related*** files ***containing*** the `modularized functions`:\n\n```python\nFile \"/Users/mariacam/Development/cyber-projects/encrypt-decrypt-files-python/venv/lib/python3.11/site-packages/cryptography/fernet.py\", line 86, in decrypt\n    timestamp, data = Fernet._get_unverified_token_data(token)\n                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/Users/mariacam/Development/cyber-projects/encrypt-decrypt-files-python/venv/lib/python3.11/site-packages/cryptography/fernet.py\", line 119, in _get_unverified_token_data\n    raise InvalidToken\n```\n\n***Lastly***, it is ***important*** to ***note that*** in the `message_decrypt` ***function***, the `message` ***represented by*** `message_encrypt.message_encrypted` ***passed*** to the `f.decrypt()` method, is ***chained*** to the `decode()` method ***instead of*** the `encode()` method. ***Not only*** are we `decrypting` our `message`, but we ***also have*** to `decode` it, ***since*** it was `encoded` when `encrypted`. ***Now*** the `message` is just `\"plain text\"` as it was ***originally*** when ***first created***.\n\n## Using GnuPG to encrypt and decrypt strings and files via the Command Line\n\nThis was ***a lot*** of ***work***, right? A `programmatic approach` ***will always*** be ***more complex*** than `executing` the ***same task*** via the `Command Line`. And in `Cybersecurity`, we ***won't*** necessarily ***have*** the `luxury` or `even need` to `programmatically execute` ***such tasks***.\n\n***This*** is ***where*** `tools` ***such as*** `gnupg` ***come in***. `gnupg`, ***aka*** `gpg`, which ***stands for*** [GNU Privacy Guard](https://gnupg.org/), is\n\n\u003ea complete and free implementation of the OpenPGP standard as defined by RFC4880 (also known as PGP). GnuPG allows you to encrypt and sign your data and communications; it features a versatile key management system, along with access modules for all kinds of public key directories. GnuPG, also known as GPG, is a command line tool with features for easy integration with other applications. A wealth of frontend applications and libraries are available. GnuPG also provides support for S/MIME and Secure Shell (ssh).\n\nGNUPG's \"claim to fame\" is that\n\n\u003e GnuPG is one of the tools that Snowden used to uncover the secrets of the NSA.\n\n## Encrypting a file with GnuPG\n\n***Next***, I ***installed*** `gpg` ***using*** [Homebrew](https://formulae.brew.sh/formula/gnupg) so I could ***use it*** to `encrypt` and `decrypt` a `file`. If you ***have*** `Homebrew` ***already installed*** on your `macOS`, but ***don't have*** `gnupg` ***installed***, ***run*** the ***following command*** in `Terminal`:\n\n```shell\nbrew install gnupg\n```\n\nIf you ***think that*** you ***might have*** it ***installed***, ***run*** the ***following command*** in `Terminal`:\n\n```shell\ngpg --version\n```\n\nIf you ***get back*** something like the ***following***:\n\n```shell\ngpg (GnuPG) 2.4.3\n```\n\nThen you ***do have*** it ***installed***. ***But*** if you ***get back***:\n\n```shell\nzsh: command not found: gpg\n```\n\nYou ***do not*** have it ***installed***.\n\nIf you are on `Linux`, you ***would*** `use` the ***following command*** to ***install*** `gpg` ***using*** the `package manager` ***of your*** `Linux distribution`:\n\n```shell\nsudo apt install gnupg\n```\n\n***After*** `gnupg` was ***installed***, I ***ran*** the ***following command*** in `Terminal`:\n\n```shell\necho Hello Maria! \u003e greetings.txt\n```\n\n**Note**: ***On*** `macOS`, ***when*** we ***run*** the `echo` command, we ***should not*** `use quotes` ***around*** the `string` of `words`. It ***throws*** an `error`.\n\n***Then*** I ***ran*** the `gpg` command to `encrypt` my ***new*** `greetings.txt` file, and I ***included*** the ***use*** of a `passphrase`. I even ***use them*** when ***communicating*** with `Github`, ***even though*** I am ***connected*** via `SSH`. ***So***:\n\n```shell\ngpg --batch --output greetings.txt.gpg --passphrase mypassword --symmetric greetings.txt\n```\n\n`mypassword` should be ***replaced with*** your ***actual*** `passphrase` value. This command ***creates*** the `encrypted` file `greetings.txt.gpg` in the ***same location*** as `greetings.txt` using its ***default*** `AES256 algorithm`. [As for the --batch option, with GPG2](https://superuser.com/questions/972204/how-to-use-gnupg-with-passphrase), ***which is*** what `GPG 2.4.3` is (`Homebrew` ***links*** `GPG` to `GPG2`), you ***have*** to ***use*** it ***with*** the --passphrase option.\n\n***After*** I ***executed*** this command, the ***following*** was ***returned*** in `Terminal`:\n\n```shell\ngpg: WARNING: unsafe permissions on homedir '/Users/mariacam/.gnupg'\n```\n\n***First***, to ***make sure*** that the `.gnupg` directory and its `contents` is ***accessible*** to me, I ***run*** the ***following command***:\n\n```shell\nchown -R $(whoami) ~/.gnupg\n```\n\nThe `chown` command ***changes*** the `file ownership` of a ***specific*** `file` or `folder`. ***Here***, it ***pertains to*** the `.gnupg` folder in my `home directory`. `whoami` ***refers to*** the `current user`, ***which*** in ***my case***, is `me`, and ***refers to*** the `current user`'s `username` on the `system`. `-R` ***indicates*** that `ownership` of a `folder` is ***being changed***. In ***my case***, this is ***simply*** a `confirmation` of `ownership`, ***since*** I am the ***only user*** on ***my computer***.\n\n***But*** this was ***not enough***. I l***ike*** to ***make sure***, ***even though*** there are ***no other*** `users` at ***this time*** on ***my computer***, that ***only*** I ***have access*** to the `.gnupg` folder. ***So first*** I ***ran*** the ***following command***:\n\n```shell\nchmod 700 ~/.gnupg\n```\n\n`chmod` is used to ***change*** the `permissions` of `files` and `directories`. The ***above changes*** the `permissions` on the `.gnupg` folder to `700`. And `700` ***means*** that ***only*** the `creator` and `owner` of the `folder` ***can*** `Read`, `Write`, and `Execute` on the directory. And `group` and `others` ***cannot perform*** any operation on the `files` in the `directory`.\n\n***Then*** I ***ran*** the ***following***:\n\n```shell\nchmod 600 ~/.gnupg/*\n```\n\n***Here***, the `permissions` for the `files` ***inside*** the `.gnupg` folder are ***set to*** `600`. This ***means*** the `owner` has `Read` and `Write` permissions on the `files` ***but not*** `execution` permissions.\n\n***Lastly***, I ***ran*** the ***following***:\n\n```shell\nchmod 700 ~/.gnupg/*.d\n```\n\n***This is*** an `extra` and `special command` ***which is*** what ***made*** it ***possible*** for me to ***change*** the `permissions` on the `.gnupg` folder and `contents` to the ***proper settings***. ***Inside*** the `folder`, ***there is*** a `directory` which ***by default*** does ***not have*** `execution permissions` when one ***tries*** to `send keys` ***without*** a `keyserver` specified:\n\n```shell\ndrw-------  2 rik rik  4096 Jun  9 03:28 crls.d    \u003c---- Notice this here\n```\n\nSo `*.d` ***ensures that*** all `.d` directories ***inside*** have `execution permissions`. ***To view*** the `source` ***where*** I ***got*** this `information` ***from*** on `Github`, ***please visit*** [This fixes the \" gpg: WARNING: unsafe permissions on homedir '/home/path/to/user/.gnupg' \" error while using Gnupg.](https://gist.github.com/oseme-techguy/bae2e309c084d93b75a9b25f49718f85), and scroll down to kirvedx's comment from Jun 13, 2022.\n\n## Decrypting files with GnuPG\n\n***Next***, I ***ran*** the ***following command*** to `decrypt` the `greetings.txt.gpg` file I ***just*** had ***encrypted***:\n\n```shell\ngpg --batch --output greetings1.txt --passphrase mypassword --decrypt greetings.txt.gpg\n```\n\n***And*** the ***following*** was ***returned*** in `Terminal`:\n\n```shell\ngpg: AES256 encrypted data\ngpg: encrypted with 1 passphrase\n```\n\n***Then***, to ***clear*** the `passphrase` which was ***stored*** in the ***session***, I ***ran*** the ***following command***:\n\n```shell\necho RELOADAGENT | gpg-connect-agent\n```\n\n***Next***, I ***wanted*** to ***verify*** that my `decrypted` file `matched` my ***original*** `greetings.txt` file, so I ***ran*** the ***following command***:\n\n```shell\ndiff -s greetings.txt greetings1.txt\n```\n\n***And*** the ***following*** was ***returned*** in `Terminal`:\n\n```shell\nFiles greetings.txt and greetings1.txt are identical\n```\n\nSuccess!\n\n**Note**: the `-s` option is short for `--sign`, which stands for \"sign a message\". So basically, I am checking to make sure that the integrity of the file when decrypted was intact.\n\n### Related Resources\n\n- [Encrypting and Decrypting Files in Linux](https://www.baeldung.com/linux/encrypt-decrypt-files)\n\n- [How to Encrypt and Decrypt Files in Python](https://thepythoncode.com/article/encrypt-decrypt-files-symmetric-python)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finterglobalmedia%2Fencrypt-decrypt-files-python","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finterglobalmedia%2Fencrypt-decrypt-files-python","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finterglobalmedia%2Fencrypt-decrypt-files-python/lists"}