한국어

개발자 도구 · SHA 해시 계산기

콘텐츠 주소 지정: Git, Docker 및 npm이 SHA 다이제스트를 이름으로 사용하는 방법

· 배경

샤-256 도커 암호화 개발자 워크플로

SHA-256 다이제스트로 처리되는 Git 커밋, Docker 레이어 및 패키지 해시
원본 ToolAcre 벡터 일러스트레이션

Git 커밋, 컨테이너 이미지 다이제스트 및 잠금 파일 무결성 문자열은 모두 해시로 데이터 이름을 지정하는 동일한 아이디어입니다. 이 게시물에서는 콘텐츠 주소 지정과 이를 통해 각 생태계가 얻는 이점에 대해 설명합니다.

sha256: docker pull — 해당 문자열이 무엇이며 왜 동일한 이미지에 대해 변경되지 않는지

버전 제어 시스템, 컨테이너 런타임 및 패키지 관리자는 모두 동일한 명명 아이디어를 사용합니다. 즉, 파일 또는 바이트 모음의 이름은 SHA 다이제스트에 의해 지정됩니다. Git에서 커밋의 40 문자 SHA-1 식별자(또는 최신 리포지토리의 64 문자 SHA-256)는 커밋의 콘텐츠(트리, 작성자, 타임스탬프 및 메시지)에서 계산됩니다. 단일 바이트를 변경하면 SHA가 변경됩니다. Docker에서 각 레이어 다이제스트는 레이어 콘텐츠의 SHA-256 해시이며 이미지 다이제스트는 매니페스트에서 계산됩니다. npm 및 기타 패키지 관리자에서 무결성 필드는 다운로드를 확인하기 위해 tarball의 SHA-512 다이제스트를 저장합니다. 콘텐츠 주소 지정은 이름이 중앙 데이터베이스나 타임스탬프가 아닌 바이트에만 의존한다는 것을 의미합니다.

이점은 각 시스템 내에서 불변성입니다. git commit SHA-256:abc...는 해시가 ID를 결정하므로 항상 동일한 트리와 메시지를 참조합니다. 누군가가 동일한 SHA로 다른 커밋을 가지고 있다고 주장하는 경우 동일한 바이트가 두 개의 다른 해시를 생성하여 암호화를 깨뜨린다고 주장하는 것입니다. 중복 제거는 자동으로 수행됩니다. 동일한 바이트를 가진 두 파일이 동일한 다이제스트를 생성하므로 스토리지 시스템은 바이트를 한 번 저장하고 두 번 참조할 수 있습니다. 무결성 검사는 다이제스트를 다시 계산하고 비교하는 것만큼 간단해집니다. 바이트가 전송 중이거나 정지 중에 수정된 경우 다이제스트는 더 이상 일치하지 않습니다.

해시를 기준으로 데이터 이름 지정 — 콘텐츠 주소 지정 아이디어 및 중복 제거와 무결성이 자유로운 이유

Git은 SHA 다이제스트로 입력된 커밋, 트리, blob 및 태그 등의 개체를 저장합니다. `git cat-file` 명령은 개체 ID를 가져와 바이트를 검색합니다. 객체 저장소는 콘텐츠 주소가 지정됩니다. 위치나 이름이 아닌 다이제스트로 요청합니다. 리포지토리를 복제하면 git은 다이제스트를 다시 계산하고 전송에 포함된 다이제스트를 확인하여 각 객체를 확인합니다. SHA-1에서 SHA-256로의 전환은 점진적입니다. 저장소는 호환성을 위해 두 가지를 모두 지원할 수 있습니다. 온디스크 형식은 객체 유형, 크기 및 압축된 바이트를 저장합니다. 다이제스트는 압축되지 않은 표준 형식을 통해 계산됩니다.

최신 Git 리포지토리는 SHA-256을 사용할 수 있으며 SHA-1 충돌이 이제 실용적이기 때문에 전환이 진행 중입니다(2017에서 설명되고 2020에서 개선됨). SHA-256를 사용하는 저장소의 커밋에는 40 대신 64 문자 16진수 식별자가 있습니다. `git hash-object` 명령은 blob(파일 내용)을 저장하지 않고 SHA를 계산합니다. `git commit-tree`는 트리 구조와 메시지의 SHA를 계산합니다. 두 작업 모두 결정적입니다. 동일한 바이트는 항상 동일한 다이제스트를 생성합니다. 이것이 GitHub 및 기타 위조 프로그램이 커밋 SHA를 일관되게 표시할 수 있는 방법입니다. 작성자의 복제본이 계산한 것과 동일한 다이제스트를 계산합니다.

