같은 해시의 표현과 텍스트의 재인코딩은 다릅니다
SHA-256 결과는 256비트, 즉 32바이트입니다. RFC 4648의 Base16은 바이트 하나를 16진수 두 자리로 표현하므로 64자가 됩니다. 같은 32바이트를 패딩이 있는 표준 Base64로 표현하면 44자입니다. 반면 64자리 16진수 문자열을 UTF-8 텍스트로 인코딩하면 입력은 64바이트이므로 Base64 결과는 88자가 됩니다. 여기서 88자는 원시 해시가 아니라 해시를 표시한 텍스트의 인코딩입니다.
실제 도구에 넣을 때 확인할 입력
abc를 SHA-256으로 계산한 뒤 두 경로를 코드로 재현했습니다. Moyoutil 해시 도구는 16진수 텍스트를 출력합니다. 그 값을 Moyoutil Base64 도구에 붙여 넣으면 이 텍스트의 UTF-8 바이트가 인코딩되어 88자가 나옵니다. 이 Base64 도구는 입력된 HEX를 원시 해시 바이트로 해석하지 않습니다. 아래의 별도 Web Crypto 예제는 원시 바이트와 HEX 텍스트를 구분하며 두 경로의 길이를 출력합니다.
const raw = new Uint8Array(await crypto.subtle.digest(
'SHA-256', new TextEncoder().encode('abc')));
const hex = Array.from(raw,
n => n.toString(16).padStart(2, '0')).join('');
const rawBase64 = btoa(String.fromCharCode(...raw));
const textBase64 = btoa(hex); // ASCII HEX text
console.log(raw.length, hex.length,
rawBase64.length, textBase64.length);
// 32 64 44 88결과를 받는 시스템의 문서에서 요구하는 표현을 확인하세요. Base64와 Base64url, 패딩 유무와 인코딩 대상은 별도 조건입니다. 문자열 길이만 맞는다고 같은 체크섬임을 확인한 것은 아닙니다. 이 글은 형식 변환을 설명하며 서명 검증이나 파일의 안전성 판정을 제공하지 않습니다.
자주 묻는 질문
Base64로 바꾸면 해시를 다시 계산한 것인가요?
아닙니다. 원시 해시 바이트의 인코딩은 표시 방식을 바꿉니다. HEX 텍스트를 인코딩하는 경우에는 인코딩 대상 자체가 다릅니다. 원본 데이터의 SHA-256을 다시 계산하는 작업과 구분하세요.