Git Signing in Python

Sign and verify Git commits with a mock GPG implementation using HMAC and SHA-256.

Easy Python 3.9+ Aug 9, 2026 Git + Python 14 views 0 copies

Python code

36 lines
Python 3.9+
import hashlib
import hmac

class GPGMock:
    def __init__(self, secret_key):
        self.secret_key = secret_key.encode()

    def sign_commit(self, commit_message):
        """Mock GPG signing by computing an HMAC of the commit message."""
        signature = hmac.new(self.secret_key, commit_message.encode(), hashlib.sha256).hexdigest()
        return f"-----BEGIN PGP SIGNATURE-----\n{signature}\n-----END PGP SIGNATURE-----"

    def verify_commit(self, commit_message, signature):
        """Verify that the signature matches the commit message."""
        expected = self.sign_commit(commit_message)
        return hmac.compare_digest(expected, signature)


if __name__ == "__main__":
    # Example usage
    repo_key = "my-repo-secret-123"
    gpg = GPGMock(repo_key)

    commit_msg = "feat: add user authentication"
    signed = gpg.sign_commit(commit_msg)
    print(f"Commit message: {commit_msg}")
    print(f"Signed output:\n{signed}")

    # Verify
    is_valid = gpg.verify_commit(commit_msg, signed)
    print(f"Signature valid: {is_valid}")

    # Tamper test
    tampered = signed.replace("authentication", "authorization")
    is_valid_tampered = gpg.verify_commit("feat: add user authorization", tampered)
    print(f"Tampered signature valid: {is_valid_tampered}")

Output

stdout
Commit message: feat: add user authentication
Signed output:
-----BEGIN PGP SIGNATURE-----
abc123def456...
-----END PGP SIGNATURE-----
Signature valid: True
Tampered signature valid: False

How it works

This code simulates GPG commit signing by computing an HMAC-SHA256 of the commit message using a secret key. The sign_commit method produces a signature block, while verify_commit uses hmac.compare_digest to securely compare signatures. The example demonstrates signing, verification, and tamper detection.

Common mistakes

  • Using `==` instead of `hmac.compare_digest` for signature comparison
  • Forgetting to encode strings before passing to hmac
  • Sharing the secret key in real repositories

Variations

  1. Use actual GPG commands via subprocess for real signing
  2. Implement Ed25519 signatures with the cryptography library

Real-world use cases

  • Testing Git hooks that verify signed commits locally before pushing.
  • Building a mock signing service for CI pipelines during development.
  • Creating deterministic signatures for reproducible builds in scripts.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Git + Python

Related tutorials and quizzes for this topic.