Git은 콘텐츠 주소가 지정된 개체를 사용하며 이 도구는 텍스트 다이제스트를 재현할 수 있습니다. 마이그레이션 세부정보에는 Git 관련 소스가 필요합니다.

Docker 이미지는 레이어로 구축되며, 각 레이어는 파일 시스템 델타입니다(이전 레이어의 변경 사항). OCI 이미지 사양은 레이어의 다이제스트와 이미지 매니페스트의 다이제스트를 계산하는 방법을 정의합니다. 레이어 다이제스트는 레이어 파일이 포함된 압축 tar 파일의 SHA-256입니다. 매니페스트는 레이어, 해당 다이제스트 및 메타데이터를 나열하는 JSON 문서입니다. 이미지 다이제스트는 매니페스트 JSON 자체의 SHA-256입니다. `latest`와 같은 태그를 사용하여 이미지를 가져오면 레지스트리는 태그를 조회하고 매니페스트 다이제스트를 반환합니다. 그런 다음 다이제스트를 통해 직접 가져올 수 있으므로 매번 정확히 동일한 바이트(모든 레이어 및 메타데이터)를 얻을 수 있습니다.

로컬 이미지의 `docker inspect` 명령은 해당 다이제스트를 표시합니다. 두 시스템의 동일한 태그에서 동일한 이미지를 실행하면 레지스트리가 동일한 매니페스트를 가리키는 해당 태그를 계속 보유하고 있는 경우 동일한 다이제스트가 생성됩니다. 콘텐츠 주소 지정을 통해 이미지 공급망을 감사할 수 있습니다. CI/CD 파이프라인은 배포된 이미지가 빌드 로그의 다이제스트와 일치하는지 확인할 수 있으며, 보안 스캐너는 이동할 수 있는 태그가 아닌 다이제스트를 통해 특정 취약점이 있는 것으로 알려진 모든 이미지에 대해 보고할 수 있습니다.

컨테이너 — OCI 매니페스트 및 레이어 다이제스트, 태그는 이동할 수 있지만 다이제스트는 이동할 수 없는 이유

패키지 관리자는 다이제스트를 사용하여 다운로드가 변조되거나 손상되지 않았는지 확인합니다. npm에서 `package-lock.json` 파일에는 해시(일반적으로 SHA-512) 및 인코딩(일반적으로 base64)을 포함하는 각 종속성에 대한 `integrity` 필드가 포함되어 있습니다. npm은 tarball을 다운로드할 때 해시를 다시 계산하고 비교합니다. 해시가 일치하지 않으면 설치가 실패합니다. Go는 모듈 경로, 버전 및 모듈 소스의 SHA-256와 유사한 구조를 가진 `go.sum` 파일을 사용합니다. Cargo는 `Cargo.lock`의 체크섬을 사용합니다. 원칙은 동일합니다. 종속성이 처음 해결될 때 다이제스트가 한 번 계산되고 모든 후속 설치에서 확인됩니다.

무결성 검사에서는 패키지를 서명 기관에 업로드하거나 서명을 별도로 저장할 필요가 없습니다. 다이제스트는 무결성 검사입니다. 최대한의 보증을 위해 프로젝트는 Go 프로젝트의 투명성 시스템으로 서명된 `go.sum` 또는 다른 검증과 결합된 npm 무결성을 사용하지만 기본 사례는 간단합니다. 게시자는 다이제스트를 한 번 계산하고 이를 잠금 파일에 기록하며 소비자 측 도구는 다운로드한 바이트가 일치하는지 확인합니다.

패키지 무결성 인코딩은 다양합니다. 이 계산기에서 지원되는 SHA 출력만 여기에 표시됩니다.

동일한 알고리즘을 통해 동일한 바이트는 바이트의 출처에 관계없이 항상 동일한 다이제스트를 생성합니다. 개발자의 커밋 로컬 빌드는 동일한 저장소에서 동일한 개정을 체크아웃하는 CI/CD 시스템과 동일한 SHA-256을 생성합니다. 이러한 재현성은 콘텐츠 주소 지정이 작동하는 이유입니다. 전달 메커니즘을 신뢰하지 않고도 아티팩트를 확인할 수 있습니다. 다이제스트는 암호화 약속이 됩니다. 단 1바이트라도 변경하면 무효화됩니다.

다이제스트를 별도로 배포하면(아티팩트를 배포하기 전) 진행 중인 수정을 방지할 수 있습니다. 릴리스 전에 게시된 웹 페이지에는 "expect SHA-256:abc..."가 표시될 수 있으며 사용자는 이에 대해 다운로드를 확인할 수 있습니다. 공개 저장소에 게시된 git 커밋은 바이트에 대한 약속입니다. 다이제스트가 그것을 증명합니다.

