2026 unknown 하계 세미나

보안 적합성 검사

해피가스트 2026. 7. 9. 19:54

보안 적합성 검사

-국가 보안적합성 검증 체계의 이해

오늘의 목표

이름이 비슷한 세 가지 - 구별하기

  1. 보안기능 확인서
  2. KCMVP
  3. CC 인증

보안적합성 검증

국가/공공기관이 IT 제품을 도입하기 전, 안전성을 검증하는 제도

  • 운용 주체: 국가정보원
  • 도입 전 검증 → 취역점 보완 → 도입 - 공공 조달의 관문 역할

최근 편입 사례

영상정보처리기기(2024.4.1)

  • TCP/IP로 연결되는 카메라 = 검증 대상
  • SDI/아날로그 전송 카메라 = 대상 제외
  • 기술 요구사항: 2024.4.1. V3.0—현행 기준

국가용 보안 요구사항

  • 칩입차단(4) - FW/웹 방화벽 등
  • 칩입방지(2) - IPS/무선 IPS
  • 구간보안(4) - VPN/NAC 등
  • 전송자료보안(4) - 보안/USB 등
  • 보안관리(6) - 패치관리 등
  • 가상화(1) - 가상화 관리
  • 엔드포인트보안(5) - 안티바이러스 등
  • 네트워크 장비(3) - 스위치/SDN
  • 양자암호통신(3) - QKD 등
  • 영상정보처리기기(2) - IP 카메라/영상 저장

공통 보안 요구 사항

서버 공통 9대 분류

  • 식별 및 인증
  • 보안관리
  • 데이터 보호
  • 자체보호
  • 업데이트 보호
  • 안전한 세션 관리
  • 감사기록
  • 암호 지원
  • 취약성 대응

보안 기능 시험제도(VSFT)

역할 분담표

주제 이름 하는 일정
정책 기관 NIS(국가정보원) 검증 정책 수립, 시험기관 지정 승인, 확인서 효력 관리
검증 기관 NSR(국가보안기술연구소) 시험 가이드 제공, 시험결과 검증, 확인서 발급 승인
시험 기관 TTA(영상기기분야) 보안 기능 시험 수행, 보안 기능 확인서 발급
신청 기관 제조 업체 시험 신청, 제출문서 작성, 취약점 개선

End-to-End 절차

 

보안 기능 확인서

  • 시험기준 만족을 확인하여, 검증기관 승인하에 시험기관이 발급하는 증서
  • ‘발급일까지 알려진 취약점 제거’를 확인
  • 발급 이후의 안전까지 보장하는 것은 아님
  • 도입기관은 이 확인서로 제품의 검증 상태를 봄

제출 문서

문서 내용
제품설명서 제품 개요/구성
보안기능 구현명세서 보안기능/모든 인터페이스/모든 계정
운용설명서 설치/운용 방법
시험결과서 시험 결과
취약점 개선내역서 발견된 취약점의 조치 내역

KCMVP

Korea Cryptographic Module Validation Program — 암호모듈 검증 제도

  • 암호모듈이 규격대로 구현됐는지를 검증
  • 결과물 = ‘검증필 암호모듈’ — 검증필 목록에 등재됨
  • NIS가 안전성을 확인하고 공지

암호모듈 경계

  • 알고리즘 구현
  • 키 관리, 난수 생성
  • 자가시험(KAT/무결성)

보안 수준

수준 요구 수준
Level 1 기본 — SW 중심 기본 구현 검증
Level 2 변조 흔적/ 역할 기반 통제
Level 3 물리 침해 대응/ 키 접근 보호
Level 4 환경 이상(전압,온도) 대응

보안요구 영역

  • 명세
  • 포트/인터페이스
  • 역할/서비스 인증
  • 유한상태모델
  • 물리보안
  • 운영환경
  • 키 관리
  • 자가시험
  • 설계보증

KCMVP 검증 절차

  1. 신청
  2. 시험기관 시험
  3. NSR 검토
  4. 목록 등재

목록에서 반드시 읽을 다섯 가지

  • 모듈명/버전
  • 알고리즘
  • 보안 수준
  • 유효 기간
  • 운영환경

