git-crypt icon indicating copy to clipboard operation
git-crypt copied to clipboard

Don't encrypt empty files in new repositories

Open AGWA opened this issue 4 years ago • 6 comments

git has several problems with using smudge/clean filters on empty files (see issue #53). The easiest fix is to just not encrypt empty files. Since it was already obvious from the encrypted file length that a file was empty, skipping empty files does not decrease security.

Since skipping empty files is a breaking change to the git-crypt file format, we only do this on new repositories. Specifically, we add a new critical header field to the key file called skip_empty which is set in new keys. We skip empty files if and only if this field is present.

Closes: #53 Closes: #162

AGWA avatar Jul 29 '20 13:07 AGWA

I'd like to give this a go in an existing repository. What process should I follow to migrate to use this new flag? I don't know how to set the flag for existing keys.

hugopeixoto avatar Jul 29 '20 14:07 hugopeixoto

  1. Make a backup

  2. Export the current key to a temporary file called originalkey: git-crypt export-key originalkey

  3. Lock the repo: git-crypt lock

  4. Unlock with a migrated key:

cat originalkey | (echo 0047495443525950544b4559000000020000000300000000 | xxd -r -p; tail -c +17) | git-crypt unlock -
  1. If you're using GPG mode, then delete the .git-crypt directory and re-add all your collaborators.

  2. When everything looks OK delete originalkey

AGWA avatar Jul 29 '20 16:07 AGWA

Hi @hugopeixoto, did you have a chance to try this out?

AGWA avatar Aug 16 '20 19:08 AGWA

Hi, sorry, I didn't. Having to hexedit the key file and re-add collaborators kind of threw me off.

I'm checking this now. Will we need to add a command to do this automatically?

hugopeixoto avatar Aug 17 '20 16:08 hugopeixoto

I'm having trouble replicating the original rebase issue, and my repository no longer has any empty files. I tested the migration with a new repository, though, and it seemed to work fine. Here's the transcript:

$ git init
Initialized empty Git repository in gitcrypttest/.git/
$ git crypt init # using the current `master` branch
Generating key...
$ cat .gitattributes
*.txt filter=git-crypt diff=git-crypt
$ cat nonempty.txt
Hello, world!
$ cat empty.txt
$ git add .gitattributes nonempty.txt empty.txt
$ git commit -m 'add files'
[master (root-commit) e832c44] add files
 3 files changed, 1 insertion(+)
 create mode 100644 .gitattributes
 create mode 100644 empty.txt
 create mode 100644 nonempty.txt
$ git crypt export-key ../default-key
$ git crypt lock
$ ls -lah
total 24K
drwxr-xr-x 3 hugopeixoto hugopeixoto 4.0K Aug 17 19:54 .
drwxr-xr-x 6 hugopeixoto hugopeixoto 4.0K Aug 17 19:54 ..
-rw-r--r-- 1 hugopeixoto hugopeixoto   22 Aug 17 19:54 empty.txt
drwxr-xr-x 9 hugopeixoto hugopeixoto 4.0K Aug 17 19:54 .git
-rw-r--r-- 1 hugopeixoto hugopeixoto   38 Aug 17 18:28 .gitattributes
-rw-r--r-- 1 hugopeixoto hugopeixoto   36 Aug 17 19:54 nonempty.txt
$ xxd empty.txt
00000000: 0047 4954 4352 5950 5400 e37e 9ea0 0581  .GITCRYPT..~....
00000010: 8b3c d08d 16d3                           .<....
$ xxd nonempty.txt
00000000: 0047 4954 4352 5950 5400 65d2 d4ad 78b9  .GITCRYPT.e...x.
00000010: 28bf 519f d0a3 bcc4 5cbb 94c4 1e0b e6e7  (.Q.....\.......
00000020: 8d15 3937                                ..97
$ (cd ~/work/contrib/git-crypt; git switch skip_empty; make)
$ cat ../default-key | (echo 0047495443525950544b4559000000020000000300000000 | xxd -r -p; tail -c +17) | git-crypt unlock -
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   empty.txt

no changes added to commit (use "git add" and/or "git commit -a")
$ git add empty.txt
$ git commit -m "emptify file"
[master 11e3974] emptify file
 1 file changed, 0 insertions(+), 0 deletions(-)
$ cat nonempty.txt
Hello, world!
$ cat empty.txt
$ git crypt export-key ../default-key-2
$ git crypt lock
$ ls -lah
total 20K
drwxr-xr-x 3 hugopeixoto hugopeixoto 4.0K Aug 17 19:55 .
drwxr-xr-x 6 hugopeixoto hugopeixoto 4.0K Aug 17 19:55 ..
-rw-r--r-- 1 hugopeixoto hugopeixoto    0 Aug 17 19:55 empty.txt
drwxr-xr-x 9 hugopeixoto hugopeixoto 4.0K Aug 17 19:55 .git
-rw-r--r-- 1 hugopeixoto hugopeixoto   38 Aug 17 18:28 .gitattributes
-rw-r--r-- 1 hugopeixoto hugopeixoto   36 Aug 17 19:55 nonempty.txt
$ git crypt unlock ../default-key-2
$ cat nonempty.txt
Hello, world!

hugopeixoto avatar Aug 17 '20 19:08 hugopeixoto

any progress on this show-stopping issue?

nkrot avatar Dec 13 '23 11:12 nkrot