GitHub에서 소스코드를 보다 보면 종종 아래 그림과 같은 Verified라는 배지가 붙은 커밋을 볼 수 있습니다.
작성자가 커밋에 본인이 직접 작성한 것이라고 서명(Sign)한 커밋을 나타 냅니다. 이러한 서명은 gpg 인증을 통해서 할 수 있는데, 커밋을 어떻게 하여야 하며, GitHub에서는 어떻게 하는지 설명합니다.
왜 커밋에 사인을 해야 하는가?
Git을 처음 접했을 때, 가졌던 의문 중 하나가 왜? 커밋의 작성자에 대한 검증을 하지 않는가? 였습니다. 좀 더 설명해 보자면 git을 처음 설치하게 되면 대부분 다음과 같은 설정을 하게 됩니다.
git config --global user.email bitlog@tistory.com
git config --gloabl user.name bitlog
# bitlog@tistory.com 은 존재하지 않습니다.
그리고 그대로 커밋을 하고 push 를 하면, 그것은 내가 작성한 커밋이 됩니다. 그렇다면 다른 누군가가 커밋할 때 내 이름과 이메일을 이용하여, 커밋한다면 어떻게 될까요? 내가 작성한 커밋으로 보이게 되는 거죠. git이 커밋할 때는 온라인 인증을 거치지 않기 때문에 이런 일이 가능합니다. (착각하기 쉽지만, 설정에 작성한 정보는 GitHub이나 GitLab에 등록된 계정의 정보와는 전혀 무관합니다.) 이러한 것을 방지하기 위해, 커밋에 서명하는 것이 가능합니다.
어차피 코드 베이스를 수정하는 사람은 동료들이고, 서로 믿고 의지하는 상대이니 반드시 해야하는 것은 아니지만, 내가 한 커밋이라는 것을 증명하기 (그리고 커밋 이력에 살짝 뽀대를 ) 위해서 서명을 하는 건 나쁘지 않아 보입니다.
커밋에 사인하기.
( 윈도우에서 git bash 기준으로 ) 커밋에 gpg 서명을 하려면 먼저 gpg 서명을 위한 애플리케이션을 설치해야 합니다. GnuPG의 다운로드 페이지에 접속하여, Gpg4win을 다운로드합니다. 설치 후에 정상적으로 설치되었는지 확인합니다.
C:\>gpg --version
gpg (GnuPG) 2.2.19
libgcrypt 1.8.5
Copyright (C) 2019 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: C:/Users/bitlog/AppData/Roaming/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
gpg 서명을 하기 위해서 키를 생성해 줍니다. "gpg --get-key"를 입력하고 이름과 이메일을 적어 줍니다. 이후 서명을 위한 비밀번호를 입력하면 키가 만들어집니다.
D:\>gpg --gen-key
gpg (GnuPG) 2.2.19; Copyright (C) 2019 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Note: Use "gpg --full-generate-key" for a full featured key generation dialog.
GnuPG needs to construct a user ID to identify your key.
Real name: bitlog
Email address: bitlog@tistory.com
You selected this USER-ID:
"bitlog <bitlog@tistory.com>"
Change (N)ame, (E)mail, or (O)kay/(Q)uit? O
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key D4E0D70A744F9320 marked as ultimately trusted
gpg: directory 'C:/Users/bitlog/AppData/Roaming/gnupg/openpgp-revocs.d' created
gpg: revocation certificate stored as 'C:/Users/bitlog/AppData/Roaming/gnupg/openpgp-revocs.d\A34C1BA7E956E35B11BECFB9D4E0D70A744F9320.rev'
public and secret key created and signed.
pub rsa2048 2020-05-09 [SC] [expires: 2022-05-09]
A34C1BA7E956E35B11BECFB9D4E0D70A744F9320
uid bitlog <bitlog@tistory.com>
sub rsa2048 2020-05-09 [E] [expires: 2022-05-09]
생성될 때, gpg: key 에 나오는 키는 잘 기록해 두세요. 이렇게 만들어진 키는 "gpg --list-keys" 명령으로 확인할 수 있습니다.
D:\>gpg --list-keys
C:/Users/bitlog/AppData/Roaming/gnupg/pubring.kbx
--------------------------------------------------
pub rsa2048 2020-05-09 [SC] [expires: 2022-05-09]
A34C1BA7E956E35B11BECFB9D4E0D70A744F9320
uid [ultimate] bitlog <bitlog@tistory.com>
sub rsa2048 2020-05-09 [E] [expires: 2022-05-09]
이제 git 에 키를 등록하고, 서명을 포함한 커밋을 합니다. 서명을 포함한 커밋은 -S 옵션을 추가해 주어야 합니다. 커밋 후에 서명된 커밋을 확인하려면 "git log --show-signature"로 할 수 있습니다.
# git 설정에 서명에 사용할 키 등록
D:\workspace\temp\sign-git>git config --global user.signingkey D4E0D70A744F9320
# 서명을 포함한 커밋
D:\workspace\temp\sign-git>git commit -S -m "signed commit"
[master (root-commit) d6c5224] signed commit
1 file changed, 2 insertions(+)
create mode 100644 README.md
# 로그에서 서명 확인
D:\workspace\temp\sign-git>git log --show-signature
commit d6c52242e5e139e5a390d938e0ad2d1b2052dd25 (HEAD -> master)
gpg: Signature made 05/09/20 23:18:09 <B4><EB><C7><D1><B9><CE><B1><B9> <C7><A5><C1><D8><BD><C3>^M
gpg: using RSA key 46E1C86E0D75619D7B34431FCD943708F573E9CE^M
gpg: Good signature from "bitlog <bitlog@tistory.com>" [ultimate]^M
Author: bitlog <bitlog@tistory.com>
Date: Sat May 9 23:18:09 2020 +0900
signed commit
그리고 커밋할 때, -S 옵션을 붙이지 않고 싶다면, git 설정에 "commit.gpgsign true"를 추가해 줍니다.
> git config --global commit.gpgsign true
GitHub에 표시하기.
서명된 커밋을 GitHub에 푸시하면 예상과는 달리 인증되지 않음(Unverified)가 표시됩니다.
GitHub에는 아까 생성한 key가 등록되지 않았기 때문입니다. 우측 상단에 프로필에서 설정 버튼을 눌러 "SSH and GPG keys" 메뉴의 "New GPG key" 버튼을 눌러 아까 생성한 key를 익스포트 하여 등록해 줍니다.
D:\workspace\temp\sign-git>gpg --armor --export D4E0D70A744F9320
-----BEGIN PGP PUBLIC KEY BLOCK-----
...
-----END PGP PUBLIC KEY BLOCK-----
key를 등록한 이후에 다시 확인해보면 인증된 것을 확인할 수 있습니다.
이제 뽀대나는 커밋을 할 수 있게 되었습니다. 어려운 내용은 아니니 한번 적용해보세요. 아 그런데, 모든 툴 GitHub Descktop 에서 커밋에 서명하기를 지원하는 것은 아닙니다.
참고 : https://help.github.com/en/github/authenticating-to-github/signing-commits