검증 대상 암호 알고리즘

  • 블록 암호
    • SEED · ARIA · HIGHT · LEA
  • 해시
    • SHA-2 (SHA-224 이상) · LSH
  • 메시지 인증
    • HMAC
  • 공개키·서명
    • RSA · KCDSA · ECDSA
  • 키설정
    • 키 교환 · 키 유도
  • 난수
    • DRBG

국산 검증필

  • 주권
    • 국가 기밀을 지키는 암호
    • 검증 주체가 국내에 있어야 함
  • 검증 가능성
    • 설계 근거와 시험 기준을 국가가 직접 확인
  • 국제 표준 등재
    • SEED·ARIA·HIGHT:
      ISO/IEC 18033-3
      LEA: ISO/IEC 29192-2

범용 블록 암호

SEED

개발 KISA · 1999
블록 128비트
표준 ISO/IEC 18033-3
자리 금융·공공에서 오래 사용

ARIR

개발 학·연·관 공동 (Academy·Research·Agency)
블록/키 128비트 · 키 128/192/256
표준 KS 표준
특징 involution 구조 — 암·복호 대칭

경량 블록 암호

HIGHT

블록  64비트 — 경량
무대 RFID · 센서 · 저전력
표준 ISO/IEC 18033-3
특징 자원 제약 장치용 설계

LEA

개발 NSR · 2013
블록 128비트—SW 고속
표준 ISO/IEC 29192-2 (경량암호)
무대 IoT · 고속 SW 처리

국산 블록 암호 - 비교

알고리즘 블록 크기 성격/용도 표준화 
SEED 128비트 범용 — 금융·공공의 초기 표준 ISO/IEC 18033-3
ARIA 128비트 범용 — 키 128/192/256, involution 구조 KS 표준
HIGHT 64비트 경량 — RFID·센서·저전력 ISO/IEC 18033-3
LEA 128비트 경량·SW 고속 — IoT (NSR 2013) ISO/IEC 29192-2

보안 요구 사항 - 공통의 뼈대

  1. 식별 및 인증
  2. 보안관리
  3. 데이터 보호
  4. 자체 보호
  5. 업데이트 보호
  6. 안전한 세션 관리
  7. 감사기록
  8. 암호 지원
  9. 취약성 대응

식별/인증과 보안 관리 - 패스워드

구분 규칙
준수 9자리 이상
준수 숫자·대문자·소문자·특수문자 각 1자 이상
금지 사용자 계정(ID)과 동일
금지 동일 문자·숫자 연속 반복
금지 키보드·순차 나열 (4자 이상)
금지 직전 패스워드 재사용

데이터 보호와 자체 보호

  • 전송
    • 관리 접속도 HTTPS(TLS) 전용
  • 저장
    • 패스워드는 bcrypt 일방향 해시(salt), 영상 키는 DEK→KEK 구조
  • 자체 시험
    • 구동 시 암호·TLS 자체시험, 실패하면 fail-closed 종료
  • 무결성
    • 설정·실행파일을 SHA-256으로 검증 (실행 시 + 주기적)

세션 관리와 감사 기록

  • 감사기록 생성 — 로그인·잠금·설정변경·세션종료·중복접속 차단 등
  • 기록 항목 — 발생일시 · 사건유형 · 주체 · 결과 (인증정보·암호키는 기록 금지)
  • 보호 — 감사기록은 변경·삭제 불가, 조회는 인가된 관리자만

암호 지원

항목 요구 사항
암호 통신 HTTPS — TLS 1.2 이상(RFC 5246 이상) · 원격관리는 SSH V2
알고리즘 보안강도 112bit 이상 · 검증대상 알고리즘 (9.1.1)
키 생성 PBKDF2 — salt 128bit 이상 · 난수발생기 생성
키 저장 DEK를 KEK로 암호화 저장 · 암호키 하드코딩 금지
키 파기 사용 종료 시 파기 — 덮어쓰기로 흔적 제거

코드

TLS 1.2 강제

