| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- Dreamhack
- sk쉴더스 루키즈
- sk 쉴더스 루키즈
- 자바
- React
- 웹개발
- 프리코스
- 우테코
- 깃
- 루키즈 31기
- 악성코드 분석
- 서울청년문화패스
- 우아한테크코스
- 루키즈31기
- 레나튜토리얼
- 코리안챔버오케스트라
- c
- 예술의 전당
- 다이나믹 프로그래밍
- 진입차수
- 프랑스어 #프랑스어배우기 #프랑스어독학 #델프인강 #시원스쿨프랑스어 #delf독학 #델프 #프랑스어기초 #프랑스어공부
- linux
- SK쉴더스
- 트랜스포트 계층
- 백엔드
- 위상 정렬
- 애플리케이션 계층
- SK쉴더스루키즈
- webhacking
- 알고리즘
- Today
- Total
yon11b
[SK 쉴더스 루키즈] notepad++ 무결성 검증하기 본문
들어가며
여러분이 매일 다운로드 받는 프로그램들, 정말 안전할까요?
"공식 사이트에서 받았으니까 괜찮겠지" 라고 생각하기 쉽지만, 현실은 그렇지 않습니다. 2017년 가짜 Notepad++ 사이트 사건, 2020년 SolarWinds 공급망 공격, 2024년 xz-utils 백도어 사건 — 모두 "정식 다운로드처럼 보이지만 실제로는 변조된 파일" 이 핵심이었어요.
만약 Notepad++ 업데이트 서버가 공격당해서 악성코드가 심긴 설치 파일이 배포된다면, 우리는 그걸 어떻게 알아챌 수 있을까요?
이 글에서는 GPG 서명 검증을 통해 무결성을 검증하는 방법을 실습해봅니다.
GPG란?
GPG(GNU Privacy Guard) 는 파일이나 메시지를 암호화하고 디지털 서명하는 오픈소스 도구입니다. 공개키 암호 기반으로 동작합니다.
GPG의 3가지 역할
- 암호화 — 메시지를 수신자만 읽을 수 있게 만들기
- 디지털 서명 — "이 파일은 진짜 내가 만든 것이며 변조되지 않았다"를 증명
- 키 관리— 공개키-개인키 쌍 생성과 배포 관리
이번 실습에서 활용할 기능은 2번 디지털 서명입니다.
실습에서 등장하는 두 종류의 파일
| 파일 | 정체 | 역할 |
| GPG Signature (.sig) | 디지털 서명 | 특정 파일이 변조되지 않았음을 증명 |
| GPG Public Key (.asc) | 공개키 | 서명을 검증할 때 사용 |
디지털 서명의 동작 원리
개발자 측: 서명 만들기
Notepad++ 개발자가 새 버전을 배포하기 전에 하는 일:
1. 원본 파일(notepad.exe)의 SHA-256 해시 계산
H = SHA-256(notepad.exe)
2. 그 해시값을 자신의 개인키로 서명
S = Sign(H, 개인키)
3. S를 .sig 파일로 저장하여 함께 배포
핵심 포인트: 파일 전체를 암호화하는 게 아니라 해시값만 서명합니다. 1GB 파일이든 1KB 파일이든 해시는 32바이트라서 빠르게 처리됩니다.
사용자 측: 서명 검증하기
다운로드 받은 파일이 진짜인지 확인하는 과정:
1. 받은 원본 파일의 해시 직접 계산
H1 = SHA-256(notepad.exe)
2. 받은 서명 S를 공개키로 검증(복호화)하여 원래 해시 추출
H2 = Verify(S, 공개키)
3. 두 해시값 비교
H1 == H2 → ✅ Good signature
H1 != H2 → ❌ BAD signature
왜 이게 위변조를 잡아내는가
세 가지 공격 시나리오를 통해 살펴봅시다.
시나리오 1: 파일을 변조했다
공격자가 notepad.exe에 악성코드를 심었지만 서명은 그대로:
H1 = SHA-256(변조된 exe) = ABC123...
H2 = Verify(원본 sig) = 7A3F2C...
H1 ≠ H2 → ❌ 검증 실패
해시는 1바이트만 바뀌어도 완전히 달라지므로 즉시 발각됩니다.
시나리오 2: 파일도 바꾸고 서명도 새로 만들었다
공격자가 변조된 파일에 자기 개인키로 새 서명을 만든 경우:
H2 = Verify(가짜 sig, Notepad++ 공개키)
= (의미 없는 값)
H1 ≠ H2 → ❌ 검증 실패
공격자에게는 Notepad++ 개발자의 개인키가 없기 때문에, 그 공개키와 짝이 맞는 서명을 만들 수 없습니다.
시나리오 3: 다른 버전의 서명을 가져다 붙였다
8.8.4의 sig 파일을 변조된 8.8.5에 붙이는 경우:
H1 = SHA-256(변조된 8.8.5 exe) = XYZ789...
H2 = Verify(8.8.4의 sig) = 9B2E1F...
H1 ≠ H2 → ❌ 검증 실패
서명은 특정 해시값에 종속되어 있어서 다른 파일에는 사용할 수 없습니다.
실습: Notepad++ 서명 검증 자동화 스크립트
이제 실제로 검증을 해봅시다. 아래 스크립트는 GPG 키 등록부터 파일 다운로드, 검증까지 한 번에 처리합니다.
#!/bin/bash
# ───── 1. GPG 공개키 등록 (한 번만 하면 됨) ─────
wget https://notepad-plus-plus.org/gpg/nppGpgPub.asc
gpg --import nppGpgPub.asc
# ───── 2. 설치 파일과 서명 파일 주소 ─────
EXE_URL="https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v8.8.5/npp.8.8.5.Installer.x64.exe"
SIG_URL="https://github.com/notepad-plus-plus/notepad-plus-plus/releases/download/v8.8.5/npp.8.8.5.Installer.x64.exe.sig"
EXE_FILE="npp.8.8.5.Installer.x64.exe"
SIG_FILE="npp.8.8.5.Installer.x64.exe.sig"
# ───── 3. 파일 다운로드 ─────
echo "[+] 파일 다운로드"
curl -L -o "$EXE_FILE" "$EXE_URL"
curl -L -o "$SIG_FILE" "$SIG_URL"
# ───── 4. GPG 서명 검증 ─────
echo "[+] GPG 서명 검증"
gpg --verify "$SIG_FILE" "$EXE_FILE"
gpg --verify 한 줄이 내부적으로 하는 일
gpg --verify notepad.exe.sig notepad.exe
이 명령어 한 줄의 내부 동작을 단계별로 보면:
1. notepad.exe 파일을 읽어 SHA-256 해시 계산
→ H1 = SHA-256(notepad.exe)
2. notepad.exe.sig 파일을 읽어 서명 데이터 추출
→ S = 서명 바이트열
3. GPG 키링에서 적절한 공개키 검색
(sig 파일에 어떤 키 ID로 서명됐는지 메타데이터로 명시됨)
→ public_key 획득
4. 서명 S를 공개키로 검증하여 원래 해시값 복원
→ H2 = Verify(S, public_key)
5. H1과 H2 비교
→ 일치 → "Good signature"
→ 불일치 → "BAD signature"
이 5단계가 한 줄 명령어 뒤에서 자동으로 일어나는 일입니다.
결과

