티스토리 뷰
개요
Git 및 GitHub은 기본적으로 `git commit`(및 `git tag`)의 name 및 email만 체크하고 보안적인 측면은 고려하지 않는다. 이는 의도하지 않은 제3자가 name 및 email만 알면 commit을 통한 repository의 변경이 가능하다는 의미이며, 이를 검증하고 방어하기 위해 Git 및 GitHub에서는 GPG 등을 통해 서명(signing)하는 방식을 사용한다. 이를통해 Git v1.8.3 이후 버전부터는 서명하지 않았거나 신뢰할 수 없는 사람이 서명한 commit이 있다면 `git merge`와 `git pull`을 통한 Merge를 허용하지 않을 수 있다. 또한 GitHub에서는 "Branch protection rules"의 "Require signed commits" 옵션을 통해 특정 브랜치에 signing commit만 허용하도록 제한할 수 있다. GitHub에서 singing된 commit은 아래와 같은 아이콘이 붙게된다.
기본적으로 Git이 사용하는 SHA-1 hashing을 통해 1차적으로 작업 데이터 무결성(Integrity)이 검증되고, GPG를 이용한 commit signing(서명)을 통해 2차적으로 commit 데이터 무결성이 검증된다고 볼 수 있다.
이 포스트에서는 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` 등으로 시각적으로 표시해주기 때문에 보안에 더욱 도움이 된다.
추가 : GPG key 내보내기 및 가져오기
포맷, 기기변경 등으로 인해 GPG Key를 백업 및 복구해야 하는 상황에서는 아래와 같이 export/import가 가능하다
키 ID 확인
gpg --list-keys
gpg --list-secret-keys
각각 "uid [상태] {키 ID} <이메일>" 형식으로 출력된다
내보내기
gpg --export {키 ID} > public.key
gpg --export-secret-key {키 ID} > private.key
가져오기
gpg --import public.key
gpg --import private.key
References
'Programming > IDE, Tools, etc.' 카테고리의 다른 글
[GitHub] Repository의 License 등록 (0) | 2022.07.27 |
---|---|
개인저장용 개발환경 스타일 세팅 (Theme, Font 등 ) (0) | 2022.07.13 |
[GitHub] 무료계정에서 private 저장소 branch protection rules 흉내내기 (with VSCode v1.69.0) (0) | 2022.07.08 |
[GitHub] GitHub CLI를 이용한 Label 설정 복제 (0) | 2022.07.06 |
[Tistory] 기본 스킨 커스터마이징 (0) | 2022.06.22 |
- Total
- Today
- Yesterday
- Debug
- selenium
- Python
- Visual Studio Code
- Custom Package
- 비동기
- coroutine
- 닷넷
- C#
- unity
- 코루틴
- github
- VS2022
- logging
- Addressables
- Scraping
- Singleton
- async
- git
- 싱글톤
- vscode
- firestore
- await
- RuntimeInitializeOnLoadMethod
- framework
- initialize
- 유니티
- .net
- 환경설정
- gcp
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |