인증이란?
**인증(Authentication)**은 누군가 또는 무언가의 **신원(Identity)**을 확인하는 과정이다. 통신이 시작되기 전에 신뢰를 구축하고, 사용자나 리소스를 식별하는 역할을 한다.
인증은 일상에서 흔히 볼 수 있다.
- 사람이 다른 사람을 알아보는 것
- PC, ATM, 스마트폰의 접근 제어
- 건물, 구역의 물리적 접근 제어
- 여권, 운전면허증을 통한 신원 확인
검증 vs 식별
**검증(Verification)**과 **식별(Identification)**은 비슷해 보이지만 다르다.
- 검증: "이 사람이 본인이 주장하는 그 사람인가?"
- 1:1 비교 (one-to-one comparison)
- 식별: "이 사람이 등록된 사용자인가? 그렇다면 누구인가?"
- 1:N 비교 (one-to-many comparison)
인증의 세 가지 방법
인증 방식은 크게 세 가지로 나뉜다.
| 방식 | 설명 | 예시 |
|---|---|---|
| Knowledge | "알고 있는 것" | 비밀번호, PIN |
| Token | "가지고 있는 것" | 스마트카드, USB 토큰, 여권 |
| Biometrics | "자신의 고유한 것" | 지문, 홍채, 서명, 음성 |
생체인증(Biometrics)은 다시 두 가지로 나뉜다.
- 생리적 특성: 지문, 홍채 패턴, 손 모양
- 행동적 특성: 서명하는 방식, 말하는 방식
비밀번호 기반 인증
가장 기본적인 인증 방식인 Knowledge 기반 인증을 살펴보자.
평문 비밀번호의 문제점
평문(Clear-Text) 비밀번호에는 두 가지 문제가 있다.
- 데이터베이스에 비밀번호가 평문으로 저장된다
- 해결: 암호화된 형태로 저장
- 비밀번호가 네트워크를 통해 평문으로 전송된다
- 해결: 암호화된 형태로 전송
비밀번호의 메시지 다이제스트
원본 비밀번호를 절대 저장하거나 전송하지 않는 방식이다. 대신 비밀번호의 **해시값(Message Digest)**을 데이터베이스에 저장하고, 인증 시에도 해시값을 비교한다.
하지만 이 방식은 **재전송 공격(Replay Attack)**에 취약하다. 공격자가 해시값을 가로채서 그대로 다시 보내면 인증이 통과되기 때문이다.
재전송 공격의 해결
각 메시지에 메시지 번호 같은 추가 정보를 포함시킨다.
수신자가 중복된 메시지를 받으면 폐기한다. TCP/IP(Layer 3, 4)에는 이미 이 기능이 구현되어 있다.
재작성 공격 (Rewrite Attack)
공격자가 메시지의 내용을 알고 있다면, 암호화된 메시지를 수정할 수 있다.
비밀번호 추측 공격
비밀번호 추측 공격은 두 가지 유형이 있다.
온라인 공격 (On-line Attack)
- 시스템 자체를 이용해 추측이 맞는지 확인
- 방어 방법:
- 추측 속도 제한: 틀린 횟수가 늘어날수록 다음 시도까지의 지연 시간 증가
- 시도 횟수 제한: 예를 들어 3회 실패 시 온라인 뱅킹 잠금
오프라인 공격 (Off-line Attack)
- 시스템 외부의 다른 방법으로 추측의 정확성 검증
- 비밀번호 저장 방식에 따라 공격 형태가 달라진다
암호화된 비밀번호
- 클라이언트가 서버와 SSL 연결을 수립
- 비밀번호를 포함한 모든 정보가 SSL로 암호화
- 서버 DB에도 암호화된 형태로 저장
- 비밀번호 파일은 읽기 불가능해야 한다
초기 Unix 시스템은 실제 비밀번호를 파일에 저장했지만, 현재는 그렇지 않다.
비밀번호 파일 보호
암호화 보호
- 단방향 암호화 알고리즘 사용 (하지만 사전 공격은 막지 못함)
- 적절한 암호화 선택으로 사전 공격을 늦출 수 있다 (예: crypt())
OS 수준의 접근 제어
- Unix/Linux: shadow password file 사용 (/etc/passwd와 분리, 보통 /etc/shadow)
- root 외에는 passwd 파일을 볼 수 없다
- Windows NT: 독자적인 바이너리 형식으로 암호화된 비밀번호 저장 (security by obscurity)
비밀번호 Salting
중복 비밀번호 문제가 있다. 같은 비밀번호를 쓰는 사용자들은 해시값도 같게 되어, 하나를 뚫으면 모두 뚫린다.
**솔팅(Salting)**으로 해결한다.
- 암호화된 비밀번호를 저장할 때 무작위 값을 추가
- 같은 비밀번호도 '다른' 암호화 결과를 가짐
- 사전 공격을 늦춤
- 공격자가 각 비밀번호를 개별적으로 크래킹해야 함 (전체 DB를 동시에 공격 불가)
해싱과 솔팅
비밀번호 해싱
비밀번호 솔팅
Linux 비밀번호 파일
Linux의 /etc/shadow 파일 구조를 보여준다.
인증 토큰
**인증 토큰(Authentication Token)**은 사용할 때마다 새로운 무작위 값을 생성하는 작은 장치이다.
구성 요소
- 프로세서
- 출력용 LCD
- 키패드 (선택)
- 실시간 시계 (선택)
유형
- Challenge/Response 방식
- Time-based 방식
작동 원리
- 토큰과 서버가 초기에 동기화
- 토큰이 주기적으로 새 비밀번호 생성
- 서버도 동일한 비밀번호 생성
토큰 생성
- 인증 토큰이 생성될 때 해당 **시드(seed)**도 함께 생성
토큰 사용
- 토큰이 자동으로 의사난수(pseudorandom number) 생성 (= 일회용 비밀번호)
- [ID / 비밀번호] 쌍을 서버에 제출
- 서버가 DB에서 해당 사용자 ID의 시드를 가져와 비밀번호 검증
- 토큰 자체도 비밀번호나 PIN으로 보호됨 ("알고 있는 것" + "가지고 있는 것")
일회용 비밀번호 (OTP)
두 가지 인증 기술이 결합된 방식이다. 대표적인 예가 ATM 카드와 PIN의 조합이다.
첫 번째 접근법
- 사용자와 시스템이 비밀번호 목록에 합의
두 번째 접근법
- 사용자와 시스템이 비밀번호를 순차적으로 업데이트
- P → P → P ...
세 번째 접근법
- 해시 함수를 이용해 순차적으로 업데이트되는 비밀번호 생성
- Lamport 일회용 비밀번호
Challenge/Response 토큰
- 클라이언트가 사용자 ID만으로 로그인 요청
- 사용자 ID가 유효하면, 서버가 무작위 챌린지 r을 사용자에게 전송 (평문 가능)
- 토큰이 r을 받아 seed로 암호화한 응답(일회용 비밀번호)을 생성하여 서버로 전송
- 서버가 암호화된 비밀번호를 검증
Time-based 토큰
- 클라이언트: 토큰이 [seed + 현재 시스템 시간]을 사용해 비밀번호 생성
- 서버가 무작위 챌린지를 보낼 필요 없음
- 시간이 무작위 챌린지 대신 가변 입력으로 사용됨
- 서버도 동일한 과정으로 비밀번호 검증
- 시간 창(time-window) 문제는 사용자가 시간을 앞으로 조정하여 해결 (1분, 2분, ...)
Challenge-Response 방식
- 비밀번호 인증: 청구인이 비밀(비밀번호)을 알고 있음을 보여줌으로써 신원 증명
- Challenge-Response 인증: 청구인이 비밀을 보내지 않고 알고 있음을 증명
- 챌린지는 검증자가 보내는 시간에 따라 변하는 값
- 응답은 챌린지에 함수를 적용한 결과
비대칭키 암호를 이용한 인증
단방향 비대칭키 인증
Bob이 Alice의 공개키로 챌린지를 암호화하고, Alice는 자신의 개인키로 복호화하여 응답(같은 nonce)을 Bob에게 전송한다.
양방향 비대칭키 인증
- 각 방향에 하나씩, 두 개의 공개키 사용
- Alice가 자신의 ID와 nonce를 Bob의 공개키로 암호화하여 전송
- Bob이 자신의 nonce를 Alice의 공개키로 암호화하여 응답
- Alice가 Bob의 복호화된 nonce로 응답
디지털 서명을 이용한 인증
Alice와 Bob이 서명을 사용해 서로를 인증하는 양방향 인증 방식이다.
영지식 증명 (Zero-Knowledge Proof)
**영지식 인증(Zero-Knowledge Authentication)**에서 청구인은 비밀의 기밀성을 위협하는 어떤 것도 노출하지 않는다.
- 청구인이 검증자에게 비밀을 알고 있음을 노출 없이 증명
- 상호작용이 비밀을 노출하거나 추측하는 것으로 이어지지 않도록 설계
- Challenge-Response 인증 방식의 더 정교한 형태
대화형 영지식 증명 시스템
인증서 기반 인증
사용자의 디지털 인증서를 기반으로 한 인증 방식이다.
- CA(인증 기관)가 사용자에게 인증서 배포
- 인증 시점에 양측 간 검증 수행
- 로그인 시 사용자가 서버에 인증서 전송
- 서버가 인증서의 유효성 검증
하지만 Trudy가 Alice의 인증서 사본을 가지고 Alice인 척할 수 있다.
인증 과정
- 사용자가 ID만으로 로그인 요청
- ID가 유효하면 서버가 무작위 챌린지 r 전송 (평문 가능)
- 사용자가 개인키로 r에 서명: s = E(r)
- 개인키는 비밀번호를 통해서만 접근 가능 ("알고 있는 것" + "가지고 있는 것")
- 서버가 r1 = D(s)와 r을 비교하여 인증
Step 1: 사용자의 컴퓨터가 개인키로 무작위 챌린지를 암호화하여 디지털 서명 생성
Step 2: 사용자의 컴퓨터가 로그인 요청의 일부로 디지털 서명을 서버에 전송
Kerberos
그리스 신화에서 Kerberos(케르베로스)는 여러 머리를 가진 개로, 하데스의 입구를 지키는 수호자이다.
배경
- 독립 PC (네트워크 연결 없음): 격리를 통한 보안
- 중앙 집중형 시분할 시스템: OS가 보안 제공
- 분산 아키텍처 (전용 워크스테이션 + 분산/중앙 서버): 문제 발생
문제점
개방된 분산 환경에서 워크스테이션의 사용자들이 서버의 서비스에 접근하려 하고, 서버는 인증된 사용자만 접근하도록 제한하고 싶다.
하지만 워크스테이션은 자신의 사용자를 네트워크 서비스에 정확히 식별한다고 신뢰할 수 없다.
네트워크 서비스 예: 프린터, 메일 서버, 파일 서버
위협
개방된 분산 환경에서 가능한 위협들:
- 사용자가 WS에 접근하여 다른 사용자인 척
- 사용자가 WS의 네트워크 주소를 변경하여 다른 WS에서 온 요청처럼 위장
- 사용자가 교환을 도청하고 재전송 공격으로 서버에 접근
Kerberos란?
네트워크 인증 프로토콜로, 어떤 두 개체 간에도 인증을 제공한다.
- 1980년대 중반 MIT에서 개발
- 버전 4와 5 존재
설계 목표와 결정
- 네트워크에 평문 비밀번호 없음 (도청 방어)
- 타임스탬프를 이용한 제한된 인증 수명 (재전송 공격 방어)
- 대칭키 암호화 사용 (ver.4: DES, ver.5: DES 외 다른 알고리즘)
- 키 배포를 위한 중앙 집중형 서버 사용 (AS + TGS)
단순 인증
Challenge/Response 인증은 개방된 환경에서 서버에 상당한 부담을 준다. 대신 **AS(Authentication Server)**를 사용한다.
첫 번째 시나리오
Kerberos가 아닌 단순한 방식이다.
문제점
- 비밀번호가 평문으로 전송
- 티켓이 재사용 불가
- 사용자가 매번 다른 서비스마다 비밀번호를 입력하고 티켓을 받아야 함
- 티켓이 재사용 가능해도 다른 서비스마다 새 티켓 필요
해결책: TGS(Ticket-Granting Server) 도입
두 번째 시나리오
- TGS 도입
- **Ticket**는 클라이언트의 워크스테이션에 저장
- 새 서비스 접근이 필요할 때마다 클라이언트가 Ticket를 TGS에 제시 (자신 인증용)
- TGS가 특정 서비스용 Ticket 발급
- message#2의 이중 암호화 (E[Ticket])
- TGS만 티켓 내용을 볼 수 있음 (클라이언트도 불가)
- 클라이언트만 티켓을 복구 가능 (K 때문)
K: AS와 C 간 공유되는 비밀키
- 사용자의 비밀번호 기반 암호화
- 사용자가 비밀번호로 워크스테이션에 로그인하면 클라이언트가 Kc를 유도
- AS도 DB의 사용자 비밀번호에서 Kc를 유도할 수 있음 (또는 Kc를 DB에 저장)
- 따라서 비밀번호가 네트워크를 타지 않음
- 올바른 사용자만 Ticket를 복구 가능
타임스탬프와 수명(티켓 유효 기간)을 통해 클라이언트가 재사용 가능한 티켓을 가지고, 새 서비스 요청마다 사용자를 귀찮게 하지 않아도 된다.
두 번째 시나리오의 첫 번째 문제
티켓 수명의 길이 문제
- 너무 짧으면: 여러 티켓 필요
- 너무 길면: Trudy가 사용할 수 있음
- Trudy가 Ticket 캡처
- Alice 로그오프
- Trudy가 Alice의 네트워크 주소와 **Ticket**로 Alice 사칭
Ticket도 같은 문제가 있다. 따라서 네트워크 서비스는 티켓을 사용하는 사람이 티켓이 발급된 사람과 동일한지 증명할 수 있어야 한다.
첫 번째 문제의 해결
AS가 클라이언트와 TGS 양쪽에 비밀 정보를 제공한다 (message#2).
K (클라이언트와 TGS 간 세션 키)
- **K**로 암호화됨: 클라이언트만 복구 가능
- **Ticket**에 포함됨: TGS만 얻을 수 있음
클라이언트가 TGS에 **인증자(Authenticator)**를 전송한다.
Authenticator = E[ ID || AD || Timestamp ]
- 인증자의 ID와 AD가 Ticket의 내용과 일치
이를 통해 티켓 제시자가 클라이언트 본인임을 증명한다. 인증자는 한 번만 사용되고 매우 짧은 수명을 가진다. 이 덕분에 티켓 수명은 길고 재사용 가능하다.
두 번째 시나리오의 두 번째 문제
클라이언트가 서버를 인증해야 한다. Trudy가 클라이언트의 메시지를 다른 서버로 보내고 그 서버가 서비스를 거부하면 어떻게 되는가?
서버 인증이 필요하다. message#5 이후 서버가 클라이언트에게 다른 인증 메시지를 보낸다. 세션 키 K (클라이언트와 애플리케이션 서버 간)가 인증에 사용된다.
Kerberos 용어
| 용어 | 설명 |
|---|---|
| AS (Authentication Server) | 일종의 KDC. 클라이언트 로그온을 인증하고 추가 인증을 위한 TGT 발급 |
| TGS (Ticket Granting Server) | 일종의 KDC. TGT를 가진 클라이언트에게 특정 애플리케이션 서버용 SGT 발급 |
| TGT (Ticket Granting Ticket) | TGS를 위한 클라이언트 인증서 포함. TGS의 키로 암호화 |
| SGT (Service Granting Ticket) | 서버를 위한 클라이언트 인증서 포함. 서버의 키로 암호화 |
Kerberos 절차 (ver. 4)
Step 1: 인증 서비스 교환
TGT(Ticket-Granting Ticket)를 받는다.
Step 2: 티켓 발급 서비스 교환
SGT(Session-Granting Ticket)를 받는다.
Step 3: 클라이언트/서버 인증 교환
상호 인증(Mutual Authentication)을 수행한다.
HGU 전산전자공학부 고윤민 교수님의 24-2 컴퓨터 보안 수업을 듣고 작성한 포스트이며, 첨부한 모든 사진은 교수님 수업 PPT의 사진 원본에 필기를 한 수정본입니다.