개발자 도구 · SHA 해시 계산기
Hex, Base64 및 Raw Bytes: 동일한 SHA 다이제스트를 작성하는 세 가지 방법
· 작동 방식
샤-256 베이스64 인코딩 파일 형식
sha256sum은 16진수를 인쇄하고 package-lock.json은 base64를 저장하며 Docker는 sha256: 접두사를 사용합니다. 모두 동일한 32바이트일 수 있습니다. 이 게시물에서는 각 표현과 표현 간 변환 방법을 설명합니다.
다르게 보이지만 일치하는 해시 — 동일한 파일에 대한 잠금 파일 문자열 및 터미널 체크섬
SHA-256 다이제스트는 기본적으로 32바이트입니다. 해당 바이트를 쓰는 방법에 따라 다이제스트의 모양이 결정됩니다. 하나의 다이제스트인 32 동일한 바이트는 64 16진수 문자(바이트당 2개) 또는 44 base64 문자(3바이트당 약 4개)로 표시되거나 인코딩에 따라 길이와 형식이 달라집니다. 동일한 기본 32 바이트에 대해 잠금 파일이 하나의 표현을 표시하고 터미널이 다른 표현을 표시할 수 있기 때문에 혼란이 발생합니다.
인코딩을 이해하는 것은 "왜 다르게 보이는가?"로 돌아가는 단계입니다. "동일하다는 것을 확인할 수 있습니다." 세 가지 표현 모두 바이트로 다시 디코딩하면 동일합니다.
다이제스트는 바이트입니다. 텍스트 인코딩 이전에 알고리즘에 따라 20, 32, 48 또는 64입니다.
텍스트 표현이 존재하기 전에 결과는 다이제스트 바이트의 ArrayBuffer입니다. ToolAcre는 해당 버퍼를 Uint8Array로 래핑한 다음 btoa를 호출하기 전에 각 바이트를 두 개의 16진수 숫자로 쓰거나 각 바이트를 이진 문자로 변환합니다. 포맷터는 해시를 다시 실행하지 않으며 단일 다이제스트 비트도 변경하지 않습니다.
바이트 너비는 이 도구에서 선택한 알고리즘을 따릅니다. SHA-1은 20바이트, SHA-256 32바이트, SHA-384 48바이트 및 SHA-512 64바이트를 반환합니다. 이는 알고리즘 메타데이터 및 테스트를 통해 검증된 지원 출력입니다. 원시 바이트는 프로그래밍 방식 비교에 적합합니다. hex 및 base64는 텍스트가 필요한 채널에 대한 전송 표기법입니다.
Hex — 바이트당 두 문자, 이것이 명령줄 도구를 지배하는 이유 및 사례 질문
16진수 표현은 숫자 0-9과 문자 A-F(또는 a-f)를 사용하여 4비트 니블의 16 가능한 값을 나타냅니다. 두 개의 16진수는 1바이트를 나타냅니다. 입력 abc의 SHA-256 다이제스트는 32바이트이므로 64 16진수 문자(ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad)로 표시됩니다. 이는 대부분의 명령줄 도구가 인쇄하는 형식입니다. 16진수는 사람이 읽을 수 있고 모호하지 않습니다. 모든 바이트는 매번 정확히 동일한 두 문자로 표시됩니다.
16진수는 문서와 명령줄에서 체크섬과 해시의 기본 형식입니다. 읽고 복사하기 쉽고 패딩이 없고 해석 시 대소문자 구분이 없으며(관례에 따라 소문자 또는 대문자가 일관되게 지정됨) URL 또는 JSON에서 이스케이프해야 하는 특수 문자가 없습니다. 단점은 원시 바이트보다 두 배 더 많은 문자를 사용한다는 것입니다. 이것이 바로 다른 형식이 존재하는 이유입니다.
Base64 및 base64url — 3바이트당 약 4자, 패딩 및 각각이 나타나는 위치(SRI, npm, SSH 지문)
Base64는 64 문자 알파벳에서 가져온 4개의 문자로 3바이트를 인코딩합니다: A-Z, a-z, 0-9, +, /. 3바이트 61 62 63(ASCII 코드 abc) base64에서 YWJj로 인코딩합니다. 전체 32바이트 SHA-256 다이제스트는 약 44 base64 문자로 인코딩됩니다. = 문자로 패딩하면 출력 길이가 4의 배수가 되므로 44 문자에 0 패딩을 추가합니다(32은 3의 배수이기 때문에 패딩이 필요하지 않습니다). 디코딩은 프로세스를 반대로 수행합니다. 즉, 4개의 base64 문자가 3바이트로 디코딩됩니다.
Base64는 package-lock.json 파일, npmshrinkwrap, HTML의 SRI(하위 리소스 무결성) 속성 및 SSH 키 지문에 나타납니다. 16진수 바이트의 100% 긴 것에 비해 원시 바이트보다 대략 33% 더 깁니다. 단점은 모든 텍스트 표현이 똑같이 읽기 쉬운 것은 아니라는 것입니다. 사람의 눈에는 base64가 16진수보다 더 뒤죽박죽된 것처럼 보입니다.
접두사 형식 — sha256: 컨테이너 다이제스트, sha384- 무결성 속성, SHA256: SSH
Base64url은 + 및 /.을 - 및 _로 대체하는 RFC 4648에 정의된 변형입니다. 알파벳은 A-Z, a-z, 0-9, -, _가 됩니다. JWT는 + 및 /가 URL에서 특별한 의미를 갖기 때문에 base64url을 사용합니다(+는 쿼리 문자열에서 공백으로 읽을 수 있고 /는 경로 구분 기호임). JWT 세그먼트는 항상 base64url로 인코딩되며 표준 base64를 요구하는 디코더는 이를 거부합니다. 반대로 표준 알파벳을 허용하지 않는 base64url 디코더는 표준 base64에서 실패합니다.
패딩은 base64url에서 선택사항입니다. 출력 길이가 4의 배수인지 확인하기 위한 =가 포함된 표준 base64 패드입니다. Base64url은 = 자체가 URL이 어색하기 때문에 일반적으로 패딩을 생략합니다. 디코더는 패딩 유무에 관계없이 base64url을 허용해야 하며 인코더는 패딩을 생성하는 내용을 명시적으로 명시해야 합니다. ToolAcre base64 도구는 알파벳을 모두 허용하고 입력 시 누락된 패딩을 허용하며 출력 시 형식을 선택할 수 있습니다.
작업된 예 — 16진수에서 base64로 그리고 그 반대로 변환된 하나의 다이제스트(바이트 경계가 표시됨)
접두사 형식은 다이제스트에 체계 식별자를 추가합니다. Docker 이미지 다이제스트는 sha256:ba7816bf...를 사용합니다. 여기서 sha256:은 접두사입니다. SSH 지문은 콜론과 함께 SHA256:을 사용합니다. 일부 도구는 sha256= 또는 SHA256=(등호 포함)를 사용합니다. 접두사는 순전히 정보 제공용입니다. 어떤 알고리즘이 다이제스트를 생성했는지 알려줍니다. 접두사를 제거하면 동일한 인코딩에 동일한 바이트가 남습니다.
다이제스트를 비교할 때 접두사는 노이즈입니다. 한 도구가 SHA256:ba78...을 인쇄하고 다른 도구가 ba78...을 인쇄하면 동일한 다이제스트입니다. 접두사는 형식에 대한 메타데이터일 뿐입니다. 마찬가지로 sha256:-(일부 컨테이너 컨텍스트에서 사용됨) 또는 sha384-(무결성 속성에서 사용됨)와 같은 접두사는 바이트를 변경하지 않는 형식 지정 규칙입니다. 비교를 위해 제거하십시오.
여기서 다루지 않는 것 — 주어진 도구가 내보내는 인코딩; 비교하기 전에 출력 형식을 확인하십시오.
하나의 다이제스트인 입력 abc의 SHA-256는 16진수(64 문자), 패딩이 있는 base64(44 문자), 패딩이 있는 base64url(44 문자, + 및 /), 대신 - 및 _ 또는 다양한 접두사 포함)과 같은 다양한 형식으로 나타납니다. 동일하게, 각각을 다시 바이트로 디코딩하고 바이트를 비교합니다. 16진수 표현 ba7816bf...는 바이트 0xba 0x78 0x16 0xbf 0x8f 0x01 0xcf 0xea ...로 디코딩됩니다. base64 표현은 디코딩될 때 동일한 바이트 시퀀스로 변환됩니다.
ToolAcre SHA 해시 계산기는 기본적으로 16진수로 출력됩니다. base64가 필요한 경우 별도의 도구를 사용하여 16진수를 base64로 변환하거나 동일한 사이트에서 base64 유틸리티를 사용하여 텍스트를 직접 인코딩할 수 있습니다. 특정 컨텍스트용으로 설계된 도구(package-lock.json의 경우 npm, 이미지 다이제스트의 경우 Docker)는 해당 컨텍스트에서 예상하는 형식으로 출력합니다. 이것들이 서로 다른 옷에 있는 모두 동일한 32 바이트라는 것을 이해하면 도구가 형식에 동의하지 않을 때 혼란이 사라집니다.
요점: 문자열이 아닌 바이트를 비교합니다. ToolAcre SHA 해시 계산기로 다이제스트를 계산한 다음 확인 중인 표현으로 변환합니다.
16진수 다이제스트를 base64로 수동으로 변환하려면 16진수를 바이트로 그룹화하고 각 바이트를 10진수로 변환한 다음 base64 알파벳을 사용하여 인코딩합니다. 바이트 0xba(16진수 ba)는 10진수 186입니다. 0x78은 120입니다. 0x16은 22입니다. 0xbf는 191입니다. 이 4바이트를 그룹화하고 base64로 인코딩하면 w(알파벳의 0 + 22) 문자가 (186 인코딩), AA(120 인코딩), vw(191 인코딩)로 제공됩니다. 전체 다이제스트에는 이 작업을 10번 수행하고 필요한 경우 패딩이 필요합니다. 이 수동 프로세스는 유익하지만 지루합니다. base64 변환기 도구를 사용하면 즉시 변환할 수 있습니다.
핵심 통찰력은 다이제스트가 바이트 우선이고 텍스트 표현이 보조라는 것입니다. 동일한 바이트의 모든 인코딩은 동일한 바이트로 다시 디코딩되므로 무결성 확인을 위해 상호 교환이 가능합니다. 16진수의 대소문자 차이, base64의 패딩 차이, 접두사 및 간격은 모두 실제 값에 영향을 주지 않는 형식 선택입니다. 표현 간 변환 기능을 익히면 다이제스트 형식 불일치가 미스터리 대신 해결할 수 있는 디버깅 문제가 됩니다.