목차

, , , , , ,

GPG (GNU Privacy Guard)

gpg는 GnuPG의 OpenPGP 명령행 도구다. 공개키 암호화, 전자서명, 서명 검증과 keyring 관리를 제공한다.

Summary

Installation

# Debian / Ubuntu
sudo apt update
sudo apt install gnupg
 
# Fedora / RHEL
sudo dnf install gnupg2
 
# macOS
brew install gnupg
 
# Windows: GnuPG가 안내하는 Gpg4win bundle
winget install --id GnuPG.Gpg4win --exact
 
# 설치 확인
gpg --version

Usage

gpg [options] [files]

Key identification

USER-ID에는 이름, email, key ID, fingerprint 등을 쓸 수 있지만 script와 중요한 작업에서는 전체 fingerprint를 권장한다.

# 공개키와 fingerprint 확인
gpg --list-keys
gpg --fingerprint USER@example.com
 
# machine-readable inventory
gpg --batch --with-colons --fingerprint
 
# secret key가 있는 key 확인
gpg --list-secret-keys --keyid-format long
짧은 key ID나 email만으로 key를 신뢰하지 않는다. 전체 fingerprint를 대면, 통화, 공식 website 등 key를 받은 경로와 독립된 channel로 확인한다.

Key generation

Interactive wizard는 algorithm, expiry와 identity를 단계별로 설정한다.

gpg --full-generate-key

Quick interface는 명시한 값을 바로 적용한다.

# 현재 GnuPG가 지원하는 기본 algorithm으로 생성
gpg --quick-generate-key "Example User <[email protected]>" default default 1y
 
# 생성 결과와 fingerprint 확인
gpg --list-secret-keys --keyid-format long
gpg --fingerprint "[email protected]"
 
# expiry 연장
gpg --quick-set-expire PRIMARY-FINGERPRINT 1y
 
# revocation certificate 생성
gpg --output revoke.asc --generate-revocation PRIMARY-FINGERPRINT

Import and export

Public key

# ASCII-armored public key export
gpg --armor --output public-key.asc --export PRIMARY-FINGERPRINT
 
# file의 key 정보와 fingerprint를 먼저 확인
gpg --show-keys --with-fingerprint public-key.asc
 
# 확인 후 keyring에 import
gpg --import public-key.asc

Secret key backup

# 안전한 offline 경로에만 secret key export
gpg --armor --output secret-key-backup.asc \
  --export-secret-keys PRIMARY-FINGERPRINT
 
# ownertrust 별도 backup
gpg --export-ownertrust > ownertrust.txt
–export-secret-keys 출력은 private key material이다. 공유, email 전송, cloud 동기화 또는 Git commit을 금지하고 encrypted offline storage에 보관한다. Public key를 보낼 때는 반드시 –export를 사용한다.

복원은 격리된 GNUPGHOME에서 먼저 시험할 수 있다.

restore_home="$(mktemp -d)"
chmod 700 "$restore_home"
GNUPGHOME="$restore_home" gpg --import secret-key-backup.asc
GNUPGHOME="$restore_home" gpg --import-ownertrust ownertrust.txt
GNUPGHOME="$restore_home" gpg --list-secret-keys

Encrypt and decrypt

Public-key encryption

# recipient public key로 암호화
gpg --output document.txt.gpg \
  --encrypt --recipient RECIPIENT-FINGERPRINT document.txt
 
# 여러 recipient와 자신도 복호화할 수 있게 암호화
gpg --output document.txt.gpg --encrypt \
  --recipient RECIPIENT-FINGERPRINT \
  --recipient SELF-FINGERPRINT \
  document.txt
 
# 복호화
gpg --output document.txt --decrypt document.txt.gpg

Symmetric encryption

gpg --symmetric --cipher-algo AES256 --output archive.tar.gpg archive.tar
gpg --output archive.tar --decrypt archive.tar.gpg

Passphrase는 command argument나 environment variable로 넘기지 말고 pinentry에서 입력한다. Recipient가 여러 명이거나 장기간 운영할 때는 passphrase 공유보다 public-key 방식이 관리하기 쉽다.

Sign and verify

Detached signature

