서명 된 git 커밋 확인 중?


96

최신 버전 git에서는 PGP 키로 개별 커밋 (태그 외에도)에 서명 할 수 있습니다.

git commit -m "some message" -S

다음 옵션 을 git log사용하여 의 출력에 이러한 서명을 표시 할 수 있습니다 --show-signature.

$ git log --show-signature
commit 93bd0a7529ef347f8dbca7efde43f7e99ab89515
gpg: Signature made Fri 28 Jun 2013 02:28:41 PM EDT using RSA key ID AC1964A8
gpg: Good signature from "Lars Kellogg-Stedman <lars@seas.harvard.edu>"
Author: Lars Kellogg-Stedman <lars@seas.harvard.edu>
Date:   Fri Jun 28 14:28:41 2013 -0400

    this is a test

그러나 주어진 커밋에서 서명을 프로그래밍 방식으로 확인하는 방법이 git log있습니까? git tag -v주어진 커밋에 유효한 서명이 있는지 여부를 나타내는 종료 코드를 제공하는 커밋과 동등한 것을 찾고 있습니다.


1
나는 그것이해야한다고 생각 git commit ...하고 git log .... 내가 아는 한, 투명하게 gpg전달되는 하위 명령을 추가 git하지 않았습니다. 테스트 할 저장소가 없지만 git show --show-signature <commitish>작동합니까?
twalberg

