티스토리 뷰

개요

Git은 커밋을 생성할 때 user.name과 user.email 정보를 메타데이터로 저장한다. 하지만 이 정보는 단순히 텍스트 형태로 기록될 뿐, 작성자 신원에 대한 검증 과정은 없다. 즉, 제3자가 같은 이름과 이메일을 설정하면 겉보기에는 동일한 작성자가 만든 커밋처럼 보이는 커밋을 만들 수 있다.

물론 GitHub 저장소에 커밋을 푸시하려면 SSH 키나 Personal Access Token을 통한 인증 절차가 필요하기 때문에,
단순히 name과 email만 안다고 해서 저장소를 직접 변경할 수 있는 것은 아니다. 다만, 커밋 자체는 위조가 가능하다는 점에서 신원 검증(Authenticity) 이라는 측면에서는 여전히 취약점이 존재한다.

 

이러한 문제를 보완하기 위해 Git은 GPG(GNU Privacy Guard), SSH, S/MIME 등의 방식을 이용한 커밋 서명(Signing) 기능을 제공한다. 이를 통해 커밋 작성자는 자신의 비공개 키(private key)로 커밋에 디지털 서명을 추가할 수 있고, 다른 사용자는 해당 공개 키(public key)를 통해 커밋이 실제로 해당 작성자에 의해 만들어졌는지 검증할 수 있다.

GitHub은 이 서명을 검증하여, 신뢰할 수 있는 서명일 경우 커밋 옆에 “✅ Verified” 배지를 표시한다. 이 표시를 통해 커밋의 출처를 쉽게 확인할 수 있으며, 오픈소스 프로젝트나 협업 환경에서는 신뢰성을 높이는 효과가 있다.

 

Verified 표시된 서명된 commit

 

Git은 v1.8.3 버전부터 GPG 서명 기능을 공식적으로 지원한다. 서명된 커밋이나 태그를 검증할 수 있으며, --verify-signatures 옵션을 사용해 병합 시 서명을 확인할 수도 있다. 다만, Git은 기본적으로 서명되지 않은 커밋을 자동으로 차단하지 않으며, 해당 동작을 강제하려면 별도의 설정이나 훅(hook)을 직접 추가해야 합니다.

GitHub에서는 이를 좀 더 쉽게 제어할 수 있다.
Repository Settings → Branch protection rules에서 “Require signed commits” 옵션을 활성화하면, 해당 브랜치에는 서명된 커밋만 푸시할 수 있도록 제한할 수 있다.

 

Git은 커밋 객체를 생성할 때 기본적으로 SHA 해시(SHA-1 또는 SHA-256) 를 사용하여 데이터의 무결성(Integrity) 을 보장한다. 즉, 누군가 커밋 내용을 임의로 수정하면 해시가 달라지기 때문에 쉽게 위조를 탐지할 수 있다.

반면, GPG 서명(Signing) 은 데이터의 무결성뿐 아니라 작성자 신원(Authenticity) 을 추가로 검증하는 역할을 한다. 따라서 두 기능은 상호 보완적이다.
SHA는 “데이터가 변조되지 않았는가?”를,
GPG 서명은 “이 데이터를 정말 이 사람이 만들었는가?”를 보장한다고 볼 수 있다.

 

요약하자면 Git은 기본적으로 데이터 무결성을 보장하지만, 작성자 신원까지 검증하지는 않는다.
GPG 또는 SSH 기반 서명 기능을 활성화하면 커밋의 신뢰성을 높일 수 있고, GitHub의 “Require signed commits” 설정을 통해 프로젝트 수준에서 이를 강제할 수도 있다.

개인 프로젝트에서는 필수는 아니지만, 협업 환경이나 오픈소스 프로젝트에서는 GPG 서명을 사용하는 것이 보안적·관리적 측면에서 유리하다.

 

이 포스트에서는 GPG key를 생성하고 Git 및 GitHub에 설정하여 서명된 commit을 통해 신뢰성을 향상시키는 방법에 대해 다뤄본다.

 

PGP & GPG

PGP(Pretty Goog Privacy)는 대칭키(비밀키) 및 비대칭키(공개키) 방식을 사용하여 데이터를 암/복호화하고 전자서명을 할 수 있는 암호화 소프트웨어이다. 1991년에 Phil Zimmermann에 의해 개발되었으며 시만텍에서 유료로 판매되고 있다. 이에 PGP에서 파생된 오픈소스기반의 OpenPGP가 현재 전세계 email 암호화 표준으로 널리 사용되고 있다.

