EncryptAGit - Encrypt Your Git Repos

Overview

Downloads

EncryptAGit

Encrypt Your Git Repos

Authors

Installation

pip install encryptAgit

Upgrade

pip install encryptAgit --upgrade

Requirements

  • GitPython
  • pathlib
  • cryptography
  • pathspec

Why??

OK. I'm already paying for github. It stores files. And has versioning.

I wanted to see how hard it would be to write something from scratch with reasonable security...

..That I wouldn't mind using.

I'm using encryptAgit as a note taking app. I can use whatever editor I want. Sublime Text, vim, emacs, VS Code. Whatever that writes files to disk.

You could use encryptAgit to keep your notes/code private, but yet public, and share the key with only people you want to have access.

Feel free to share how you are using it!

Threat model

My threat model does not include Mossad.

If someone is on your computer capturing keystrokes, this won't help you.

If someone comes across your gitrepo of encrypted notes and they want to decrypt it, it's not going to be easy (depends on your password/salt combos - read more...).

Security

I'm using fernet.

As this is a store of secrets, I can't use a random salt. The user provides it.

To produce the encryption/decryption key, I'm using Scrypt with the user provided salt to make the Key Derivation Function and then the user password is provided to derive the key.

It takes over 1 sec to compute the key on a late model macBook pro (not an M1).


random.seed(user_salt)
# The salt must be consistent and it is secret.
# Not md5!
self.salt = random.randbytes(16)

kdf = Scrypt(
    salt=self.salt,
    length=32,
    n=2**15,
    r=13,
    p=3,
)

start = time.time()
self.key = base64.urlsafe_b64encode(kdf.derive(bytes(password, 'iso-8859-1')))
end = time.time()

I consider the salt and password to be secrets. Maybe share one of each between friends so only the two of you can open a git repo. I don't know. Either way, keep them secure.

Encrypted files (tokens - fernet speak) are stored in encrypted_git.json.

encrypted_git.json format:

