AGWA / git-crypt

Transparent file encryption in git
https://www.agwa.name/projects/git-crypt/
GNU General Public License v3.0
8.11k stars 472 forks source link

git-crypt: This repository contains a malformed key file. It may be corrupted. #230

Open pantelis-karamolegkos opened 2 years ago

pantelis-karamolegkos commented 2 years ago

Trying to add a new git-crypt collaborator as follows.

Following steps run on a MacOS Big Sur with

▶ gpg --version
gpg (GnuPG) 2.3.3
libgcrypt 1.9.4
Copyright (C) 2021 Free Software Foundation, Inc.
License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /Users/pantelis/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
AEAD: EAX, OCB
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

1 Create the key for a specific user id

gpg --full-generate-key -u foo@bar.com

Provided rest of the details interactively. RSA key was selected

2

I switch to the working tree of my GH repo containing encrypted files. I am a git-crypt collaborator so I am able to add the new user

git-crypt add-gpg-user --trusted foo@bar.com

3

Run a GH PR with the above change, where GH does recognise that a new git-crypt collaborator was added, since I see the following message automatically being created in the PR

New collaborators:

AF23912 Foo Bar <foo@bar.com>

4

I export locally the new user's private key

gpg --export-secret-keys foo@bar.com > private.key

5

I scp this private key to another machine running Debian 9 and

$ gpg --version
gpg (GnuPG) 2.1.18
libgcrypt 1.7.6-beta
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: /home/pantelis/.gnupg
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
        CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2

so next steps are executed running the above gpg version

6

I import the key that was copied during step 5

$ gpg --import private.key

gpg: key XXXXXXXX: public key "Foo Bar <foo@bar.com>" imported
gpg: key XXXXXXXX: secret key imported
gpg: Total number processed: 1
gpg:               imported: 1
gpg:       secret keys read: 1
gpg:   secret keys imported: 1

7

I clone the repo (I have an ssh private key for this job

$ git clone git@github.com/MyUsername/MyRepo

8

I cd into the new dir and try to perform a decryption

$ cd MyRepo
$ git-crypt unlock

git-crypt: This repository contains a malformed key file.  It may be corrupted.
erinaceous commented 2 years ago

Also having this issue in some environments but not others- tl;dr: I think it's the version of the gpg binary

I've got a repository which is using a total of 6 GPG keys, generated by myself on Fedora 35 and by other colleagues running Ubuntu 20.04, as well as a docker container using ubuntu:21.04. All of these are able to git-crypt unlock the repo with our respective GPG keys. However a CentOS 8.5 machine gives us the git-crypt: This repository contains a malformed key file. It may be corrupted. message.

Here's comparison of package versions, and terminal outputs from inspecting the files in .git-crypt/keys/default/0:

Working git-crypt 0.6.0 on Fedora 35

http://rpmfind.net/linux/RPM/fedora/devel/rawhide/aarch64/g/git-crypt-0.6.0-11.fc35.aarch64.html

$ gpg --version
gpg (GnuPG) 2.3.4
libgcrypt 1.9.4-unknown
$ dnf repoquery --deplist git-crypt
package: git-crypt-0.6.0-11.fc35.x86_64
  dependency: git
   provider: git-2.34.1-1.fc35.x86_64
  dependency: glibc >= 2.33.9000-43.fc35
   provider: glibc-2.34-11.fc35.i686
   provider: glibc-2.34-11.fc35.x86_64
  dependency: libc.so.6(GLIBC_2.34)(64bit)
   provider: glibc-2.34-11.fc35.x86_64
  dependency: libcrypto.so.1.1()(64bit)
   provider: opae-devel-2.0.0-2.3.fc35.x86_64
   provider: openssl-libs-1:1.1.1l-2.fc35.x86_64
   provider: openssl1.1-1:1.1.1i-3.fc35.x86_64
  dependency: libcrypto.so.1.1(OPENSSL_1_1_0)(64bit)
   provider: opae-devel-2.0.0-2.3.fc35.x86_64
   provider: openssl-libs-1:1.1.1l-2.fc35.x86_64
   provider: openssl1.1-1:1.1.1i-3.fc35.x86_64
  dependency: libgcc_s.so.1()(64bit)
   provider: libgcc-11.2.1-7.fc35.x86_64
  dependency: libgcc_s.so.1(GCC_3.0)(64bit)
   provider: libgcc-11.2.1-7.fc35.x86_64
  dependency: libgcc_s.so.1(GCC_3.3.1)(64bit)
   provider: libgcc-11.2.1-7.fc35.x86_64
  dependency: libstdc++.so.6()(64bit)
   provider: libstdc++-11.2.1-7.fc35.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3)(64bit)
   provider: libstdc++-11.2.1-7.fc35.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.13)(64bit)
   provider: libstdc++-11.2.1-7.fc35.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.3)(64bit)
   provider: libstdc++-11.2.1-7.fc35.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4)(64bit)
   provider: libstdc++-11.2.1-7.fc35.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.11)(64bit)
   provider: libstdc++-11.2.1-7.fc35.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.20)(64bit)
   provider: libstdc++-11.2.1-7.fc35.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.21)(64bit)
   provider: libstdc++-11.2.1-7.fc35.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.26)(64bit)
   provider: libstdc++-11.2.1-7.fc35.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.5)(64bit)
   provider: libstdc++-11.2.1-7.fc35.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.9)(64bit)
   provider: libstdc++-11.2.1-7.fc35.x86_64
  dependency: rtld(GNU_HASH)
   provider: glibc-2.34-11.fc35.i686
   provider: glibc-2.34-11.fc35.x86_64