GPG라고 불리는 GnuPG(GNU Privacy Guard)는 OpenPGP로 구현된 PGP(RFC4880) 암호화 소프트웨어이다. Git 설치시 같이 설치되며, 설치폴더의 "usr\bin" 폴더에서 찾을 수 있다. (e.g. "C:\Program Files\Git\usr\bin\gpg.exe")

아래와 같은 명령으로 GPG 버전을 확인 할 수 있다.

$ gpg --version

또한, 아래 내용들은 GPG v2.1.17 이상에서만 수행 가능하다.

 

GPG key 생성

현재 %PATH%가 지정되어 있지 않기 때문에 gpg.exe가 위치한 폴더에서 Git Bash를 실행한다.

아래 명령을 입력하여 GPG key를 생성한다.

$ gpg --full-generate-key

Step 1. key 알고리즘 선택

GitHub에서는 현재 RSA, ElGamal, DSA, ECDH, ECDSA, EdDSA 알고리즘을 지원하고 있다. 원하는 key 알고리즘을 선택하거나 default인 "(1) RSA and RSA (default)"를 선택한다.

Step 2. key 크기 선택

GitHub에서 key의 크기는 적어도 4096 bits 이상이어야 한다. 4096을 입력한다.

Step 3. key 유효기간 선택

key가 유출될 경우 GitHub에 등록된 key를 삭제하고 재생성하면 되기 때문에 유효기간은 "key does not expire"로 선택한다.

Step 4. 사용자 정보 입력

Git 및 GitHub에서 사용중인 name 및 email을 입력한다. comment는 입력하지 않아도 관계없다.

만약 email을 비공개로 하고 싶다면 GitHub에서 제공하는 `no-reply` email 주소로 설정 가능하다.

Step 5. secure passphrase 설정

commit시 입력하는 보안암호를 설정한다. 나중에 설정을 통해 보안암호 입력 주기를 조절 가능하다.

모든 단계가 끝났다면 GPG key가 생성된다.

 

GPG key 확인

아래 명령을 통해 GPG key ID를 확인한다

$ gpg --list-secret-keys --keyid-format=long
/Users/hubot/.gnupg/secring.gpg
------------------------------------
sec   4096R/3AA5C34371567BD2 2016-03-10 [expires: 2017-03-10]
uid                          Hubot 
ssb   4096R/42B317FD4BA89E7A 2016-03-10

위 예시에서는 `3AA5C34371567BD2`가 GPG key ID이다. 해당값은 아래에서 설정하는 동안 계속 사용되기 때문에 잠시 따로 저장해놓도록 하자.

 

Git 설정

Git 전역설정에 GPG key ID를 세팅한다.

$ git config --global user.signingkey 3AA5C34371567BD2

이제 아래와 같이 `-S` 옵션을 통해 signing commit을 할 수 있다.

$ git commit -a -S -m "signed commit message"

매번 옵션을 주기 번거롭다면 Git 전역설정에 항상 자동서명하도록 설정도 가능하다.

$ git config --global commit.gpgsign true

만약 CLI가 아닌 `VSCode`를 사용하는 경우 설정의 "Git: Enable Commit Signing"(`git.enableCommitSigning`)을 체크해서 위 자동서명 설정과 동일한 효과를 누릴수도 있다. `git config --global`로 전역설정을 한다면 해당 설정은 관계없다.

`Visual Studio`로 commit하는 경우 `gpg` 경로 문제로 오류가 발생 할 수 있다. 아래와 같이 전역설정에 `gpg` 경로를 추가하여 문제를 해결할 수 있다.

$ git config --global gpg.program "C:\Program Files\Git\usr\bin\gpg.exe"

 

GPG 설정

매번 commit시에는 `secure passphrase`를 입력해야 한다. 너무 번거롭다면 gpg agent 환경설정 파일을 통해 입력 주기를 변경 가능하다. "%HomePath%\.gnupg"폴더에 `gpg-agent.conf`파일을 생성하고 아래의 내용을 입력 및 저장한다.

default-cache-ttl 28800
max-cache-ttl 28800

여기서 28800은 초를 나타내며 최초 commit에서 secure passphrase를 입력하면 8시간동안 cache하여 묻지 않겠다는걸 의미한다. 아래 내용을 참조하여 개인 입맛에 맞게 설정하면 된다.

  • default-cache-ttl : access(commit)할 때마다 갱신되는 캐시 타이머. (default 10분)
  • max-cache-ttl : access해도 갱신되지 않는 최대 캐시 타이머. (default 2시간)

