GPG는 GnuPG = GNU Privacy Guard로 PGP(Preety Good Privacy)를 대체하는 암호화, 복호화 프로그램입니다.

깃허브 커밋 verified 마크

깃허브 커밋 내역을 보면 커밋 메시지 옆에 "Verified" 로고가 있는 경우가 있는데요, 커밋이 gpg(또는 pgp) 키를 이용해 서명되었다는 것을 나타냅니다.

왜 굳이 커밋에 인증을 해야 할까요? 기본적으로 git 커밋에는 이름과 이메일이 들어갑니다. 그런데 악의적인 사용자가 git 설정에 제 이름과 이메일을 써서 멀웨어를 만든 뒤 깃허브에 릴리즈했다고 생각해봅시다. 나중에 멀웨어임이 밝혀지면 저는 그 멀웨어에 관여하지 않았지만 커밋 내역에 이름과 이메일이 들어가있어 범인으로 오인될 수 있습니다. 또 팀원의 깃헙계정이 해킹돼 악성 코드가 심어진 PR을 보냈다고 생각해봅시다. 이럴때 문제가 생길 수 있습니다.

그래서 GPG 키를 이용해 서명을 추가하면 "이 커밋은 확실히 내가 만들었다"라는 걸 입증할 수 있습니다.

GPG 키를 생성하고 github 계정에 등록하는 법을 알아보겠습니다.

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

※ Ubuntu 18.04, gpg 2.2.4 기준으로 작성됐습니다.

 

1. gpg key 생성

$ gpg --full-generate-key
gpg (GnuPG) 2.2.4; Copyright (C) 2017 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.

Please select what kind of key you want:
   (1) RSA and RSA (default)
   (2) DSA and Elgamal
   (3) DSA (sign only)
   (4) RSA (sign only)
Your selection? 1

RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (3072) 4096
Requested keysize is 4096 bits

Please specify how long the key should be valid.
         0 = key does not expire
      <n>  = key expires in n days
      <n>w = key expires in n weeks
      <n>m = key expires in n months
      <n>y = key expires in n years
Key is valid for? (0)
Key does not expire at all

Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: John Doe
Email address: johndoe@email.com
Comment:
You selected this USER-ID:
    "John Doe <johndoe@email.com>"

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

gpg --full-generate-key 명령어를 사용해 키를 생성합니다. Github에 사용하는 키 유형은 반드시 RSA에 키 사이즈는 최소 4096비트여야 한다고 합니다. 키 생성 과정을 요약하면 다음과 같습니다.

  • 암호화 방식: RSA and RSA
    • 기본값이므로 그냥 엔터 치거나 1 입력하면 됩니다
  • 키 사이즈: 4096비트
    • 기본값은 3076 비트입니다. 4096을 입력해줘야 합니다.
  • 키 유효기간: 0
    • 키 유효기간을 설정한 경우 유효기간이 지나면 해당 키로 인증한 커밋들의 서명이 무효가 됩니다. 깃허브에서는 Verified 로고가 없어집니다.
    • 키 관리만 잘 하면 유효기간을 0(무한)으로 해도 무방합니다. 단, 키 유출이 의심되는 경우 폐기해줘야 하는 점 참고해주세요.
  • 이름, 이메일, 주석
    • Comment는 입력하지 않아도 됩니다
    • 이메일을 공개하고 싶지 않다면 Github에서 제공하는 no-reply 이메일 주소를 사용하세요
  • 키에 대한 암호(Passphrase)
    • 커밋할 때 passphrase를 입력해야 커밋이 됩니다

GPG 2.1.17 미만 버전은 gpg --full-generate-key 명령어가 없으니 gpg --default-new-key-algo rsa4096 --gen-key 명령어를 사용합니다.

GPG 키 passphrase 설정창

마지막으로 passphrase를 입력할때는 이런 다이얼로그가 나옵니다. 패스워드 없이 만들려고 해봤는데 안되네요.

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.

전부 입력했다면 랜덤 바이트를 만들어내니 그동안 마우스를 움직이거나 키보드를 치거나 디스크를 쓰는 등 해서 더 좋은 랜덤값이 나오게 엔트로피를 만들라고 나옵니다. 그냥 가만히 있어도 되긴 합니다.

pub   rsa4096 2020-09-08 [SC]
      ABCDEFG....
uid                      John Doe <johndoe@email.com>
sub   rsa4096 2020-09-08 [E]

 

1.1 랜덤값 생성 부분에서 멈추는 경우