$ file *.gpg
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b .
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b .
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b .
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b .
$ for file in *.gpg; do echo $file; gpg -v $file; echo; done
[redacted].gpg
gpg: Note: RFC4880bis features are enabled.
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]
gpg: using subkey [redacted] instead of primary key [redacted]
gpg: encrypted with rsa3072 key, ID [redacted], created 2022-01-19
      "[redacted]"
gpg: AES256.OCB encrypted data
gpg: original file name=''

[redacted].gpg
gpg: Note: RFC4880bis features are enabled.
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]
gpg: using subkey [redacted] instead of primary key [redacted]
gpg: encrypted with rsa3072 key, ID [redacted], created 2022-01-17
      "[redacted]"
gpg: AES256.OCB encrypted data
gpg: original file name=''

[redacted].gpg
gpg: Note: RFC4880bis features are enabled.
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]
gpg: encrypted with RSA key, ID [redacted]
gpg: public key decryption failed: No secret key
gpg: decryption failed: No secret key

[redacted].gpg
gpg: Note: RFC4880bis features are enabled.
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]
gpg: using subkey [redacted] instead of primary key [redacted]
gpg: encrypted with rsa3072 key, ID [redacted], created 2021-11-19
      "[redacted]"
gpg: AES256.CFB encrypted data
gpg: original file name=''

[redacted].gpg
gpg: Note: RFC4880bis features are enabled.
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]
gpg: encrypted with RSA key, ID [redacted]
gpg: public key decryption failed: No secret key
gpg: decryption failed: No secret key

[redacted].gpg
gpg: Note: RFC4880bis features are enabled.
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]
gpg: encrypted with RSA key, ID [redacted]
gpg: public key decryption failed: No secret key
gpg: decryption failed: No secret key

Failing git-crypt 0.6.0 on CentOS 8.5.2111

https://centos.pkgs.org/8/epel-x86_64/git-crypt-0.6.0-7.el8.x86_64.rpm.html

$ gpg --version
gpg (GnuPG) 2.2.20
libgcrypt 1.8.5
$ dnf repoquery --deplist git-crypt
package: git-crypt-0.6.0-7.el8.x86_64
  dependency: git
   provider: git-2.27.0-1.el8.x86_64
  dependency: libc.so.6(GLIBC_2.14)(64bit)
   provider: glibc-2.28-164.el8.x86_64
  dependency: libcrypto.so.1.1()(64bit)
   provider: openssl-libs-1:1.1.1k-5.el8_5.x86_64
  dependency: libcrypto.so.1.1(OPENSSL_1_1_0)(64bit)
   provider: openssl-libs-1:1.1.1k-5.el8_5.x86_64
  dependency: libgcc_s.so.1()(64bit)
   provider: libgcc-8.5.0-4.el8_5.x86_64
  dependency: libgcc_s.so.1(GCC_3.0)(64bit)
   provider: libgcc-8.5.0-4.el8_5.x86_64
  dependency: libm.so.6()(64bit)
   provider: glibc-2.28-164.el8.x86_64
  dependency: libstdc++.so.6()(64bit)
   provider: libstdc++-8.5.0-4.el8_5.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3)(64bit)
   provider: libstdc++-8.5.0-4.el8_5.x86_64
  dependency: libstdc++.so.6(CXXABI_1.3.3)(64bit)
   provider: libstdc++-8.5.0-4.el8_5.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4)(64bit)
   provider: libstdc++-8.5.0-4.el8_5.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.11)(64bit)
   provider: libstdc++-8.5.0-4.el8_5.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.20)(64bit)
   provider: libstdc++-8.5.0-4.el8_5.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.21)(64bit)
   provider: libstdc++-8.5.0-4.el8_5.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.5)(64bit)
   provider: libstdc++-8.5.0-4.el8_5.x86_64
  dependency: libstdc++.so.6(GLIBCXX_3.4.9)(64bit)
   provider: libstdc++-8.5.0-4.el8_5.x86_64
  dependency: rtld(GNU_HASH)
   provider: glibc-2.28-164.el8.i686
   provider: glibc-2.28-164.el8.x86_64