gpg-agent 데몬이 동작하는 동안에는 바로 적용이 안될 수 있기 때문에 PC를 재부팅하거나 아래와 같이 데몬을 재시작 시킨다.

gpgconf --kill gpg-agent
gpg-agent --daemon --use-standard-socket

 

GitHub 설정

아래 명령을 통해 GPG key ID 값을 ASCII 값으로 export한다.

$ gpg --armor --export 3AA5C34371567BD2
# Prints the GPG key ID, in ASCII armor format

-----BEGIN PGP PUBLIC KEY BLOCK-----

...

-----END PGP PUBLIC KEY BLOCK-----

GitHub사이트의 "계정 > Settings > SSH and GPG keys"로 들어가 "New GPG key" 버튼을 클릭하고 해당 key를 나타내는 제목과 위 ASCII값의 "-----BEGIN PGP PUBLIC KEY BLOCK-----"부터 "-----END PGP PUBLIC KEY BLOCK-----"까지를 복사해서 붙여넣은 후 "Add GPG key" 버튼을 클릭해서 key 등록을 마무리한다. 이제 개인키를 이용해 commit을 전송하면 GitHub에서는 공개키를 이용해 해당 서명의 유효성을 검사하게 된다.

 

등록이 완료되면 해당 GPG key에 대한 간략한 정보가 표시되며, key는 복수개가 등록이 가능하다.

참고로 GitHub 계정 생성시 GitHub's verified signature라고 해서 내부적으로 GPG key가 등록이 되어있으며 GitHub사이트를 통해 commit등의 작업시에는 해당 key로 singning이 일어난다.

  • GitHub's verified : "This commit was created on GitHub.com and signed with GitHub’s verified signature."
  • committer's verified : "This commit was signed with the committer’s verified signature."

또한, 경계모드(Vigilant mode)의 "Flag unsigned commits as unverified" 옵션을 활성화 시키면 인증되지 않는 commit 등을 `unverified` 등으로 시각적으로 표시해주기 때문에 보안에 더욱 도움이 된다.

경계모드(Vigilant mode)

 

추가 : GPG key 내보내기 및 가져오기

포맷, 기기변경 등으로 인해 GPG Key를 백업 및 복구해야 하는 상황에서는 아래와 같이 export/import가 가능하다

키 ID 확인

gpg --list-secret-keys	// 비밀키
# 또는 gpg --list-keys	// 공개키

각각 "uid [상태] {키 ID} <이메일>" 형식으로 출력된다

내보내기

gpg --export-secret-key {키 ID} > private.key
# 또는 gpg --export {키 ID} > public.key	// 공개키만 필요시

가져오기

gpg --import private.key
# 또는 gpg --import public.key	// 공개키만 필요시

 

References

https://www.gnupg.org/

 

The GNU Privacy Guard

GnuPG is a complete and free implementation of the OpenPGP standard as defined by RFC4880 (also known as PGP). GnuPG allows you to encrypt and sign your data and communications; it features a versatile key management system, along with access modules for a

www.gnupg.org

https://git-scm.com/book/ko/v2/Git-%EB%8F%84%EA%B5%AC-%EB%82%B4-%EC%9E%91%EC%97%85%EC%97%90-%EC%84%9C%EB%AA%85%ED%95%98%EA%B8%B0

 

Git - 내 작업에 서명하기

Git은 암호학적으로 안전하다. 하지만, 그냥 되는 건 아니다. 저장소에 아무나 접근하지 못하게 하고 진짜로 확인된 사람에게서만 커밋을 받으려면 GPG를 이용한다.

git-scm.com

https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification

 

About commit signature verification - GitHub Docs

About commit signature verification You can sign commits and tags locally, to give other people confidence about the origin of a change you have made. If a commit or tag has a GPG or S/MIME signature that is cryptographically verifiable, GitHub marks the c

docs.github.com

https://director-joe.kr/74

 

GPG key 생성 방법, github 연결 방법 및 git 설정 방법

GPG는 GnuPG = GNU Privacy Guard로 PGP(Preety Good Privacy)를 대체하는 암호화, 복호화 프로그램입니다. 깃허브 커밋 내역을 보면 커밋 메시지 옆에 "Verified" 로고가 있는 경우가 있는데요, 커밋이 gpg(또는..

director-joe.kr

https://irostub.github.io/information/gpg-how-to-export-and-import-gpg-key-commit-sign-other-machine/

 

다른 기기로 gpg키 복사 및 커밋 서명(How to export and import gpg key, commit sign other machine)

GPG Key를 복사하여 옮기기

irostub.github.io

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/12   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함