{
    {
  "full_file_path": {
    "token": "gAAAAAABidd63NQSVrcIRrq9f_g68o4KV13w3SiSXSPI5fxOJNnhlyUUU0eTnzlzkBf_mdRsvZeeh8Sq8YO7yV2GaqB56qNai7t_kkbgJ34OiDLl_N-bXviELx5MSyblp-EbKciUsYH67qIpbnTsbw9KZcQg5uzp9RIlWT9aYaEOruJbEjLSM7_KoWWLKtajFaZ87t9ZY_3nJ7AdSdvOx645Th9VXWxrxV3PQtXaLUYCUYIpfKV3w_9uHCRoA=",
    "filehash": "ee7d78b32d112e88d69fa0739e3217c0d44b193ccbb7579909e1b72e7839f7b5922b5ca80d5f88b3e60aa67dd1ee379b8f74f9dc824b2c6c509471a11d406789"
  },

}

filehash is the sha512 of the user provided salt + the file contents.


    def hash_file(self, file_path):
        return hashlib.sha512(self.salt + open(file_path, 'rb').read()).hexdigest()

This helps to prevent searching for a file by hash.

No keying material is logged or written to disk.

Yes, you can see the repo_path + file name in the encrypted_git.json file. Make sure it is not sensitive info. Reason this is not encrypted is it allows for speed and minimizes decryption cycles to check if a file has been modified. One might say, you could encrypt the full_file_path, like so...

{
    1: {"fullPath": "CBAAAAABidd63NQSVrcIRrdsas63635181faske82",
    "token": "gAAAAAABidd63NQSVrcIRrq9f_g68o4KV13w3SiSXSPI5fxOJNnhlyUUU0eTnzlzkBf_mdRsvZeeh8Sq8YO7yV2GaqB56qNai7t_kkbgJ34OiDLl_N-bXviELx5MSyblp-EbKciUsYH67qIpbnTsbw9KZcQg5uzp9RIlWT9aYaEOruJbEjLSM7_KoWWLKtajFaZ87t9ZY_3nJ7AdSdvOx645Th9VXWxrxV3PQtXaLUYCUYIpfKV3w_9uHCRoA=",
    "filehash": "ee7d78b32d112e88d69fa0739e3217c0d44b193ccbb7579909e1b72e7839f7b5922b5ca80d5f88b3e60aa67dd1ee379b8f74f9dc824b2c6c509471a11d406789"
    },

}

Whereas, the fullPath is kept decrypted in a python dict pointing to the current filehash. However, the fullPath will allways be different when encrypted and great care will be required to ensure I'm not writing to the encrypted_git.json file multiple times for the same file. To properly find the file to change/update/remove, I'd have to decrypt each fullPath to ensure I had an exact match - then update or drop the file from the json blob.

Hmm... I'll pass for now.

Keep your filenames non-sensitive!

And use a passphrase for your salt and passwords.

Isn't this like chef data-bags?

Not really. Fernet is AES-CBC. It's authenticated. The difference is I'm using Scrypt to derive a password vs pkcs5_keyivgen, which is depreciated and is not using a salt. I'm requiring it.

Usage

This works best in a fresh git repo. I haven't implemented git history squashing yet. So any old files will be in your git history.

Maybe I'll implement git history squashing/deletion in a new release.

  1. git clone your notes repo
  2. Change directory to it.
  3. Execute encryptAgit.py
encryptAGit
๐Ÿ˜„ No encrypted_git.json file, seems like first use!
๐Ÿค— Welcome to encryptAGit! Let's encrypt your repo!
๐Ÿค“ Use a passphrase for both salt and password. Remember what you enter!
๐Ÿง‚Enter your salt:
๐Ÿ•ต๏ธ Enter your password:
[*] It took 1.185420036315918 seconds to make the key.
[*] Updating moo.txt in encrypted store
[*] Updating hello.txt in encrypted store
[*] Updating pictures/kailua_beach.png in encrypted store
[*] Updating pictures/washington_monument.png in encrypted store
[*] Updating notes/unencryped.txt in encrypted store
[*] Updating notes/testing.txt in encrypted store
[*] Updating notes/1/more.txt in encrypted store
[*] Writing updated encrypted_git.json
[*] Push of encrypted_git.json complete!

Now any SAVED changes to files in your git repo will be automatically encrypted and pushed to your git repo.

Here I saved a file in a new directory called newdir called newfile.txt:

[*] Updating newdir/newfile.txt in encrypted store
[*] Writing updated encrypted_git.json
[*] Push of encrypted_git.json complete!

Use .gitignore:

 cat .gitignore 
*.swp
.DS_Store
README.md

Any files you put in .gitignore will not be encrypted, deleted, or saved. You have to git add, commit, and push those yourself.

Ending the process and changing password

Hit CTRL+C and you will be asked if you want to rotate your salt/password.

Type n if you don't, y if you do.

encryptAgit
๐Ÿ˜Š Welcome Back to encryptAGit! Let's decrypt your repo!
๐Ÿง‚Enter your salt:
๐Ÿ•ต๏ธ Enter your password:
[*] It took 1.0983080863952637 seconds to make the key.
[*] Writing decrypted moo.txt to disk.
[*] Writing decrypted hello.txt to disk.
[*] Writing decrypted pictures/kailua_beach.png to disk.
[*] Writing decrypted pictures/washington_monument.png to disk.
[*] Writing decrypted newdir/newfile.txt to disk.
[*] Writing decrypted notes/unencryped.txt to disk.
[*] Writing decrypted notes/testing.txt to disk.
[*] Writing decrypted notes/1/more.txt to disk.
^C
๐Ÿ’ญ Do you want to change your salt and password? (y/n):

If you want to backout completely without erasing your UNENCRYPTED files type CTRL+C twice in a row.

sys.exit(main()) File "/Users/pioneer/homebrew/lib/python3.9/site-packages/encryptAgit.py", line 361, in main run.run() File "/Users/pioneer/homebrew/lib/python3.9/site-packages/encryptAgit.py", line 346, in run answer = input('\n๐Ÿ’ญ Do you want to change your salt and password? (y/n):') KeyboardInterrupt ">
encryptAgit
๐Ÿ˜Š Welcome Back to encryptAGit! Let's decrypt your repo!
๐Ÿง‚Enter your salt:
๐Ÿ•ต๏ธ Enter your password:
[*] It took 1.0983080863952637 seconds to make the key.
[*] Writing decrypted moo.txt to disk.
[*] Writing decrypted hello.txt to disk.
[*] Writing decrypted pictures/kailua_beach.png to disk.
[*] Writing decrypted pictures/washington_monument.png to disk.
[*] Writing decrypted newdir/newfile.txt to disk.
[*] Writing decrypted notes/unencryped.txt to disk.
[*] Writing decrypted notes/testing.txt to disk.
[*] Writing decrypted notes/1/more.txt to disk.
^C
๐Ÿ’ญ Do you want to change your salt and password? (y/n):^CTraceback (most recent call last):
  File "/Users/pioneer/homebrew/lib/python3.9/site-packages/encryptAgit.py", line 339, in run
    time.sleep(1)
KeyboardInterrupt

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/pioneer/homebrew/bin/encryptAgit", line 8, in 
    sys.exit(main())
  File "/Users/pioneer/homebrew/lib/python3.9/site-packages/encryptAgit.py", line 361, in main
    run.run()
  File "/Users/pioneer/homebrew/lib/python3.9/site-packages/encryptAgit.py", line 346, in run
    answer = input('\n๐Ÿ’ญ Do you want to change your salt and password? (y/n):')
KeyboardInterrupt

Editing files offline

Let's say to do a double CTRL+C and want to edit files offline - feel free to do so! Then later start encryptAgit again, if there were no edits to the decrypted files you won't get a warning:

encryptAgit
๐Ÿ˜Š Welcome Back to encryptAGit! Let's decrypt your repo!
๐Ÿง‚Enter your salt:
๐Ÿ•ต๏ธ Enter your password:
[*] It took 1.073664903640747 seconds to make the key.
^C  
๐Ÿ’ญ Do you want to change your salt and password? (y/n):n

[*] Exiting
๐Ÿ‘‹ Removing unencrypted files not in .gitignore

If you edit the files without encryptAgit running you'll be asked to overwrite the newer file or not after running encryptAgit again:

โžœ  git-notes git:(main) โœ— vim moo.txt
โžœ  git-notes git:(main) โœ— encryptAgit              
๐Ÿ˜Š Welcome Back to encryptAGit! Let's decrypt your repo!
๐Ÿง‚Enter your salt:
๐Ÿ•ต๏ธ Enter your password:
[*] It took 1.0608000755310059 seconds to make the key.
[!] moo.txt has changed since last encryption
[!!] Seems the file on disk has changed from the encrypted file, overwrite it from the encrypted version? (y/n):n
[*] Updating moo.txt in encrypted store.
[*] Writing updated encrypted_git.json
[*] Push of encrypted_git.json complete!

Enjoy

Please submit any bug reports to the github repo...

Considerations

GitHub repo and file size limits.

TODO

  • Add git history squashing option on user password change.
  • Video on example usage
  • Inspection of encrypted files before overwrite of new file or not
Owner
midnite_runr
I laugh in the general direction of security products.
midnite_runr
A bot written in Python to automatically buy tokens on the Binance Smart Chain as soon as liquidity is provided

A bot written in Python to automatically buy tokens on the Binance Smart Chain as soon as liquidity is provided. If youโ€™ve found this bot useful and have profited from it please consider donating any

473 Dec 25, 2022
An Etebase (EteSync 2.0) server so you can run your own.

Etebase - Encrypt Everything An Etebase (EteSync 2.0) server so you can run your own. Installation Requirements Etebase requires Python 3.7 or newer a

EteSync & Etebase 1.2k Dec 31, 2022
That Hash will name that hash type! Identify MD5, SHA256 and 300+ other hashes Comes with

Call for translators! We're looking for translators to help translate this spec for everyone! Read this documentation in the following languages ํ•œ๊ตญ์–ด ไธญ

All Contributors 6.8k Jan 05, 2023
Hasher Hash, Compare and Verify your files Translations

Hasher Hash, Compare and Verify your files Translations In order to translate Hasher to a language you must add a folder with the language abbreviatio

Jeyson Flores 14 Apr 01, 2022
Pool funds to bootstrap a Uniswap pair

Seed liquidity A contract to pool funds which are then used to boostrap a new Uniswap liquidity pair. Specification A new SeedLiquidity contract is de

66 Dec 09, 2022
This folder contains all the assignment of the course COL759 : Cryptography & Computer Security

Cryptography This folder contains all the assignment of the course COL759 : "Cryptography & Computer Security" Assignment 1 : Encyption, Decryption &

0 Jan 21, 2022
๐Ÿ˜ˆ Shining is a tool that enables engineers to remotely pull smart contract code in multi-file situations.

๐Ÿ‘‘ Shining ๐Ÿ˜ˆ Shining is a tool that enables engineers to remotely pull smart contract code in multi-file situations. Shining is the name of one of my

xxxeyJ 15 Jun 17, 2022
CertPy is a high level toolkit for generating x509 (e.g. SSL/TLS/HTTPS) certificates in Python.

CertPy CertPy is a high level toolkit for generating x509 (e.g. SSL/TLS/HTTPS) certificates in Python. Certificate โ€œprofilesโ€ are implemented as Pytho

Ryan Castellucci 4 Feb 21, 2022
A workshop to build an NFT smart contract on the polygon blockchain

Polygon NFT Workshop This is an interactive workshop that guides you through the steps to deploy an NFT smart contract on the Polygon blockchain. By t

Banjo Obayomi 56 Oct 14, 2022
Simple crypto & blockchain implementation written in Python

JaamoCoin - simple Python blockchain example This is a very simple blockchain example written in Python. Based on this tutorial: https://medium.com/co

Jaakko Alajoki 1 Jan 07, 2022
Python program that handles the creation, encryption and storage of log/journal files. Kinda works like a diary of sorts.

LucaSoft J.O.U.R.N.A.L The J.O.U.R.N.A.L (Just anOther User Redaction & Navigation Assistant by Lucaspec72) is a Python program that handles the creat

Lucaspec72 8 Oct 27, 2021
A lightweight encryption library in python.

XCrypt About This was initially a project to prove that I could make a strong encryption but I decided to publish it so that the internet peoples coul

Anonymous 8 Sep 10, 2022
Certbot is EFF's tool to obtain certs from Let's Encrypt and (optionally) auto-enable HTTPS on your server.

Certbot is EFF's tool to obtain certs from Let's Encrypt and (optionally) auto-enable HTTPS on your server. It can also act as a client for any other CA that uses the ACME protocol.

29.5k Dec 31, 2022
A hybrid(AES + RSA) encryptor in python.

python-file-encryptor A hybrid(AES + RSA) encryptor in python. Tasted on Windows and Linux(Kali). Install Requirements Use the package manager pip to

Alireza Kalhor 8 Jun 24, 2022
This is an experimental AES-encrypted RPC API for ESP 8266.

URPC This is an experimental AES-encrypted RPC API for ESP 8266. Usage The server folder contains a sample ESP 8266 project. Simply set the values in

Ian Walton 1 Oct 26, 2021
The leading native Python SSHv2 protocol library.

Paramiko Paramiko: Python SSH module Copyright: Copyright (c) 2009 Robey Pointer 8.1k Jan 08, 2023

Python wrapper for the Equibles cryptos API.

Equibles Cryptos API for Python Requirements. Python 2.7 and 3.4+ Installation & Usage pip install If the python package is hosted on Github, you can

Equibles 1 Feb 02, 2022
A simple script useful to switch from Dashlane to Bitwarden by converting the password file to the right format.

A simple script useful to switch from Dashlane to Bitwarden by converting the password file to the right format.

3 May 06, 2022
O BiscoitoDaSorte foi criado com o objetivo de estudar desenvolvimento de bots para Discord.

BiscoitoDaSorteBOT O BiscoitoDaSorte foi criado com o objetivo de estudar desenvolvimento de bots para Discord. BOT online e com o comando =sorte Requ

Jonas Carvalho 5 Mar 17, 2022
A Docker image for plotting and farming the Chiaโ„ข cryptocurrency on one computer or across many.

An easy-to-use WebUI for crypto plotting and farming. Offers Plotman, MadMax, Chiadog, Bladebit, Farmr, and Forktools in a Docker container. Supports Chia, Cactus, Chives, Flax, Flora, HDDCoin, Maize

Guy Davis 328 Jan 01, 2023