$ file *.gpg
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b .
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b .
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b .
[redacted].gpg: PGP RSA encrypted session key - keyid: [redacted] RSA (Encrypt or Sign) 3072b .
$ for file in *.gpg; do echo $file; gpg --keyid-format 0xlong -v $file; echo; done
[redacted].gpg
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]

[redacted].gpg
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]
gpg: using subkey [redacted] instead of primary key [redacted]

[redacted].gpg
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]
gpg: encrypted with RSA key, ID [redacted]
gpg: decryption failed: No secret key

[redacted].gpg
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]
gpg: encrypted with RSA key, ID [redacted]
gpg: decryption failed: No secret key

[redacted].gpg
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]
gpg: encrypted with RSA key, ID [redacted]
gpg: decryption failed: No secret key

[redacted].gpg
gpg: WARNING: no command supplied.  Trying to guess what you mean ...
gpg: public key is [redacted]
gpg: encrypted with RSA key, ID [redacted]
gpg: decryption failed: No secret key

Fedora 35 and CentOS 8 both have git-crypt 0.6 installed, appear to both be using openssl 1.1.1, the differences I can see is that CentOS 8 is currently on older minor versions of these dependencies:

Although these versions are all greater than minimum required according to the respective Ubuntu 20.04 package: https://packages.ubuntu.com/focal/git-crypt

My hunch is that it's down to gpg, as comparing the files in .git-crypt/keys/default/0 produces different (less) output on gpg 2.2.20 compared to 2.3.4

mxvincent commented 2 years ago

Hello, i have the same issue. I generate a gpg key and crypt a repository from osx.

OSX softwares:

gpg --version
gpg (GnuPG) 2.3.4
libgcrypt 1.10.0

git-crypt --version
git-crypt 0.6.0

On an ubuntu 20.04 workstation i try to unlock the repository. The gpg key was imported from previous osx station.

Ubuntu softwares:

gpg --version
gpg (GnuPG) 2.2.19
libgcrypt 1.8.5

git-crypt --version
git-crypt 0.6.0

git-crypt unlock
git-crypt: This repository contains a malformed key file.  It may be corrupted.
helmutg commented 1 year ago

I'm not sure whether I encountered the same issue, but let me give some ideas on debugging.

If you encounter the message "This repository contains a malformed key file.", you should figure out which keyfile that is. Below .git-crypt/keys, you can find encrpyted key files and you can decrypt them using plain gpg. For each of those decrypted keyfiles, you can run git crypt unlock .../decrypted/keyfile. One of them will likely fail.

Once you know which keyfile is failing, check whether it happens carry a key name default. That'd be important to note, because the name default turns the key file invalid. At least @erinaceous happens to use this key name and may be affected. Rather than telling you about the use of a bad key name, it gives you some instructions on upgrading the key file. Rather than upgrade, consider renaming your key.

Hope this helps.

In the mean time, I kindly request improving the error message for using a bad key name... That should have been easier to figure out.

opensorceror commented 1 year ago

I ran into this today and spent several hours troubleshooting, but eventually got it working on my end. It does indeed seem to be an issue with the way the key pair is generated, and so perhaps with the version of gpg that generates the key.

Steps to reproduce:

  1. On MacOS Ventura 13.2.1 (22D68), with gpg (GnuPG) 2.4.0 and libgcrypt 1.10.1, and git-crypt 0.6.0, generate a GPG key pair by running the command gpg --full-generate-key. Choose RSA 4096 when generating the key pair.
  2. In a "Debian GNU/Linux 8 (jessie)" Docker image, import the previously generated secret key and try to decrypt your Git repo. You'll see the message "git-crypt: This repository contains a malformed key file. It may be corrupted." and decryption will fail.

Fix: Replace step #1 above by the following - generate the GPG key pair using gpg --gen-key using gpg (GnuPG) 2.0.22, libgcrypt 1.5.3 (I used a CentOS VM). All steps above are identical. Suddenly, step #2 magically works.