def create_ssl_context(cert_path: str, key_path: str) -> ssl.SSLContext:
		ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
		# [NIS 1.2.1(1), 4.1.1(1)] TLS 1.2 이상만 허용
		ctx.minimum_version = ssl.TLSVersion.TLSv1_2
		# [NIS 1.2.1(1)] TLS 1.0, 1.1 및 SSL 2/3 명시적 차단
		ctx.options |= ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 \
								| ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
		ctx.load_cert_chain(cert_path, key_path)
		return ctx
		
  • 한 줄(minimum_version)이 아니라 두 겹
  • 명시적 차단 옵션까지 건다
  • 조항 번호가 주석으로 코드에 박혀 있다
    = 추적매트릭스의 실체

패스워드 표 1

def validate_password(password, username=None):
		# [표1 금지] 사용자 계정(ID)과 동일한 패스워드 금지
		if username and password.lower() == username.lower():
				return False, "사용자 계정(ID)과 동일한 패스워드는 사용할 수 없습니다"
		# [표1 준수] 9자리 이상의 길이 확보
		if len(password) < 9:
				return False, "패스워드는 9자 이상이어야 합니다"
				
def _has_keyboard_sequence(password, min_length=4):
		# [표1 금지] qwer/asdf/1234 등 키보드 연속 4자 이상 차단
		pw_lower = password.lower()
		for row in KEYBOARD_ROWS:
				for i in range(len(row) - min_length + 1):
						seq = row[i:i + min_length]
						if seq in pw_lower or seq[::-1] in pw_lower:
							return True
		return False

5회 잠금, 구현과 검사가 마주본다

# 구현 — server/auth.py

if not self._verify_password(password, user.password_hash):
		attempts = self.db.increment_failed_attempts(username)
		# [NIS 2.2.1(2)] 5회 이하 연속 실패 시 인증 비활성화
		if attempts >= self.max_failures:
				self.db.lock_user(username, self.lockout_duration)
				# [NIS 8.1.1 표3] 한계치 도달 -> 감사기록
				self.audit.log(AuditEventType.ACCOUNT_LOCKED, ...)
		
  • 5회째에 잠금
  • 잠금 사건을 검사기록으로 남김
  • 잠금과 기록이 한 몸
# 검사 — validator/main.py

# 5회 실패 시도
for i in range(5):
		resp = self._login(test_user, wrong_pass)
# 6번째 -- 정상 비밀번호여도 잠금 상태여야 한다
resp = self._login(test_user, self._test_pass)
if resp.status_code == 401:
		self._add("인증 실패 5회 잠금", True, "잠금 동작 확인")
  • 검사기는 서버 코드를 보지 않음
  • 밖에서 실제로 두들겨 ‘행동’으로 판정함

지울 수 없는 기록, 사라져야 하는 키

# 감사기록 — 지울 수 없게 · server/audit.py

-- [NIS 8.3.1(2)] 인가된 관리자라도 삭제 불가
CREATE TRIGGER prevent_audit_delete
BEFORE DELETE ON audit_log
BEGIN
		SELECT RAISE(ABORT, '감사기록은 삭제할 수 없습니다');
END;
  • DB 트리거가 DELETE 자체를 실패시킴
  • 관리자 권한으로도 우회할 수 없음
# 암호키 — 반드시 사라지게 · client/crypto.py

def wipe(self) -> None:
		# [NIS 9.4.1(2)] 0으로 3회 덮어쓰기
		for _ in range(3):
				ctypes.memset(
						(ctypes.c_char * len(self._buf)).from_buffer(self._buf),
						0, len(self._buf))
		self._buf = bytearray()
  • 메모리를 0으로 3회 덮어씀 - 흔적까지 지운다

속지 않는 서버

# 실패 사유를 말하지 않는다 · server/auth.py 

AUTH_FAIL_MSG = "인증 실패"
# 없는 계정인지, 틀린 패스워드인지 알려주지 않는다
# [NIS 2.5.2] 인증 실패 사유 미제공
  • 계정 열거 차단 - CTF에서 늘 먼저 찔러보는 곳
# 헤더를 믿지 않는다 · server/main.py

def get_client_ip(request: Request) -> str:
		# [NIS 3.3.1] X-Forwarded-For를 신뢰하면
		# IP 화이트리스트 우회 가능 -- 사용 금지
		return request.client.host if request.client else "unknown"
  • XFF 헤더는 공격자가 마음대로 씀 - 소켓의 실제 peer만 신뢰

입구는 한 명씩만

# server/main.py

def _validate_single_host_ip(ip_str: str) -> tuple[bool, str]:
		# [NIS 3.3.1(4)] 와일드카드, any, 범위 표현 차단
		blocked_patterns = ["*", "any", "0.0.0.0", "::", "0:0:0:0:0:0:0:0"]
		if ip_str.lower() in blocked_patterns:
				return False, f"'{ip_str}'는 허용되지 않는 IP 형식입니다"
		if "*" in ip_str or "?" in ip_str:
				return False, "와일드카드(*, ?)를 포함한 IP는 허용되지 않습니다"
		...
# 미들웨어 — 차단 + 감사기록

@app.middleware("http")
async def ip_whitelist_middleware(request, call_next):
		# [NIS 3.3.1] 관리용 단말 IP 제한 + 차단 시 감사기록
		client_ip = get_client_ip(request)
		if not auth_manager.check_ip_whitelist(client_ip):
				audit_logger.log(AuditEventType.IP_BLOCKED, ...)
				return JSONResponse(status_code=403, ...)
		
  • ‘전부 허용’으로 도망갈 길을 코드가 막음
  • 차단도 감사기록이 남음

키를 지키는 계층

# 패스워드 → bcrypt · server/auth.py

def _hash_password(self, password: str) -> str:
		# [NIS 4.2.1(5)] 일방향 해시 + salt 128bit
		# bcrypt는 salt 랜덤 생성 + iteration 내장
		return bcrypt.hashpw(
		password.encode("utf-8"), bcrypt.gensalt()
		).decode("utf-8")
		
  • 복원할 필요가 없는 값
  • 일방향 해시로만 저장함
  • salt·iteration은 bcrypt에 내장.
# 패스프레이즈 → KEK · client/crypto.py

def derive_kek(self, passphrase, salt=None):
		# [NIS 9.2.1(1)] PKCS#5 v2.1(RFC 8018) -- PBKDF2HMAC
		if salt is None:
				salt = os.urandom(16) # [9.2.1(5)] salt 128bit
		kdf = PBKDF2HMAC(
				algorithm=hashes.SHA256(),
				length=32, # [9.1.1] 보안강도 112bit 이상
				salt=salt,
				iterations=self.kek_iterations, # 100000회
		)
		
  • 패스프레이즈에서 KEK를 유도
  • 기준의 숫자 세 개가 인자에 그대로 박혀 있음

부팅부터 의심

# 구동 시 자체시험 · client/selftest.py

def run_self_test(config) -> tuple[bool, list[str]]:
		# [NIS 5.1.1(1)] 구동 시 필수 자체시험
		# 1. [5.1.1(5)] 카메라 하드웨어 접근
		# 2. [5.1.1(2)] 서버 연결 (네트워크 프로세스)
		# 3. [5.1.1(2)] TLS 인증서 유효성
		# 4. [5.1.1(2)] 암호화 모듈 동작
		...

  • 켜질 때마다 카메라·서버·TLS·암호 모듈을 스스로 점검
# 주기적 무결성 검증 · client/integrity.py

def verify(self) -> list[dict]:
		# [NIS 5.2.1(2)(4)] 현재 해시를 기준(baseline)과 비교
		# 실행 시 + 24시간 주기 자동 검증
		with open(self.hash_file) as f:
				baseline_doc = json.load(f)
		...
  • 돌아가는 중에도 24시간마다 파일 해시를 기분과 대조

검증 자동화

요구사항 검사는 어떻게 자동화되는가

검사 대상 서버 → 검사기 → PASS/FAIL (리포트 + NIS 조항)
  • 검사기기는 문서를 읽지 않음
  • 실제로 접속하고, 로그인하고, 공격을 흉내 내서 방어를 확인함
  • 38개 세부 항목을 자동 판정하고, 각 판정에 NIS 조항 번호를 붙임

validator가 보는 것

