Devin.KR
로그인

리눅스 sha256sum 사용법 - 파일 무결성 검증과 체크섬 목록 관리

개발자 조회 1

이 명령어를 언제 쓰는가

수 GB짜리 설치 이미지를 받았는데 중간에 깨졌는지 알 수 없을 때, 백업 파일을 다른 서버로 옮긴 뒤 원본과 같은지 확인할 때, 배포 산출물이 빌드 서버에서 나온 그 파일이 맞는지 확인할 때 sha256sum을 쓴다.

동작은 간단하다. 파일 내용 전체를 읽어 64자리 16진수 지문을 만든다. 1비트라도 다르면 완전히 다른 값이 나온다. 그래서 두 파일이 같은지를 파일을 나란히 놓지 않고도 판정할 수 있다.

이름이 비슷한 md5sum이 아직 많이 보이지만, 새로 쓰는 코드에는 넣지 않는 것이 맞다. 이유는 아래 함정 절에서 설명한다.

기본 형식

sha256sum [옵션] [파일...]

출력은 체크섬 + 공백 두 칸 + 파일명 한 줄이다.

sha256sum app.tar.gz
28281199c26e30971014914d9c82514c56e682bdc4f7fd2be054be38129ccd7a  app.tar.gz

파일명을 주지 않으면 표준 입력을 읽고 파일명 자리에 -가 찍힌다. 공백이 두 칸이라는 점이 중요하다. 이 형식을 그대로 저장한 파일이 -c 검증의 입력이 된다.

자주 쓰는 옵션

옵션의미예시
-c체크섬 목록 파일을 읽어 검증sha256sum -c SHA256SUMS
--quiet검증 시 OK인 줄은 안 찍고 실패만sha256sum -c --quiet SHA256SUMS
--status아무것도 출력하지 않고 종료 코드로만 판정스크립트에서 if와 조합
--ignore-missing목록에 있지만 없는 파일은 건너뛴다일부 파일만 받았을 때
--strict목록 파일에 형식이 깨진 줄이 있으면 실패자동화에서 권장
--tagBSD 스타일로 출력SHA256 (app.tar.gz) = 2828...
-b바이너리 모드. 파일명 앞에 *리눅스에서는 실질 차이 없음

실전 예제

1) 배포판 이미지를 받고 공식 체크섬과 대조한다. 가장 기본이자 가장 자주 하는 일이다. 눈으로 64자리를 비교하지 말고 기계에 맡긴다.

# 배포처가 공개한 값을 그대로 붙여 넣는다(공백 두 칸 유지)
echo '28281199c26e30971014914d9c82514c56e682bdc4f7fd2be054be38129ccd7a  app.tar.gz' | sha256sum -c -
app.tar.gz: OK

값이 다르면 app.tar.gz: FAILED와 함께 WARNING: 1 computed checksum did NOT match가 나오고 종료 코드가 1이 된다.

2) 배포 산출물 전체의 체크섬 목록을 만들고 검증한다. 릴리스 아티팩트를 배포할 때의 표준 흐름이다.

# 만드는 쪽
cd /release/v2.4.0
sha256sum app.tar.gz config.yml > SHA256SUMS

# 받는 쪽
cd /release/v2.4.0
sha256sum -c SHA256SUMS
app.tar.gz: OK
config.yml: OK

3) 서버 간 전송 후 무결성을 확인한다. rsync나 scp가 성공했다고 해서 디스크에 제대로 내려앉았다는 보장은 아니다. 특히 스토리지 장애를 겪은 뒤에는 확인할 값어치가 있다.

sha256sum /backup/shopdb_20260825.sql
ssh db2 'sha256sum /backup/shopdb_20260825.sql'

두 값을 자동으로 비교하려면 이렇게 한다.

LOCAL=$(sha256sum /backup/shopdb_20260825.sql | cut -d' ' -f1)
REMOTE=$(ssh db2 "sha256sum /backup/shopdb_20260825.sql" | cut -d' ' -f1)
[ "$LOCAL" = "$REMOTE" ] && echo 'OK' || echo 'MISMATCH'

4) 디렉터리 전체의 지문을 떠 두고 나중에 변경 여부를 본다. 설정 디렉터리가 누군가에 의해 바뀌었는지 확인하는 간단한 방법이다.

# 기준 시점
find /etc/nginx -type f -print0 | sort -z | xargs -0 sha256sum > /root/nginx_baseline.sha256

# 나중에
sha256sum -c --quiet /root/nginx_baseline.sha256

--quiet를 주면 달라진 파일만 나온다. 파일 수가 많을 때 눈에 훨씬 잘 들어온다.

5) 스크립트에서 종료 코드로만 판단한다. 로그를 더럽히지 않고 조건 분기만 하고 싶을 때 --status를 쓴다.