Good signature 메시지가 핵심입니다. 이게 보이면 파일이 변조되지 않았음이 수학적으로 증명된 것입니다.
💡 WARNING은 왜 뜨는가?
"이 공개키가 진짜 Notepad++ 개발자의 키인지 GPG가 자동으로 보증할 수 없다"는 의미입니다. 공식 사이트에 게시된 키 지문(fingerprint)과 위 출력의 지문을 직접 비교하면 더 확실해집니다.
.exe파일을 변조한 뒤 다시 검증을 시도해봅니다.

Bad signature가 출력됩니다.
'보안 > SK 쉴더스 루키즈' 카테고리의 다른 글
| [SK 쉴더스 루키즈] 리눅스/윈도우 서버에서 자동 진단 수행하기 (0) | 2026.05.09 |
|---|---|
| [SK 쉴더스 루키즈] 중앙집중형 로그 관리 환경 구축(Fluent-Bit, OpenSearch Dashboard) (0) | 2026.05.09 |
| [SK 쉴더스 루키즈] Authentication Failures - 비밀번호 brute forcing 공격 실습 (0) | 2026.05.08 |
| [SK 쉴더스 루키즈] CSRF 실습(NodeGoat, bWAPP) (0) | 2026.05.08 |
| [SK 쉴더스 루키즈] Insecure Design(tampering 실습) (0) | 2026.05.07 |