작업된 예 — 도구에서 사용하는 이름을 요약하기 위해 바이트에서 하나의 blob을 따릅니다.

시스템마다 다이제스트를 다르게 인코딩합니다. Git은 기본적으로 소문자 16진수(40 또는 64 16진수 문자)를 사용합니다. Docker는 `sha256:` 뒤에 16진수 형식을 사용합니다. npm과 Go는 무결성 필드에 base64를 사용합니다. 바이트는 동일합니다. 단지 표현이 다를 뿐이죠. "abc"에 대한 SHA-256 다이제스트는 항상 동일한 256 비트이지만 64 문자 16진수 문자열, 44 문자 base64 문자열 또는 `sha256:`과 같은 레이블로 표시될 수 있습니다. 인코딩 간 변환은 무손실입니다. 다이제스트는 모든 표현에서 동일한 값입니다.

여러 도구에서 다이제스트를 비교할 때 인코딩을 이해하는 것이 중요합니다. Git이 16진수 다이제스트를 인쇄하고 도구에 base64가 표시되면 한 표현을 다른 표현으로 변환하여 일치하는지 확인해야 합니다. ToolAcre의 SHA 해시 계산기는 모든 다이제스트에 대해 16진수와 base64를 모두 표시하므로 쉽게 변환하거나 다른 시스템과 상호 참조할 수 있습니다.

여기서 다루지 않는 내용 — 각 도구가 사용하는 특정 인코딩(16진수 대 base64)은 별도의 게시물에서 다룹니다.

콘텐츠 주소 지정은 암호화에만 국한되지 않지만 암호화 해시를 사용하면 보안이 강화됩니다. CRC32 체크섬은 콘텐츠 주소 데이터도 지정하지만 CRC32 충돌은 일반적이며 충돌이 만들어질 수 있습니다. 이 저장소는 SHA-256을 손상된 것으로 표시하지 않는 반면 CRC32는 적대적 무결성 기본 요소로 제공되지 않습니다. 해시 알고리즘의 선택은 보안에 중요합니다. SHA-256은 적에 대한 무결성 보호가 필요한 시스템의 최신 표준입니다. SHA-1는 레거시 전용입니다(Git 및 기타 프로그램은 마이그레이션 중입니다). 올바른 알고리즘을 선택하는 것은 콘텐츠 주소 지정을 이름 지정 체계로 선택하는 것과는 별개의 결정입니다.

암호화 해시와 결합된 콘텐츠 주소 지정은 최신 소프트웨어의 공급망 무결성의 기초입니다. 설치하는 모든 패키지, 실행하는 모든 컨테이너 및 체크아웃하는 모든 커밋은 보안 전송에 의존하지 않고도 원래 게시자가 의도한 바이트인지 확인할 수 있습니다(보안 전송은 여전히 ​​좋은 관행임).

요약: 해시는 ID입니다. ToolAcre SHA 해시 계산기를 사용하면 이러한 시스템이 의존하는 것과 동일한 다이제스트를 계산할 수 있습니다.

콘텐츠 주소 지정은 인코딩, 저장 위치 또는 전송 메커니즘과 무관합니다. 동일한 바이트는 로컬, CDN, 레지스트리에 저장되거나 HTTP 또는 보안 HTTPS를 통해 전송되는지에 관계없이 동일한 다이제스트를 생성합니다. 다이제스트는 바이트에 대한 암호화 약속이며 이를 확인하려면 외부 서비스가 아닌 바이트와 알고리즘만 필요합니다. 이것이 콘텐츠 주소 지정이 오프라인 확인을 가능하게 하는 이유입니다. 신뢰할 수 없는 채널을 통해 파일을 다운로드하고 다이제스트를 확인하고 바이트가 진짜인지 확인할 수 있습니다.

ToolAcre SHA 해시 계산기를 사용하면 이러한 시스템이 의존하는 것과 동일한 다이제스트를 계산할 수 있습니다. 문자열을 붙여넣거나 파일을 관찰하고, 계산기를 실행하고 Docker, Git, npm 및 기타 도구가 내부적으로 사용하는 SHA-256, SHA-384 및 SHA-512 다이제스트를 확인하세요. 계산된 다이제스트를 원본 소스의 다이제스트와 비교하여 바이트가 수정되지 않았는지 확인하세요. 계산기는 붙여넣은 UTF-8 텍스트를 해시합니다. 파일이나 키 자료를 해시하지 않으므로 해시할 수 있는 것(텍스트 입력)과 할 수 없는 것(바이너리 파일, 인코딩된 형식의 암호화 키) 사이의 경계가 명확하고 문서화되어 있습니다.