랜덤바이트 만들어야되니 엔트로피가 더 필요하다라고 계속 나오는 경우 키 생성을 멈추고 RNG(random number generator)를 이용해봅니다. (GPG does not have enough entropy - serverfault)

$ sudo apt install rng-tools
$ sudo rngd -r /dev/urandom

rng-tools를 설치한 다음 키 생성 전에 쉘 하나를 더 열어서 rngd를 실행시켜놓고 키를 생성해보세요

 

2. Github gpg key 등록

GPG 키를 생성했으면 이제 깃허브 계정에 등록해봅시다.

$ gpg --list-secret-keys --keyid-format LONG
/home/ubuntu/.gnupg/pubring.kbx
-------------------------------
sec   rsa4096/ABCDEFGHIJKLMNOP 2020-09-08 [SC]
      BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
uid                 [ultimate] John Doe <johndoe@email.com>
ssb   rsa4096/CCCCCCCCCCCCCCCC 2020-09-08 [E]

gpg --list-secret-keys --keyid-format LONG을 입력한 뒤 위 코드에서 ABCD...NOP로 표시된 부분을 복사한 뒤 아래 명령어를 입력합니다.

$ gpg --armor --export ABCDEFGHIJKLMNOP
-----BEGIN PGP PUBLIC KEY BLOCK-----

mABlP0zm3j90fjKazUnb7vjj99Qv6eWrggnOdfwelaJ/fekj39sjdf9/djf93jsfadfLMm
3f9sjdfklaAA/VatcxyN5ZzPKhWfj3+DOnQRMzTV+/AcW3ezA6HFcIPRkHGrZRmJzEH3Ly
....
-----END PGP PUBLIC KEY BLOCK-----

위 명령어를 입력하면 ASCII-Armor 포맷의 pgp public key 블록이 나오는데 전부 복사합니다.

깃허브 SSH, GPG 키 설정

Github - Settings로 들어간 다음 SSH and GPG keys에서 "New GPG key" 버튼을 누릅니다.

GPG 키 추가

아까 복사했던 내용을 붙여넣고 "Add GPG key" 버튼을 누릅니다

새로운 GPG키가 추가된 모습

그럼 이제 깃허브 GPG 키 설정이 완료됐습니다. 앞으로 해당 GPG Key ID 서명이 추가된 커밋은 Verified 아이콘이 나오게 됩니다.

 

3. Git 설정

$ git config --global user.signingkey ABCDEFGHIJKLMNOP

git config의 user.signingkey를 GPG Key ID를 입력해줍니다. 아까 list-secret-keys로 봤을 때 ABC... 부분입니다.

$ git commit -S -m "커밋 메시지"

이제 커밋할 때 -S 옵션을 넣으면 커밋에 서명이 됩니다.

그런데 매번 이렇게 하긴 귀찮기 때문에 config을 수정해서 자동으로 gpg 서명을 해주도록 할 수 있습니다.

$ git config --global commit.gpgsign true

이제 커밋할 때 종종 passphrase를 입력하라고 나오고, 입력해야 커밋을 할 수 있습니다.

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

key의 비밀번호를 너무 자주 입력하는 것 같다 싶으면 다시 입력하는 주기를 설정할 수 있습니다. ~/.gnupg/gpg-agent.conf에 위 내용을 추가합니다. GPG 2.1 미만 버전에서는 max-cache-ttl 대신 maximum-cache-ttl을 사용해야 한다고 합니다.

위 내용은 28800초, 즉 8시간동안 패스워드를 물어보지 않게 설정하는 것입니다. 뒤에 초를 조정하시면 됩니다.

 

GPG 서명된 커밋 확인 방법

git log GPG 서명 보기 커맨드

git log --show-signature를 이용해 커밋들의 gpg 서명을 확인할 수 있습니다.

 

오류 발생시

error: gpg failed to sign the data

$ git commit -m "test"
error: gpg failed to sign the data
fatal: failed to write commit object

이렇게 나오는 경우 ~/.bash_profile에 아래 내용을 추가해줍니다.

export GPG_TTY=$(tty)

그 다음 bash_profile을 다시 로드해줍니다.

$ source ~/.bash_profile

"gpg: signing failed: Inappropriate ioctl for device"라고 나올 때도 동일하게 하시면 됩니다. (github issue)

  1. Blog Icon
    Jemin

    gpg failed to sign the data 오류때문에 삽질하고 있었는데 좋은 포스팅 감사합니다.
    덕분에 쉽게 해결 했습니다.
    건승하세요~!