简体   繁体   中英

When using GPG to sign git commits, what exactly is being signed?

If I use GPG to sign a commit ( https://git-scm.com/book/en/v2/Git-Tools-Signing-Your-Work ) and then check the contents of the commit object I just created:

git commit -a -S -m "This is a Signed commit"
git cat-file -p HEAD

I get:

tree 1265193cc831c2bd47cedbb27f029e5d45fa0bb039d5bb5136f152a3e88c07b0
parent 16625976433ec56a26feb1478051b28b78684a3d68f475221afcfae2a7aaaa0d
author John Doe <john.doe@internet.www> 1612379624 +0100
committer John Doe <john.doe@internet.www> 1612379624 +0100
gpgsig-sha256 -----BEGIN PGP SIGNATURE-----

 iQGzBAABCAAdFiEELgGt+L8yg4keIDJDpyYj1XHdLa8FAmAa9egACgkQpyYj1XHd
 La+BogwA0VEoobCJPRLk2olHzW6iO9ioyxIrrW6uPAcLv6uernxrGDK6odYuywED
 XeVEu3L9/HLG8MYSqgAGKDWfiOphRi5Lw1fLnSA3MNC1uh18OqdmD/PjyP9hMnbC
 XayugJJ2dPkUHADxeDoQOGHg6wmfn+/4IsHit74YsAYXcDz1/QIHrEGMPCwROGCX
 Nb1srMw2/8e+NM9U5h5KSw5ZYmBtSynIWCsHBC2w8eqvuhKMmKxbGV3izV7eOTfl
 R8aC2FJSuSd/MhGprAki2sW1efiNr1EJNt/hvP2S9Eq/fkLUlVuWk5cyg/8tDJX5
 VQO5RqCTR/Yz5mleoKMOeBBARzWK/r1l0bVQZYoraO8I8zxuLt5gkxqvqTOrhOKy
 uTX58BdQHSlx1fU02UuPruimpbSZOBhwPFeVXl8Kj3zUWLNpTeQXZ/MSNZOiR1qF
 xMdqKbuzh53B3tqvd02Cy7jdIssT8DwLM5V3IjYfv/GG/iQOE7BHGxYbPgEkv4e6
 KvUBxEjj
 =8gBZ
 -----END PGP SIGNATURE-----

This is a Signed commit

What exactly is the digest that is being signed? If the signature is embedded in the commit object, then it can hardly be the commit hash itself - so is it the tree hash? Or something else? Does that in turn mean that the commit message is not signed and could be tampered with?

Note: I'm using a git repository here that was initialized with --object-type sha256 to use SHA-256 based hashes (by default git uses SHA-1), but my question applies to git repositories with SHA-1 hashes as well (in case gpg signature works differently for SHA-1 and SHA-256 repositories)

The data you're signing is the entirety of the commit or tag object, minus the contents of any multi-line headers starting with gpgsig , and, in the case of tags, the contents of the trailing tag signature. So, basically the contents of the object minus the signature portions themselves. That includes the message.

Note that the hash of the object includes the signature, so the signature cannot be removed or changed (or additional ones added) unless you rewrite history.

Git 2.30 and before had a bug where they would incorrectly flag a commit or tag with multiple signatures as being invalid. There's a patch that will likely be included in the next version to fix that.

If you put the commit without the signature portion into a file called commit and put the signature portion (minus the leading whitespace) into a file called commit.asc , you can verify the signature with gpg --verify commit.asc .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM