깃에 GPG(GNU Privacy Guard) 설정

먼저 GPG(GNU Privacy Guard)가 뭔지 간단하게 살펴보자.  GPG는 RFC4880에 따라 OpenPGP를 완전하게 독립적으로 구현한 구현체다. 사용자의 데이터나 통신을 암호화하거나 사인할 수 있는 명령어 툴을 제공한다.

깃은 변경사항을 리파지토리에 저장할 때, 필요하다면 GPG를 이용해 사인을 하도록 지원한다.  여기서는 필요성 보다는 그래서 어떻게 설정하면 되는지 알아보자.

  1. 윈도우용 GPG 도구 설치
  2. 콘솔창에서 등록된 키가 있는지 확인 먼저 확인하자.
    >gpg -K
  3. 키가 없다면, 키를 생성한다. (기본값으로 대부분 충분)
    >gpg --gen-key
    gpg (GnuPG) 2.0.28; Copyright (C) 2015 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?
    RSA keys may be between 1024 and 4096 bits long.
    What keysize do you want? (2048)
    Requested keysize is 2048 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: your name
    Email address: your.email@example.com
    Comment:
    You selected this USER-ID:
        "your name <your.email@example.com>"
    
    Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
    You need a Passphrase to protect your secret key.
    
    gpg: AllowSetForegroundWindow(1520) failed: 액세스가 거부되었습니다.
    
    gpg: AllowSetForegroundWindow(12472) failed: 액세스가 거부되었습니다.
    
    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 A35FD1C6 marked as ultimately trusted
    public and secret key created and signed.
    
    gpg: checking the trustdb
    gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
    gpg: depth: 0  valid:   2  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 2u
    pub   2048R/A35FD1C6 2015-08-27
          Key fingerprint = 9442 AA8B A90E 8502 740B  1C9F 6D33 5225 A35F D1C6
    uid       [ultimate] your name <your.email@example.com>
    sub   2048R/9CB4DE6C 2015-08-27
  4. 사용자의 signingkey를 config에 등록한다.
    >git config --global user.signingkey A35FD1C6
  5. 필요하다면, 항상 사인하도록 config에 설정한다.
    >git config --global commit.gpgsign true
  6. 5번을 했다면, 아래와 같이 -S 옵션 없이 커밋할 수 있다.
    >git commit -m "your message."
  7. 커밋이 사인되었는지 아래와 같이 확인할 수 있다.
    >git log --show-signature
    commit 595d8f81aafe06c9dd6576658bde4c7b162580b8
    gpg: Signature made Thu Aug 27 13:10:46 2015     using RSA key ID A35FD1C6
    gpg: Good signature from "your name <your.email@example.com>"
    gpg: WARNING: This key is not certified with a trusted signature!
    gpg:          There is no indication that the signature belongs to the owner.
    Primary key fingerprint: 2413 CF8A 8F47 C668 E9A6  76BF D36D 2D40 CF1D 8C60
    Author: your name <your.email@example.com>
    Date:   Thu Aug 27 13:10:46 2015 +0900
    
        your message.
    

그 밖에

키를 잘못 만들었다면,

> gpg --delete-secret-keys A35FD1C6
...
> gpg --delete-keys A35FD1C6
...

순서로 삭제한다. 개인키(private key)를 먼저 삭제해야, 공개키(public key)를 삭제할 수 있다. 참고로, 한 번 삭제하면 복구가 불가능하므로 답이 없다.

참고로, 리누스(Linus)는 모든 commit을 사인하는 것은 올바르지 않다고 지적한 바 있다. 다른 사람에게 보낼 때 한번만 사인하는 것으로 충분하다는 것이다.

위의 가이드를 따랐는데도 여전히 아래와 같은 에러를 만난다면, 다음 글을 참고하자.

>git commit -m "your message"
gpg: skipped "your name <your.email@example.com>": secret key not available
gpg: signing failed: secret key not available
error: gpg failed to sign the data
fatal: failed to write commit object

참조