show_signature출력에만 항목을 추가합니다 ( github.com/git/git/blob/master/log-tree.c#L370 참조 ).
Emil Sit

참고 : 곧해야합니다 --raw위해 git verify-tag/ git verify-commit. 보기 내 대답은 아래
VonC

1
참고 :와 자식 2.11 (Q4 2016), git log소개합니다 추가 상태 코드는 E, X, Y, R대한 ERRSIG, EXPSIG, EXPKEYSIG,와 REVKEYSIG, 정도의 사용자는 %G?더 많은 정보를 가져옵니다. 참조 아래에있는 내 편집 대답
VonC

1
Git 2.26 (2020 년 1 분기)에서는 /를 gpg.minTrustLevel사용할 때 새로운 구성 이 도움이 될 수 있습니다 . 아래에서 수정 된 답변을 참조하십시오 . git verify-tagverify -commit
VonC

답변:


115

내가했던 것처럼 이런 경우에 누군가가 검색 엔진을 통해 해당 페이지로 온다 : 질문이 게시 된 이후 새로운 도구가 2 년 만에 가능하게되었습니다이이 작업에 대한 자식 명령은 지금 : git verify-commitgit verify-tag커밋을 확인하는 데 사용할 수 있으며, 태그.


34

참고 : 최대 2.5 이눔 아,하기 git verify-commitgit verify-tag만 사람이 읽을 수있는 메시지가 표시됩니다.
검사를 자동화하려면 git 2.6+ (2015 년 3 분기)가 다른 출력을 추가합니다.

참조 e18443e 커밋 , aeff29d 커밋 , ca194d5 커밋 , 434060e을 커밋 , 8e98e5f 커밋 , a4cc18f 커밋 , d66aeff 커밋 에 의해 (2015년 6월 21일를) 브라이언 m. 칼슨 ( bk2204) .
(Merged by Junio ​​C gitsterHamano -- in commit ba12cb2 , 03 Aug 2015)

verify-tag/ verify-commit: 원시 gpg 상태 정보를 인쇄하는 옵션 추가

verify-tag/ verify-commit는 기본적으로 표준 오류에 대해 사람이 읽을 수있는 출력을 표시합니다.
그러나 컴퓨터에서 읽을 수있는 원시 gpg 상태 정보에 액세스하여 서명 정책의 자동화 된 구현을 허용하는 것도 유용 할 수 있습니다 .

사람이 읽을 수있는 형식 대신 표준 오류에 대한 gpg 상태 정보를 생성 하는 --raw옵션 을 추가 verify-tag합니다.

을 더한:

verify-tag서명은 양호하지만 키를 신뢰할 수없는 경우 성공적으로 종료됩니다. verify-commit성공적으로 종료됩니다.
이러한 행동의 차이는 예상치 못한 원치 않는 것입니다. 이전에 존재
했기 때문에 share 의 동작 verify-tag을 갖도록 실패한 테스트를 추가하십시오 .verify-commitverify-tag


git 2.9 (2016 년 6 월) git merge doc 업데이트 :

Keller Fuchs (``)의 커밋 05a5869 (2016 년 5 월 13 일)를 참조하십시오 . 도움 : Junio ​​C Hamano ( ) . (Merged by Junio ​​C Hamano -- in commit be6ec17 , 17 May 2016)
gitster
gitster

--verify-signatures:
--no-verify-signatures:

병합되는 사이드 브랜치의 팁 커밋이 유효한 키, 즉 유효한 uid가있는
키로 서명되었는지 확인합니다. 기본 신뢰 모델에서 이는 서명 키가 신뢰할 수있는 키에 의해 서명되었음을 의미합니다. 사이드 브랜치의 팁 커밋이 유효한 키로 서명되지 않은 경우 병합이 중단 됩니다.


Git 2.10 업데이트 (2016 년 3 분기)

Linus Torvalds ( )의 commit b624a3e (2016 년 8 월 16 일)를 참조하십시오 . (합병 : Junio ​​C Hamano -- in commit 83d9eb0 , 19 Aug 2016)torvalds
gitster

gpg-interface: pgp 서명을 확인할 때 "긴"키 형식 출력 선호

" git log --show-signature"및 PGP 서명의 확인 상태를 표시하는 기타 명령은 이제 32 비트 키 ID가 지난 세기이므로 더 긴 키 ID를 표시합니다.

Linus의 원본은 과거에 갇혀 있던 바이너리 배포자가 이전 코드베이스로 가져 가고자하는 경우에 대비하여 유지 관리 트랙에 적용되도록 리베이스되었습니다.


Git 2.11+ (2016 년 4 분기)는 훨씬 더 정확할 것입니다.

Michael J Gruber ( )의 commit 661a180 (2016 년 10 월 12 일)을 참조하십시오 . (의해 병합 - Junio C 하마노 -56d268b 커밋 2,016 26 10 월)mjg
gitster

" %G?"프리티 형식 지정자에 표시된 GPG 확인 상태 는 만료 된 키로 만든 서명, 해지 된 키로 만든 서명 등을 구별 할만큼 풍부하지
않았습니다 . 이를 표현하기 위해 새 출력 문자가 할당되었습니다 .

gpg2doc/DETAILS 에 따르면 :

각 서명 코드의 하나를 들어 GOODSIG, BADSIG, EXPSIG, EXPKEYSIG, REVKEYSIG또는 ERRSIG배출된다.

이제 git pretty-format문서 에는 다음이 포함됩니다.

  • ' %G?': 표시
    • " G"(유효한) 서명의 경우
    • " B"잘못된 서명
    • " U"의 유효성을 알 수없는 양호한 서명의 경우
    • X만료 된 양호한 서명의 경우 " "
    • Y만료 된 키로 만든 좋은 서명의 경우 " "
    • R취소 된 키로 만든 좋은 서명의 경우 " "
    • E서명을 확인할 수없는 경우 (예 : 키 누락) " ", 서명이없는 경우 "N"

Git 2.12 (Q1 2017) " git tag"및 " git verify-tag" 는 GPG 검증 상태를 " --format=<placeholders>"출력 형식 에 넣는 방법을 배웠습니다 .

참조 4fea72f 커밋 , 02c5433 커밋 , 커밋 ff3c8c8 에 의해 (2017 1월 17일) 산티아고 토레스 ( SantiagoTorres) .
참조 07d347c 커밋 , 2111aa7 커밋 , 94240b9 커밋 에 의해 (2017년 1월 17일를) 루카스 Puehringer (``) .
(Merged by Junio ​​C gitsterHamano -- in commit 237bdd9 , 31 Jan 2017)

추가 --formatgit tag -v대신 음소거 GPG 검증의 기본 출력을하고하면 포맷 태그 객체를 인쇄합니다.
이를 통해 호출자는 GPG 확인시 참조 / 태그의 태그 이름을 태그 개체 헤더의 태그 이름과 교차 확인할 수 있습니다.


Git 2.16 (2018 년 1 분기)을 통해 커밋 서명 확인을 더욱 자동화 할 수 있습니다. merge.verifySignatures 구성 변수를 .

Hans Jerry Illikainen (``)의 commit 7f8ca20 , commit ca779e8 (2017 년 12 월 10 일)을 참조하십시오 . (Merged by Junio ​​C Hamano -- in commit 0433d53 , 28 Dec 2017)
gitster

merge: 구성 옵션 추가 verifySignatures

git merge --verify-signatures 병합되는 브랜치의 팁 커밋이 올바르게 서명되었는지 확인하는 데 사용할 수 있지만 매번이를 지정해야하는 것은 번거 롭습니다.

기본적으로이 동작을 활성화하는 구성 옵션을 추가합니다.이 옵션은 --no-verify-signatures.

git merge구성 man 페이지는 현재 읽

merge.verifySignatures:

true이면 --verify-signatures명령 줄 옵션 과 동일합니다 .


Git 2.19 (2018 년 3 분기)는 " git verify-tag"및 " git verify-commit"가 기본 "의 종료 상태를 사용하도록 학습되었으므로 훨씬 더 유용합니다.gpg --verify 에서 발견 된 불량 또는 신뢰할 수없는 서명을 알리기 위해 " 합니다.

참고 : 힘내 2.19로 gpg.format"로 설정 될 수있다 openpgp"또는 " x509"및 gpg.<format>.program그 "를 통해 CMS와 X.509 인증서 표시를 할 수 있도록) 형식을 처리하는 데 사용하는 어떤 프로그램을 지정하는 데 사용됩니다 gpgsm"대신 사용되는 openpgp경유 "gnupg ".

참조 4e5dc9c 커밋 에 의해 (2018년 8월 9일)를 Junio C 하마노 ( gitster) .
도움을받은 사람 : Vojtech Myslivec ( VojtechMyslivec) , brian m. carlson ( bk2204)Jeff King ( peff) .
(Merged by Junio ​​C gitsterHamano -- in commit 4d34122 , 20 Aug 2018)

gpg-interface: 종료 상태를 gpg다시 호출자에게 전파

gpg-interface API가 2015 년 중반 v2.6.0-rc0 ~ 114에서 서명 된 태그 및 서명 된 커밋에 대한 서명 확인 코드 경로 지원을 통합했을 때 실수로 GPG 서명 확인을 느슨하게했습니다.

변경하기 전에 서명 된 커밋은 GGPG에서 " "ood 서명을 찾고 " gpg --verify"프로세스 의 종료 상태를 무시하고 " "프로세스의 종료 상태를 전달하여 확인했습니다."gpg --verify " .

우리가 현재 가지고있는 통합 코드는 " gpg --verify" 의 종료 상태를 무시하고 키에 대한 신뢰에 관계없이 서명이 만료되지 않은 키와 일치 할 때 성공적인 확인을 반환합니다 (예 : " G"오드 하나 에 추가하여 허용 "U "신뢰할 수없는 것 외에도 "을 허용합니다).

기본 " gpg --verify"(또는 " gpg.program"구성 변수로 지정된 사용자 정의 명령 )이 그렇게 할 때 이러한 명령이 종료 상태로 실패를 알리 도록합니다.
이것은 본질적으로 역 호환되지 않는 방식으로 동작을 변경하여 신뢰할 수없는 키로 만든 서명을 올바르게 검증하더라도 " gpg --verify"의 동작 을 거부합니다 .

출력이 서명이 양호하거나 올바르게 계산되지만 신뢰할 수없는 키로 만들어진 경우 " gpg"(또는 gpg.program) 에서 얻은 0 종료 상태를 여전히 무시하여 " " 주위에 잘못 작성된 래퍼를 잡기 gpg위해 사용자가 제공 할 수 있습니다. .

U이 폴백 코드에서 신뢰할 수 없는 지원을 " " 제외 할 수 있지만, 이는 단일 커밋에서 이전 버전과 호환되지 않는 두 가지 변경 사항을 만드는 것이므로 지금은 피합시다.
원하는 경우 후속 변경을 수행 할 수 있습니다.


암호화를 수행하기 전에 키를 신뢰 / 서명해야합니다.

신뢰 측면에서는 진전이 있습니다.
Git 2.26 (2020 년 1 분기)에서는 gpg.minTrustLevel다양한 서명 확인 코드 경로에 필요한 최소 신뢰 수준을 알리는 구성 변수가 도입되었습니다.

Hans Jerry Illikainen ( )의 commit 54887b4 (2019 년 12 월 27 일)를 참조하십시오 . (Merged by Junio ​​C Hamano -- in commit 11ad30b , 30 Jan 2020)illikainen
gitster

gpg-interface: 구성 옵션으로 minTrustLevel 추가

서명자 : Hans Jerry Illikainen

키 중 하나 신뢰 수준이 있다면 이전, 병합 및 풀 작업을위한 서명 확인은 검사 TRUST_NEVER또는 TRUST_UNDEFINED에서를 verify_merge_signature().

그럴 경우 프로세스 die() 'd.

서명 확인을 수행 한 다른 코드 경로는 전적으로 반환 코드에 의존했습니다. check_commit_signature() .

신뢰 수준에 관계없이 좋은 키로 만든 서명은 check_commit_signature() .

이러한 동작의 차이로 인해 사용자는 키링에있는 키의 신뢰 수준이 그렇지 않은 작업 (예 : a 또는 )의 경우에도 항상 Git에서 고려한다고 잘못 가정하게 될 수 있습니다.verify-commitverify-tag .

작동 방식 gpg-interface.c은 키 / 서명 상태의 결과 구조 의 result구성원에있는 가장 낮은 신뢰 수준 2 개 를 저장하는 signature_check것이 었습니다 (만난 상태의 마지막 상태 줄이에 기록됨 result).

이는 GPG의 하위 섹션 General status codesKey related에서 각각 문서화됩니다 .

GPG 문서는 TRUST_ status코드 에 대해 다음과 같이 말합니다 .


다음은 몇 가지 유사한 상태 코드입니다.

- TRUST_UNDEFINED <error_token>
- TRUST_NEVER     <error_token>
- TRUST_MARGINAL  [0  [<validation_model>]]
- TRUST_FULLY     [0  [<validation_model>]]
- TRUST_ULTIMATE  [0  [<validation_model>]]

양호한 서명의 경우 이러한 상태 줄 중 하나가 생성되어 서명을 만드는 데 사용 된 키의 유효성을 나타냅니다.
오류 토큰 값은 현재 gpgsm에서만 내 보냅니다.


내 해석은 신뢰 수준이 키 및 / 또는 서명의 유효성과 개념적으로 다르다는 것입니다.

그것은 또한 check_signature()' G'(에서 GOODSIG와 같이 ) 및 ' U'(에서와 같이 TRUST_NEVER또는 TRUST_UNDEFINED)둘 다 성공으로 간주 된 결과)의 결과 가있는 이전 코드의 가정 인 것으로 보입니다 .

'의 결과는 두 경우 U'특별한 의미를 가지고는 있었다 verify_merge_signature()(여기서이 발생 gitdie())과의 format_commit_one()(가 출력 영향을받는 경우 %G?형식 지정자를).

TRUST_ status사용자가 개별 부분 git(예 : 병합)을 직접 수행하는 것보다 전역 적으로 적용되는 최소 신뢰 수준을 구성 할 수 있도록 행 처리를 리팩토링하는 것이 합리적이라고 생각합니다 (이전 버전과의 호환성이있는 유예 기간 제외).

또한 키 / 서명 상태와 동일한 구조체 멤버에 신뢰 수준을 저장하지 않는 것이 합리적이라고 생각합니다.

TRUST_ status코드 의 존재는 서명이 좋다는 것을 의미하지만 (위에 포함 된 스 니펫의 첫 번째 단락 참조) 내가 알 수있는 한 GPG의 상태 줄 순서는 잘 정의되어 있지 않습니다. 따라서 signature_check구조 의 동일한 구성원에 저장된 경우 신뢰 수준이 키 / 서명 상태로 덮어 쓸 수있는 가능성이 있습니다 .

이 패치는 새로운 구성 옵션을 소개합니다 : gpg.minTrustLevel.

신뢰 수준 확인을 통합 하고 구조에 gpg-interface.ctrust_level구성원을 추가합니다 signature_check.

이전 버전과의 호환성은 verify_merge_signature()사용자가 구성 할 수있는 항목 gpg.minTrustLevel이 설정 되지 않은 경우 이전의 거부 TRUST_UNDEFINED및 거부 동작 과 같은 특수한 경우를 도입하여 유지됩니다.TRUST_NEVER 적용됩니다.

반면에 gpg.minTrustLevel가 설정되면 해당 값이 이전 동작을 재정의합니다.

마찬가지로, %G?서식 지시자가 '쇼를 계속 U'의 신뢰 수준을 가진 키를 사용하여 만든 서명을 TRUST_UNDEFINED하거나 TRUST_NEVER,짝수 불구하고 ' U'문자는 더 이상 존재하지 result의 멤버 signature_check구조.

%GT서명에 대해 가능한 모든 신뢰 수준을 표시하려는 사용자를 위해 새로운 형식 지정자 도 도입되었습니다.

또 다른 접근 방식은 단순히 신뢰 수준 요구 사항을 verify_merge_signature() .

이것은 또한 서명 확인을 수행하는 git의 다른 부분과 동작을 일관되게 만들었습니다.

그러나 키 서명을 위해 최소한의 신뢰 수준을 요구하는 것은 실제 사용 사례 인 것 같습니다.

예를 들어 Qubes OS 프로젝트에서 사용하는 빌드 시스템은 현재 verify-tag의 원시 출력을 파싱하여 git tags 서명에 사용되는 키에 대한 최소 신뢰 수준을 주장 합니다 .

이제 git config gpgman 페이지 에는 다음이 포함됩니다.

gpg.minTrustLevel :

서명 확인을위한 최소 신뢰 수준을 지정합니다.
이 옵션이 설정되지 않은 경우 병합 작업에 대한 서명 확인에는 최소한 marginal신뢰 가있는 키가 필요합니다 .
서명 확인을 수행하는 다른 작업에는 최소한 undefined신뢰 가있는 키가 필요합니다 .
이 옵션을 설정하면 모든 작업에 필요한 신뢰 수준이 무시됩니다. 중요도가 높은 순서로 지원되는 값 :

  • undefined
  • never
  • marginal
  • fully
  • ultimate

함께 힘내 2.26 (Q1 2020) , " git show"등은 헥사을 수득 정정 된 그 오류 출력을 원시 포맷으로 객체 이름을 주었다.

show_one_mergetag : 부모가 아닌 16 진수 형식으로 인쇄합니다.

mergetag가 얕은 복제 후에 발생할 수있는 부모가 아닌 이름을 지정하면 해당 해시는 이전에 원시 데이터로 인쇄되었습니다.
대신 16 진수 형식으로 인쇄하십시오.

git -C shallow log --graph --show-signature -n1 plain-shallow후 테스트git clone --depth 1 --no-local . shallow


Git 2.27 (2020 년 2 분기)에서는 GnuPG와 인터페이스하기위한 코드가 리팩터링되었습니다.

Hans Jerry Illikainen ( )의 commit 6794898 , commit f1e3df3 (2020 년 3 월 4 일)을 참조하십시오 . (Merged by Junio ​​C Hamano -- in commit fa82be9 , 27 Mar 2020)illikainen
gitster

gpg-interface: check_signature()GPG 검증 선호

서명자 : Hans Jerry Illikainen

이 refactors에게의 사용 커밋 verify_signed_buffer()의 외부를 gpg-interface.c사용하는 check_signature()대신.

또한 .NET verify_signed_buffer()에 의해 내부적으로 만 호출되기 때문에 파일 로컬 함수로 바뀝니다 check_signature().

이 GPG 서명 검증을 수행 할 수 망할 놈의 다른 부분에서 사용이 개 전 세계적 범위 기능은 이전과 같다 : verify_signed_buffer()check_signature().

지금 만 check_signature()사용됩니다.

verify_signed_buffer()함수는 Michał Górny에서 설명한대로 중복 서명을 방지하지 않습니다 .

대신 GPG에서 오류가없는 종료 코드와 하나 이상의 GOODSIG상태 필드 가 있는지 만 확인 합니다.

이는 check_signature()둘 이상의 서명이 발견되면 오류를 반환하는 것과 대조됩니다 .

낮은 수준의 확인은 verify_signed_buffer()호출자가 GPG 상태 메시지 자체의 다양한 부분을 구문 분석하고 유효성을 검사하지 않는 경우 문제를 사용 합니다.

그리고 이러한 메시지를 처리 gpg-interface.c하는 것은 함수 로 예약해야하는 작업처럼 보입니다 check_signature().

또한를 사용 verify_signed_buffer()하면 GPG 상태 표시 줄의 내용에 의존하는 새로운 기능을 도입하기가 어렵습니다.

이제 서명 확인을 수행하는 모든 작업은에 대한 단일 진입 점을 공유합니다 gpg-interface.c.

이렇게하면 동일한 수준의 확인을 수행하지 않는 이상한 엣지 케이스없이 GPG 서명 확인의 변경되거나 추가 된 기능을 Git의 모든 부분에 쉽게 전파 할 수 있습니다.


4

코드를 간략하게 살펴보면 그러한 직접적인 방법이 없음을 알 수 있습니다.

git 소스의 모든 테스트 grep는 출력 을 ping하는 데 의존합니다 (테스트는 t / t7510-signed-commit.shgit show 참조 ).

--pretty "%H %G?%"쉽게 구문 분석 할 수 있도록 다음과 같이 출력을 사용자 정의 할 수 있습니다 .

git merge서명 확인을 요청할 수있는 것처럼 보이지만 다시 테스트에 의존합니다 grep( t / t7612-merge-verify-signatures.sh 참조 ). 유효하지 않은 서명으로 인해 잘못된 서명 git merge으로 종료되는 것처럼 보이 므로 어딘가에서 테스트 병합을 수행하고 해당 병합을 버려서 잠재적으로이 문제를 해킹 할 수 있지만 grep을 호출하는 것보다 더 나빠 보입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.