if sha256sum -c --status SHA256SUMS; then
  tar xzf app.tar.gz -C /opt/app
else
  echo '아티팩트 검증 실패. 배포를 중단한다.' >&2
  exit 1
fi

6) 다운로드하면서 동시에 해시를 계산한다. 디스크에 임시 파일을 두 번 읽지 않아도 된다.

curl -sL https://example.com/app.tar.gz | tee app.tar.gz | sha256sum

함정과 주의점

md5는 이미 깨진 알고리즘이다. 2004년에 서로 다른 두 입력이 같은 MD5 값을 갖도록 만드는 충돌 공격이 실증됐고, 이후 노트북 수준의 연산으로도 몇 초 안에 충돌을 만들어낼 수 있게 됐다. 2012년 Flame 악성코드는 실제로 MD5 충돌을 이용해 위조된 코드 서명 인증서를 만들어 윈도우 업데이트로 위장했다. SHA-1도 2017년 SHAttered 연구로 실제 충돌 PDF 두 개가 공개되면서 같은 처지가 됐다.

단순한 전송 오류 검출이라면 md5도 여전히 동작하지만, 누군가 의도적으로 파일을 바꿔치기하는 상황을 막을 수는 없다. 보안이 얽힌 자리에서는 반드시 sha256 이상을 쓴다. 성능 차이는 요즘 CPU에서는 무시할 수준이다.

체크섬은 무결성을 증명할 뿐 진위를 증명하지 않는다. 이게 가장 중요한 오해다. 파일과 SHA256SUMS가 같은 서버에 나란히 놓여 있다면, 그 서버를 장악한 공격자는 둘 다 바꾸면 그만이다. 검증은 깨끗하게 통과하지만 파일은 변조된 것이다. 체크섬이 지켜 주는 것은 전송 중 손상과 스토리지 비트 썩음 정도다. 배포처가 누구인지까지 확인하려면 GPG 서명(gpg --verify SHA256SUMS.asc SHA256SUMS)이나 사이닝 인프라가 필요하다. 공개 키는 반드시 다른 경로로 받아야 의미가 있다.

-c 는 목록에 적힌 경로를 현재 디렉터리 기준으로 찾는다. sha256sum app.tar.gz > SHA256SUMS로 만든 파일에는 app.tar.gz라는 상대 경로만 들어간다. 다른 디렉터리에서 sha256sum -c /release/SHA256SUMS를 실행하면 No such file or directory와 함께 실패한다. 목록 파일이 있는 디렉터리로 이동한 뒤 검증한다. 절대 경로로 만들면 다른 서버에서 경로가 달라 또 깨지므로, 상대 경로 + 디렉터리 이동이 가장 무난하다.

목록 파일의 형식이 조금이라도 깨지면 한 줄도 검증하지 않는다. 표준 형식은 텍스트 모드가 공백 두 칸, 바이너리 모드가 공백 한 칸 + *다. GNU sha256sum은 검증할 때 공백 한 칸이나 탭도 받아 주지만, 체크섬이 64자가 아니거나 구분자가 아예 없으면 no properly formatted checksum lines found와 함께 통째로 실패한다. 웹에서 복사한 체크섬을 붙여 넣을 때는 줄바꿈이 중간에 끼어들기 쉬우니 -c -로 넘기기 전에 확인한다.

macOS·BSD에는 GNU sha256sum이 없거나 다르다. macOS에는 shasum -a 256이 어디서나 통하는 표준이다. 최근 macOS에는 /sbin/sha256sum도 들어 있고 출력 형식과 --quiet·--ignore-missing 같은 긴 옵션까지 GNU에 맞춰 두었지만, 이는 md5 계열 도구가 GNU 호환 모드로 동작하는 것이라 오래된 macOS나 다른 BSD에는 없다. FreeBSD는 sha256이라는 이름에 출력 형식도 SHA256 (file) = ...로 다르다. 이식성이 필요하면 리눅스에서 --tag로 BSD 형식을 맞추거나, macOS에 brew install coreutilsgsha256sum을 넣는다.

대용량 파일은 시간이 걸리고 디스크를 갈아 마신다. 500GB 백업의 해시를 계산하면 그 500GB를 전부 읽는다. 운영 중인 스토리지에서 업무 시간에 돌리면 I/O가 눈에 띄게 밀린다. ionice -c3를 붙이거나 한가한 시간에 돌린다.

함께 보면 좋은 명령어

  • rsync-c 옵션을 주면 자체 체크섬으로 파일을 비교한다. 전송과 검증을 한 번에 하려면 이쪽이 편하다.
  • find — 디렉터리 전체 체크섬 목록을 만들 때 find ... -print0 | xargs -0 sha256sum 형태로 짝을 이룬다.
  • gpg — 체크섬 목록 자체에 서명해 진위까지 보장하고 싶을 때 필요하다.