# 원본과 별도 signature 생성
gpg --local-user SIGNER-FINGERPRINT \
  --armor --detach-sign release.tar.gz
 
# signature와 원본을 함께 검증
gpg --verify release.tar.gz.asc release.tar.gz

Detached signature 검증은 signature file과 원본 file을 모두 명시한다. 원본을 생략하면 filename 추론 또는 stdin 동작에 의존할 수 있다.

Cleartext signature

gpg --local-user SIGNER-FINGERPRINT --clear-sign message.txt
gpg --verify message.txt.asc

Signed file

gpg --local-user SIGNER-FINGERPRINT --sign document.txt
gpg --output document.txt --decrypt document.txt.gpg
Download 검증에서는 먼저 공식 channel에서 signing key fingerprint를 확인하고 public key를 import한 뒤, signature와 artifact를 함께 검증한다. Good signature만 보지 말고 출력된 fingerprint와 expected signer를 대조한다.

Keyserver and WKD

# fingerprint로 keyserver에서 받기
gpg --keyserver hkps://keys.openpgp.org \
  --receive-keys FULL-FINGERPRINT
 
# Web Key Directory 등으로 email address의 key 찾기
gpg --locate-keys user@example.com
 
# 자신의 public key 전송
gpg --keyserver hkps://keys.openpgp.org \
  --send-keys FULL-FINGERPRINT

Options

Option 설명
–armor, -a ASCII-armored output을 만든다.
–recipient, -r 암호화 recipient를 지정한다. 반복 가능하다.
–local-user, -u 서명 또는 복호화에 사용할 local key를 지정한다.
–output FILE, -o FILE stdout 대신 출력 file을 지정한다.
–homedir DIR 별도 GnuPG home을 사용한다. Command line에서만 지정한다.
–batch Interactive prompt를 금지한다. Automation에서는 –status-fd–with-colons도 검토한다.
–dry-run, -n 지원되는 operation에서 실제 변경을 피한다. 모든 command의 완전한 simulation을 보장하지 않는다.
–verbose, -v 진단 정보를 늘린다.

Config

~/.gnupg/gpg.conf, dirmngr.conf, gpg-agent.conf, GNUPGHOME, file permission과 안전한 예시는 GPG configuration에서 다룬다.

gpgconf --list-dirs
gpgconf --check-options gpg
gpgconf --reload all

Automation

Human-readable message를 parsing하지 말고 machine interface를 사용한다.

gpg --batch --no-tty --status-fd 2 \
  --output OUTPUT --decrypt INPUT.gpg
 
gpg --batch --with-colons --list-keys

Troubleshooting

No public key

서명자의 public key가 local keyring에 없다. 공식 source에서 fingerprint를 확인한 뒤 key를 import하거나 WKD/keyserver에서 받아 다시 fingerprint를 대조한다.

gpg --show-keys --with-fingerprint signer.asc
gpg --import signer.asc
gpg --verify artifact.sig artifact

Unusable public key

Recipient key가 expired/revoked되었거나 encryption-capable subkey가 없을 수 있다.

gpg --list-options show-unusable-subkeys \
  --with-subkey-fingerprint --list-keys RECIPIENT

Inappropriate ioctl for device / pinentry failure

Remote shell이나 container에서 pinentry가 TTY를 찾지 못하는 경우가 많다.

export GPG_TTY="$(tty)"
gpgconf --kill gpg-agent
gpgconf --launch gpg-agent

GPG_TTY를 shell startup file에서 현재 terminal에 맞춰 설정하고, headless automation에서는 passphrase 전달 방식을 임의로 우회하지 말고 agent/pinentry와 secret injection 설계를 분리한다.

Unsafe permissions on homedir

GnuPG home과 secret file의 owner/permission을 확인한다.

chmod 700 ~/.gnupg
find ~/.gnupg -type f -exec chmod 600 {} \;

Shared directory나 network filesystem에 secret keyring을 두지 않는다. Existing socket 등 일부 entry는 file이 아니므로 무조건 재귀 chmod하지 않는다.

Compatibility

Deprecated / Legacy

Help

gpg --help (GnuPG 2.2.20)

See Also

History