검사/항목 내용 NIS 조항 
TLS 버전 TLS 1.0/1.1 거부 · 1.2 이상만 허용 1.2.1① · 4.1.1①
암호 스위트 112bit 이상 · 금지 알고리즘 없음 9.1.1①②
불필요 포트 지정 포트 외 열린 포트 없음 3.2.1 · 10.3.1
인증 실패 잠금 5회 실패 → 잠금 2.2.1②③
중복 로그인 동일 계정 동시 접속 차단 7.2.1①
세션 만료 유휴 시 토큰 만료 7.1.1②
패스워드 정책 9종 입력 — 표1 준수·금지 2.3.1 표1
IP 범위 차단 7종 입력 — 0.0.0.0 · * · CIDR 거부 3.3.1③④
계정명 차단 8종 입력 — admin·root 등 거부 3.4.1④
감사 기록 이벤트 생성·항목 확인 8.1.1 · 8.1.2

심사의 벽

  1. 문서의 벽
  • 제출문서 5종 전부 한국어
  • 구현명세서에는 모든 인터페이스·모든 계정을 전수 기재, 미재 발견
    = 백도어 간주 → 발급 거부

2. 이력의 벽

  • 취약점 개선내역서
  • 신청일 3년 전부터 신청 전일까지, 제품에 해당하는 공개 취약점(CVE 등)의 개선 완료 내역을 기재

3. 요구사항의 벽

  • 공통 9대분류 + 제품별 요구사항
  • 조항 하나하나를 구현·문서·시험과 1:1로 잇는 추적매트릭스

4. 시간의 벽

  • 권장 시험기간
  • 공통요구사항 35~40일 + 제품 요구사항 5~10일, ‘부적합’ 판정마다 보완 루프로 되돌아감

5. 유지의 벽

  • 확인서 유효기간 5년/2년
  • 형상(버전) 변경 시 추가시험·동일성 확인 시험, 발급 후에도 관리가 계속됨

AI가 가속하는 것들

과거 지금
조항 코드 추적매트릭스를 수작업으로 관리 코드 주석 기반 자동 생성·동기화
— 앞의 [NIS 2.3.1] 주석이 그 재료
요구사항·지침 문서 수백 쪽을 정독·해석 조항 요약·해석 보조, 구현 체크리스트로 변환
구현명세서 등 문서 5종 초안을 손으로 작성 코드에서 인터페이스·계정 목록 추출, 한국어 기술문서 초안 생성
3년치 공개 취약점(CVE) 이력을 일일이 조사 의존성·CVE 스캔과 개선내역 정리 자동화
시험 전 자체 점검(사전 모의심사)을 수동으로 자동 검증기 생성
— 38항목 PASS/FAIL (앞의 validator)

방법론

실전

프롬프트 예시

① “IP카메라 요구사항 2.2.1을 구현해줘 — 연속 인증 실패 5회 이하에서 계정 잠금,
5분 경과 후 해제, 잠금 발생 시 감사기록. 구현부마다 [NIS 2.2.1] 주석을 달아줘.”
→ 산출물: 잠금 로직 코드 — 앞 ‘코드로 보는 조항 ③’에서 본 것

② “코드베이스 전체에서 [NIS *] 주석을 스캔해 조항 파일 함수 추적매트릭스를
표로 만들어줘. 체크리스트와 대조해 미구현 조항을 표시해줘.”
→ 산출물: 추적매트릭스 — 앞 추적매트릭스 장에서 본 것

③ “이 서버를 밖에서 검사하는 자동 검증기를 만들어줘 —
TLS 1.0/1.1 접속이 거부되는지, 틀린 패스워드 5회 후 정상 패스워드로도 로그인이 막히는지,
판정마다 조항 번호를 붙여 PASS/FAIL 출력.”
→ 산출물: validator — 앞 ‘출력 예시’ 장에서 본 것

'2026 unknown 하계 세미나' 카테고리의 다른 글

물리계층 보안 (PHY-Security) 입문  (0) 2026.07.13
시큐어 코딩  (0) 2026.07.08
자동차 보안  (0) 2026.07.08
PQC II  (0) 2026.07.08
격자 기반 암호SIS · LWE부터 Kyber와 ML-KEM  (0) 2026.07.08