Git Encryption Nuances

Published on October 14, 2017

Git Encryption Nuances

If you want to use a public resource like GitHub or GoogleDrive to store your repository, but are not ready to share the results of your work with the whole world, then encryption of files in the git repository will help you. This is not a top-secret technology and there are a number of small articles on the Internet (and even on Habré) on this subject, but all of them are a variation of the piece of git documentation devoted to attributes and do not reveal the topic at all. In addition, in the process of using git in this mode, there are nuances of use that are not always easy to understand and solve, which I will try to highlight in this article.

Environment


Initially, it is assumed that encryption software is available on the computer. The natural choice is to use openssl. In Linux, it is by default. On windows, it comes bundled with mingw in a git installation for windows. The only thing we need to take care of under Windows is that the folder in which openssl is located (for example, “C: \ Program Files \ Git \ mingw64 \ bin \”) appears in the PATH environment variable. Then we do not have to create additional utilities (as recommended in the articles about encryption in the git) and the whole configuration is much simpler.

Git setup


Now let's do the magic of creating attributes in git. First, we need to figure out what exactly we want to encrypt in the tree. If you are a seasoned paranoid, like me, then you decide to encrypt everything. Create a file in the root of the empty .gitattributes repository: If you are not so paranoid, you can replace the wildcard with * .java or * .cpp to your liking. Why init.txt? We’ll make a short memo for ourselves so that in case of cloning the repository we don’t have to frantically search for instructions on the Internet. In addition, it can be very successfully used as a Shelov script to initialize cryptography in a freshly cloned copy. Now create the mentioned init.txt file:

* filter=openssl diff=openssl
.git* !filter !diff
init.txt !filter !diff






<code> #This is protected repository. To initialize it you need:
#
# git clone -n https://github.com/<your_project_name>
# git checkout tags/init
# Then execute in shell:
# . init.txt <password for repository>
[ -z "$1" ] && echo "Argument required: <password>" && return
git config filter.openssl.clean "openssl enc -base64 -aes-256-ecb -S 123456789 -k $1"
git config filter.openssl.smudge "openssl enc -d -base64 -aes-256-ecb -k $1"
git config diff.openssl.textconv "openssl enc -d -base64 -aes-256-ecb -k $1 2&>/dev/null || cat"
git checkout master</code>

After making sure that git and openssl are available in the paths, we run the file as shown in the comment (If you are on Windows this must be run from git-bash).

. init.txt my_repo_pass

Or, just by hands we launch 3 git config commands from this file replacing $ 1 in the line with the password for the repository.

Now add this all to the repository: Voila, everything is ready for work with us. Now we can add new files and they will be automatically crypted.

git add .
git commit -m "protection initialization"
git push
git tag init
git push --tags




Integration with Intelij


Now the fun part. If you create a scripted java project on github and start working with it, you will very soon notice that the git plugin in the IDE stubbornly does not want to compare files with previous versions. This is because intelij pulls previous versions of a file from the repository using the git show command . Now attention: the git show and git format-patch commands do not use filters by default. To do this, they need to specify the --textconv option. I couldn’t get the git plugin to do it myself, so I made a small wrapper for git and specified it in the settings. It automatically adds this option to the show command.

git4idea.bat


@echo off
set ARGS=%*
"C:\Program Files\Git\bin\git.exe" %ARGS: show = show --textconv %


Option for Linux (unfortunately not tested): Now, I hope, the topic is revealed.

#!/bin/bash
export ARGS="$*"
git "${ARGS/ show / show --textconv }"