인증 실험실

인증 실험실

인증의 모든 방식은 하나의 원리로 정리됩니다. 비밀은 보내지 않고, 비밀로 계산한 결과만 보낸다. 내가 브라우저가 되어 은행과 연결하는 장면을 따라가며, 숫자가 실제로 어떻게 오가는지 직접 바꿔 봅니다. 처음 보는 사람도 위에서부터 순서대로 읽으면 끝까지 이해할 수 있게 구성했습니다.

내 손에만 있는 값 (안 보냄) 네트워크에 흐르는 값 (누구나 볼 수 있음) 각자 계산한 값 헷갈리기 쉬운 오해
  1. 큰 그림인증이 답하는 두 질문
  2. 기초 부품 8개해시, 서명, 인증서, nonce…
  3. TLS 1.3 한 바퀴브라우저가 은행을 확인
  4. 키 교환키를 안 보내고 같은 키 만들기
  5. nonce녹화 재생 공격 막기
  6. SSL, TLS 1.2, 1.3무엇이 바뀌었나
  7. 로그인과 세션은행이 나를 확인
  8. 서명된 토큰 (JWT)장부 없는 번호표
  9. OTP2단계 인증
  10. WVP에 적용사이트, 영상, 장비
  11. 기기 인증카메라와 NVR
  12. 용어 모음한 줄 정의
0 · 큰 그림

인증은 두 질문에 답하는 일

인증(AuthN)은 "너 누구야"이고, 인가(AuthZ)는 "너 뭐 할 수 있어"입니다. 로그인은 인증, 관리자 메뉴가 보이는지는 인가입니다. 이 페이지는 인증을 다룹니다.

어떤 인증이든 두 단계로 나뉩니다. 처음 증명(누구인지 확인)과 이후 유지(매번 "아까 그 상대 맞다"를 이어 가기). 은행 사이트에 들어가면 이 과정이 양쪽 방향으로 한 번씩 일어납니다.

1. TLS
이 서버, 진짜 은행이야?
브라우저가 은행을 확인하고 암호화 통로를 엽니다. 인증서와 서명, 키 교환.
2. 로그인
이 사람, 진짜 김상필이야?
통로 안에서 아이디·비밀번호를 보내 은행이 나를 확인합니다.
3. 유지
아까 로그인한 그 사람 맞아?
매 요청마다 번호표(세션)나 서명된 토큰(JWT)을 붙입니다.
4. 추가 확인
비밀번호만 털린 건 아니야?
OTP 같은 2단계 인증으로 "그 폰을 가졌는지"까지 봅니다.

TLS가 끝나도 은행은 아직 내가 누군지 모릅니다. "누군가와 안전한 통로가 생겼다"까지만 압니다. 그래서 그 안에서 다시 로그인을 합니다.

1 · 기초 부품

먼저 알아 둘 부품 8개

아래 장면과 실험은 모두 이 부품들의 조합입니다. 지금 다 외울 필요는 없고, 읽다가 막히면 돌아와서 보면 됩니다.

해시

입력을 넣으면 고정 길이 값이 나오는 한 방향 계산. 같은 입력은 항상 같은 값, 결과에서 입력을 되찾을 수 없음.

비유: 지문. 지문으로 사람은 확인해도, 지문에서 사람을 만들 수는 없다.

쓰이는 곳: 비밀번호 저장, 장비 로그인 응답값

HMAC

비밀값 + 내용을 섞어 만든 해시. 같은 비밀을 가진 쪽만 같은 결과를 만들 수 있음.

비유: 눈앞에서 금고를 열어 보이기. 비밀번호를 말하지 않고도 안다는 걸 증명.

쓰이는 곳: TLS 확인 메시지, OTP, 서명된 토큰

대칭키

잠그는 키와 여는 키가 같은 키. 빠르지만, 상대와 미리 나눠 가져야 하는 문제가 있음.

비유: 집 열쇠 복사본. 둘 다 같은 열쇠를 들고 있어야 함.

쓰이는 곳: TLS 연결 후 모든 데이터 암호화 (아래의 키 2)

키 교환

대칭키를 보내지 않고 양쪽이 각자 계산해서 같은 키를 얻는 방법. 공개된 재료만 오감.

비유: 각자 비밀 물감을 섞어 교환한 뒤 다시 섞으면 같은 색이 나옴.

쓰이는 곳: TLS 1.3 (실험 1)

공개키 · 개인키

한 쌍으로 만들어지는 키. 개인키는 주인만 갖고, 공개키는 누구에게나 줌. 이 페이지에서는 서명용으로만 씀.

비유: 도장(개인키)과 인감 대조용 견본(공개키).

쓰이는 곳: TLS 서명②, 인증서

서명

개인키로 만들고 공개키로 확인. "이 내용은 키 주인이 이 모양 그대로 만들었다"를 보증. 못 고치게 할 뿐, 못 보게 하는 건 아님.

비유: 계약서 도장. 내용은 누구나 읽지만 고치면 도장이 안 맞음.

쓰이는 곳: 인증서, TLS 서명②, JWT

인증서 · CA

인증서 = 공개키 + 이름(도메인) + 유효기간 + CA의 서명. CA는 인증서를 발급하는 기관이고, CA 공개키는 브라우저·OS에 미리 들어 있음.

비유: 신분증. 사진은 공개키, 발급기관 도장은 CA 서명.

쓰이는 곳: TLS (장면)

nonce

number used once. 이번 한 번만 쓰는 값. 대부분 난수로 만들지만 순번(1, 2, 3…)이어도 됨. 공개해도 됨.

비유: 창구 직원이 "방금 부른 숫자 7392를 적고 지금 서명하세요".

쓰이는 곳: TLS 랜덤값, 장비 로그인, OTP의 시각 (실험 2)

헷갈린 지점

✗"서명하면 내용이 숨겨진다"

서명은 내용을 숨기지 않습니다. 고치면 들킨다는 보증입니다. 숨기는 건 암호화(대칭키)의 일입니다.

✗"공개키는 잠그는 용도, 개인키는 여는 용도"

그런 용도도 있지만(옛 RSA 키 교환), TLS 1.3에서 은행 키 쌍은 서명에만 씁니다. 개인키로 서명을 만들고, 공개키로 확인합니다. 데이터를 잠그는 건 키 교환으로 만든 대칭키입니다.

2 · 장면

TLS 1.3 한 바퀴

"시작"을 누르면 숫자가 실제로 오가는 모습을 보여 줍니다. 신원 확인은 은행의 고정 키로, 암호화 키는 매번 새로 각자 계산합니다. 아래 "선 위에 흐른 것" 칸을 보면 엿보는 사람이 무엇을 손에 넣는지 알 수 있습니다.

인터넷 (누구나 엿볼 수 있음) 엿보는 사람이 본 것: 없음 나 (브라우저) 비밀숫자 6 CA 공개키 키 2 계산 인증서·서명② 확인 ✓ 서명② 안의 R1이 다름 ✗ 거부 은행 비밀숫자 15 + 은행 개인키 키 2 계산 확인 메시지 일치 ✓
0 / 5

준비

나는 비밀숫자 6을, 은행은 비밀숫자 15와 은행 개인키를 가지고 있습니다. 둘 다 아직 한 번도 밖으로 내보내지 않았습니다. 양쪽은 이번 연결에만 쓰는 무작위 값(nonce) R1, R2도 하나씩 만듭니다.

나만 아는 것비밀숫자 6
선 위에 흐른 것아직 없음
은행만 아는 것비밀숫자 15, 은행 개인키

인증서 = 신분증

신분증인증서
얼굴 사진은행 공개키
이름, 주소도메인(bank.com), 유효기간
발급기관 도장CA 서명 ①
앞사람 얼굴과 사진 대조은행 공개키로 서명 ② 확인

서명은 두 개

서명 ①서명 ②
어디에인증서지금 이 대화 전체
누가 찍나CA은행 (개인키)
뭘로 확인CA 공개키
(브라우저 내장)
은행 공개키
(인증서 안)
의미이 공개키는 진짜 은행 것인증서를 주운 게 아니라 진짜 본인

확인 순서 한 줄: CA 공개키 → 인증서 확인 → 그 안의 은행 공개키 꺼냄 → 은행 공개키 → 서명② 확인.

헷갈린 지점

✗"처음에 내 비밀숫자를 준다"

비밀숫자 6은 끝까지 나가지 않습니다. 나가는 것은 6으로 계산한 재료 8뿐입니다.

✗"인증서는 은행 공개키로 확인한다"

반대입니다. 인증서는 브라우저에 내장된 CA 공개키로 확인하고, 은행 공개키로 확인하는 것은 은행이 그 자리에서 찍은 서명②입니다.

✗"은행 공개키는 따로 받는다"

인증서 안에 들어 있습니다. 인증서를 받으면 같이 받는 것입니다.

✗"인증서만 있으면 충분하다"

인증서는 공개 정보라 누구나 복사해 보낼 수 있습니다. 서명②는 은행 개인키가 있어야만 만들 수 있어서, 인증서를 주운 사람과 진짜 은행을 가려 줍니다.

✗"은행이 내 재료 8을 다시 돌려보낸다"

돌려보내지 않습니다. 8을 포함한 대화 내용에 서명만 합니다. 나는 내가 보낸 8을 알고 있으니, 서명 내용과 대조할 수 있습니다.

✗"내가 보낸 8도 공개키로 처리해서 보낸다"

8은 그냥 보냅니다. 일반 브라우저는 자기 인증서가 없습니다. 대신 은행의 서명②가 "받은 값은 8"까지 포함하므로, 해커가 바꾸면 내가 서명을 확인할 때 걸립니다.

✗"확인 메시지에 키 2를 넣어 보낸다"

절대 보내지 않습니다. 대화 요약과 키 2로 계산한 결과값(HMAC)만 보냅니다. 금고 비밀번호를 말해 주는 게 아니라 눈앞에서 금고를 열어 보이는 것입니다. 실제로는 2를 그대로 쓰지 않고, 2에서 용도별 키(확인용, 암호화용, 방향별)를 여러 개 뽑아 씁니다.

✗"임시키를 은행 공개키로 잠가 보낸다"

이것은 TLS 1.2까지의 RSA 키 교환입니다. 통신을 녹화해 두었다가 나중에 은행 개인키를 훔치면 과거 통신이 전부 풀려서 TLS 1.3에서 없앴습니다. 1.3에서 은행 키는 서명에만 씁니다. (비교 보기)

✗"TLS 1.3에는 nonce가 없다"

있습니다. 양쪽이 32바이트 랜덤(R1, R2)을 하나씩 보내고, 매번 새로 만드는 재료(8, 19) 자체도 일회용입니다. 서명②가 이 값들을 포함한 대화 전체에 찍히기 때문에, 녹화한 옛 응답은 오늘 쓸 수 없습니다. 연결 뒤 데이터 덩어리에도 순번이 섞인 nonce가 붙습니다.

✗"TLS 단계에서 은행이 나를 확인한다"

하지 않습니다. 은행이 아는 것은 "누군가와 안전한 통로가 생겼다"까지입니다. 그래서 그 통로 안에서 로그인을 합니다. (로그인과 세션)

3 · 실험 1

키를 보내지 않고 같은 키 만들기

위 장면의 8, 19, 2가 어디서 나왔는지 직접 바꿔 봅니다. 공개값은 밑수 5, 나눗수 23이고, 계산은 "5를 n번 곱해 23으로 나눈 나머지"입니다. 공개값은 누구나 압니다.

숫자정체밖으로 나가나
5, 23공개값 (계산 규칙)누구나 앎
6, 15비밀숫자절대 안 보냄
8, 19재료 (상대가 비밀숫자로 계산해 보낸 값)이것만 교환
2최종 키각자 계산, 안 보냄

나 (브라우저)

6
보낼 재료 = 56 mod 23 = 8
받은 재료로 키 = 196 mod 23 = 2
노랑(공용) + 빨강(내 비밀)

은행 (서버)

15
보낼 재료 = 515 mod 23 = 19
받은 재료로 키 = 815 mod 23 = 2
노랑(공용) + 파랑(은행 비밀)

선 위에서 엿보는 사람이 본 것

키 교환은 엿보기를 막고, 서명은 끼어들기를 막습니다. 둘은 역할이 다르고, 둘 다 있어야 안전합니다.

왜 양쪽 키가 같은가

곱하는 순서만 다를 뿐 둘 다 5를 (내 비밀 × 은행 비밀)번 곱한 것입니다. 곱셈은 순서를 바꿔도 같고, 중간에 23으로 나눈 나머지를 취해도 이 성질은 유지됩니다.

재료 8을 보고 비밀숫자를 찾을 수 있나

5ⁿ mod 23을 n = 1부터 넣어 보면:

이 예시는 숫자가 작아서 대입하면 찾힙니다. 하지만 결과가 5, 2, 10, 4, 20…처럼 규칙 없이 튀어서 "크면 줄이고 작으면 늘리는" 지름길이 없습니다(이산 로그 문제). 실제 비밀숫자는 77자리 수준이라, 최선의 공격으로도 우주 나이의 수백 배가 걸립니다. 반대로 정방향 계산은 77자리여도 순식간입니다.

헷갈린 지점

✗"비밀 10 + 재료 5 = 키 15 같은 계산이면 된다"

덧셈은 거꾸로 계산이 쉬워서, 엿보는 사람이 재료로 비밀을 되찾거나 같은 키를 만들어 버립니다. 정방향은 쉽고 역방향은 사실상 불가능한 연산이 필요합니다.

✗"공개값 5와 23을 다 아는데 왜 못 푸나"

계산 규칙을 알아도 거꾸로 가는 지름길이 없습니다. 하나씩 대입하는 수밖에 없는데, 실제 크기에서는 대입할 개수가 상상을 넘습니다. 양자컴퓨터는 이 문제를 빠르게 풀 수 있어서, 대비용 양자내성암호(PQC)가 TLS에 섞여 들어가는 중입니다.

✗"내가 받는 건 은행의 비밀숫자다"

받는 것은 은행이 비밀숫자 15로 계산한 재료 19입니다. 15는 은행 밖으로 나오지 않습니다.

4 · 실험 2

nonce: 한 번만 쓰는 숫자

nonce는 "이번 한 번만 쓰고 버리는 값"입니다. 이 값을 계산에 섞으면, 엿들은 결과를 나중에 다시 보내는(재전송) 공격이 통하지 않습니다. TLS의 랜덤값, OTP의 현재 시각, 장비 로그인의 장비 난수가 모두 같은 역할입니다.

비밀숫자와 nonce는 역할이 반대

비밀숫자 (6)nonce
만드는 법무작위무작위 또는 순번
공개숨김그냥 보냄
목적키 만들기이번 대화를 유일하게
털리면키가 털림상관없음

nonce 혼자는 아무것도 증명 못 한다

서명이나 HMAC과 같이 쓰일 때 의미가 생깁니다.

  • 서명: 내용이 진짜이고 안 바뀌었다
  • nonce: 그게 지금 새로 만든 것이다

창구 직원이 "미리 써 온 서명 말고, 제가 방금 부른 숫자 7392를 적고 지금 서명하세요"라고 하는 것과 같습니다. 숫자가 남에게 들려도 상관없습니다. 매번 새로 나오기 때문에 미리 준비한 서명으로는 못 맞춥니다.

아래는 장비(카메라) 로그인을 흉내 낸 실험입니다. 비밀번호 원문은 한 번도 선 위로 나가지 않습니다.

나 (클라이언트)

H1 = SHA256( 아이디 : SHA256(비밀번호) )
H2 = SHA256( 장비 nonce : 내 nonce )
응답값 = SHA256( H1 : H2 )
내 nonce (내가 이번에 만든 무작위 값)

장비 (카메라)

이번 연결의 장비 nonce
nonce
장비도 저장된 비밀번호로 같은 계산을 해서 맞으면 통과시킵니다.

선 위에 흐른 것

왜 nonce가 둘이고, 응답값은 무엇인가요?

장비 nonce는 장비가 먼저 보내 줍니다(첫 줄). 장비가 정했으니 장비는 이미 알고 있어 내가 다시 보낼 필요가 없습니다. 이 값 덕분에 해커가 예전 로그인을 녹화해 다시 보내도 장비가 속지 않습니다.

내 nonce는 내가 만든 값이라 장비는 모릅니다. 그래서 같이 보내야 장비도 똑같이 계산할 수 있습니다. 결과가 장비 혼자 정한 값에만 달려 있지 않게 해서, 가짜 장비가 같은 nonce를 반복해 내놓고 내 응답을 모아 두는 수법도 막습니다.

응답값(digest)은 비밀번호와 두 nonce를 섞어 계산한 값입니다. 비밀번호를 아는 쪽만 같은 값을 만들 수 있고, 이 값에서 비밀번호를 되찾을 수는 없습니다. 두 nonce 중 하나만 바뀌어도 완전히 다른 값이 됩니다.

예시 비밀번호는 실제 값이 아닙니다. nonce가 매번 바뀌니 녹화해 둔 값은 다음 연결에서 통하지 않습니다.

헷갈린 지점

✗"nonce = 난수"

반만 맞습니다. 대부분 난수로 만들지만, 정의는 "무작위"가 아니라 "한 번만 쓴다"입니다. TLS 연결 뒤 데이터 덩어리의 nonce는 순번으로 만듭니다. 겹치지만 않으면 됩니다.

✗"nonce가 공개되면 위험하다"

공개해도 됩니다. nonce는 비밀이 아니라 "이번 한 번"을 표시하는 값입니다. 비밀은 비밀번호나 비밀숫자 쪽이 맡습니다.

5 · 비교

SSL과 TLS, 그리고 1.2와 1.3

SSL(Secure Sockets Layer)이 원조이고, 버전업하며 이름이 TLS(Transport Layer Security)로 바뀐 같은 계보입니다. "SSL 인증서"는 습관적인 이름일 뿐 실제로는 전부 TLS이고, 인증서 자체는 버전과 상관없습니다.

버전시기상태
SSL 2.0, 3.01990년대폐기 (보안 결함)
TLS 1.0, 1.11999, 2006폐기. 주요 브라우저가 2020년에 지원 중단
TLS 1.22008아직 많이 씀. 설정만 잘하면 안전
TLS 1.32018현재 표준 (이 페이지의 장면)

RSA 키 교환 (SSL ~ TLS 1.2)

내가 임시키를 만들어 은행 공개키로 잠가 보냄 → 은행이 개인키로 풂

선 위 잠긴 임시키

키 교환 (TLS 1.3)

재료만 교환하고 각자 계산. 비밀숫자는 끝나면 버림. 은행 키는 서명에만 씀

선 위 재료 8, 19

녹화해 둔 과거 통신을 나중에 못 푸는 성질을 전방 비밀성(Forward Secrecy)이라고 합니다. TLS 1.3이 RSA 키 교환을 없앤 이유입니다.

1.2는 왜 아직 쓰나: 뚫린 게 아니라 옛 옵션까지 허용

1.2에서 고를 수 있는 것상태
ECDHE 키 교환 (1.3과 같은 원리)안전
RSA 키 교환전방 비밀성 없음
AES-GCM, ChaCha20 암호화안전
CBC 등 옛 암호화 방식과거 공격 사례 다수

1.3은 위험한 옵션을 아예 지운 버전입니다. 1.2를 계속 쓰는 이유는 호환성입니다. 오래된 OS, 사내 시스템, 방화벽·프록시 같은 중간 장비가 1.3을 못 알아듣는 경우가 남아 있습니다.

서버 권장 설정

  • TLS 1.3 우선
  • TLS 1.2는 허용하되 ECDHE + AES-GCM 또는 ChaCha20 조합만
  • TLS 1.0, 1.1, SSL은 끄기

폐기되면 안 쓰나

최신 브라우저는 연결 자체를 거부합니다. 하지만 펌웨어 업데이트가 끊긴 오래된 카메라, NVR, 산업용 장비는 아직 1.0을 쓰기도 합니다. 오래된 장비 웹 화면이 최신 브라우저에서 안 열리는 이유가 대부분 이것이고, 그런 장비가 남아 있다면 그 자체가 보안 구멍입니다.

6 · 실험 3

로그인과 세션: 은행이 나를 확인하는 법

TLS로 안전한 통로가 생긴 뒤, 그 안에서 일어나는 일입니다. 핵심은 번호표와 서버 장부입니다.

  1. 로그인: 아이디·비밀번호를 TLS 통로 안으로 보냅니다. 은행은 비밀번호 원문이 아니라 해시값만 저장해 두고, 받은 비밀번호를 같은 방식으로 해시해 비교합니다. DB가 털려도 원문은 나오지 않습니다.
  2. 번호표 발급: 무작위 문자열(세션 ID)을 만들어 장부에 "이 번호표 = 김상필, 30분 뒤 만료"라고 적고, 브라우저에 쿠키로 줍니다.
  3. 이후 요청: 브라우저가 그 사이트에 요청할 때마다 번호표를 자동으로 붙입니다. 은행은 장부에서 찾아 누구인지 압니다. 매번 비밀번호를 다시 안 치는 이유입니다.
  4. 로그아웃: 장부에서 지웁니다. 번호표를 들고 있어도 무효입니다.

번호표 자체에는 아무 정보가 없습니다. 의미는 전부 서버 장부에 있습니다. 그래서 "서버가 기억하는 방식"이라고 부릅니다.

브라우저

내 쿠키

은행 서버의 장부

번호표누구만료
로그인을 눌러 시작하세요.

TLS가 있는데 번호표는 어디서 털리나: 통로 안이 아니라 양 끝

공격어떻게방어
XSS게시글 등에 심은 악성 스크립트가 내 브라우저에서 실행되어, 이미 풀린 쿠키를 읽어 감HttpOnly
HTTP 노출http:// 로 유도해 암호화 없는 요청에 쿠키가 실림Secure
CSRF훔치지 않고 악용. 해커 사이트가 내 브라우저로 은행에 요청을 보내면 쿠키가 자동으로 붙음SameSite, CSRF 토큰
악성코드PC 자체가 감염되어 저장소를 통째로 가져감짧은 세션 만료

TLS는 현금 수송차입니다. 운송 중에는 안전하지만, 집에 도둑이 들거나 누가 나인 척 심부름을 보내는 건 못 막습니다. 쿠키 옵션은 집 보안입니다.

헷갈린 지점

✗"TLS로 통로가 보호되니 번호표는 못 훔친다"

통로 안은 안전합니다. 털리는 곳은 통로 양 끝(브라우저 안, 기기 자체)과 통로가 없는 순간(http)입니다. 위 표가 그 목록입니다.

✗"로그아웃하면 브라우저 쿠키가 지워져서 안전하다"

안전해지는 진짜 이유는 서버 장부에서 지워지기 때문입니다. 해커가 미리 복사해 간 번호표도 장부에 없으니 무효가 됩니다. 위 실험에서 훔친 뒤 로그아웃하고 다시 해커 버튼을 눌러 보세요.

7 · 실험 4

번호표 자체가 신분증 (서명된 토큰, JWT)

세션은 번호표에 정보가 없고 서버 장부에 다 있었습니다. JWT는 반대로 필요한 정보를 토큰 안에 적고 서버가 서명해서 줍니다. 서버는 장부 없이 서명만 확인하고 내용을 믿습니다. TLS의 서명과 같은 원리입니다.

헤더 . 내용 . 서명   (점으로 나뉜 세 덩어리. 헤더는 서명 방식, 내용은 누구·권한·만료)

내용을 한 글자 고쳐 보세요. 예를 들어 viewer를 admin으로.

서버가 발급 때 만든 서명 (서버 비밀키로 계산)
서명
지금 내용으로 다시 계산한 서명
서명

세션 vs JWT

세션JWT
정보 위치서버 장부토큰 안
서버 확인장부 조회서명 검증
강제 로그아웃장부에서 지우면 즉시만료 전까지 못 막음
서버 여러 대장부 공유 필요서명 키만 있으면 됨
잘 맞는 곳웹 사이트 하나API, 모바일 앱, 여러 서비스

직원 계정을 지금 당장 막아야 한다면

장부가 없으니 "그 사람 토큰만" 골라 무효로 할 수 없습니다.

방법효과대가
서명 키 교체즉시 전원 차단모두 재로그인
짧은 만료 + 리프레시 폐기5~15분 뒤 차단그 사이엔 못 막음
차단 목록즉시 그 사람만매 요청 조회 = 장부 부활

판단 기준: 사이트 하나 + 브라우저 사용자이고, 권한 회수가 즉시 되어야 하는 관제 시스템이라면 세션이 구조적으로 맞습니다. "요즘은 JWT"라는 이유만으로 바꾸면 오히려 손해일 수 있습니다.

헷갈린 지점

✗"토큰 내용은 암호화되어 있다"

인코딩일 뿐이라 누구나 열어 볼 수 있습니다. 서명은 못 고치게 하는 것이지 못 보게 하는 것이 아닙니다. 비밀번호 같은 값은 절대 넣으면 안 됩니다.

✗"서명 키를 바꾸면 그 사람만 막힌다"

모든 토큰이 같은 키로 서명되었으니 전원의 토큰이 무효가 됩니다. 최후의 수단입니다.

✗"JWT는 장부가 전혀 필요 없다"

보통 수명이 짧은 액세스 토큰과 수명이 긴 리프레시 토큰을 함께 쓰는데, 리프레시 토큰은 서버가 목록을 관리해 폐기할 수 있게 합니다. 결국 일부는 장부를 다시 둡니다.

8 · 비교

OTP: 2단계 인증

비밀번호가 털려도 막으려고, "그 폰을 가지고 있는지"를 한 번 더 봅니다. 구글 OTP 같은 앱은 등록 때 QR로 나눠 가진 비밀값에 현재 시각(30초 단위)을 섞어 6자리를 만듭니다. 시각이 nonce 역할을 합니다. 아래는 표준 방식(TOTP)으로 실제 계산합니다.

폰 (OTP 앱)

비밀값 + 시각 칸 → HMAC → 6자리
------
TLS 확인 메시지OTP
비밀키 2등록 때 받은 비밀값
비밀 얻는 법매번 새로 키 교환으로 계산미리 한 번 나눠 가짐
섞는 재료 (nonce 역할)대화 내용현재 시각
확인 대상같은 키를 가졌나등록한 그 폰을 가졌나
역할통로 확인사용자 인증 (2단계)

공통 원리는 하나입니다. 비밀은 안 보내고, 비밀로 계산한 결과만 보냅니다. 차이는 비밀을 언제 얻느냐입니다.

9 · 적용

WVP 영상 관제에 대 보기

wvp.idisman.co.kr는 위의 방식들을 자리마다 나눠 씁니다. 사람의 로그인, 영상 서버 접속, 장비 연결이 각각 다른 방식입니다.

구간방식이 페이지의 어느 장
브라우저 ↔ WVPTLS (인증서 확인)2. TLS 1.3 한 바퀴
사이트 로그인Django 세션. sessionid 쿠키 = 번호표, django_session 테이블 = 장부, csrftoken = CSRF 방어6. 로그인과 세션
영상 서버 접속서명된 짧은 토큰. 짧게 만료시켜 "즉시 로그아웃이 안 되는" 약점을 줄임7. 서명된 토큰
WVP ↔ 장비DirectIP: nonce + 응답값 로그인 (아래 대응표)4. nonce

로그인 주소 /login/?next=%2F는 Django 기본 패턴으로, "로그인이 끝나면 원래 가려던 / 로 보내 달라"는 뜻입니다. 사람 계정은 즉시 차단이 중요해서 세션이 맞고, 영상 서버는 매 요청 장부를 조회하지 않고 빠르게 검증하는 게 유리해서 짧은 토큰이 맞습니다.

장비 연결(DirectIP) 대응표

순서실제로 오가는 것이 페이지의 어느 것
1TCP 접속 → 인사(hello)아직 인증 없음
2장비가 장비 정보 + nonce를 보냄실험 2의 장비 nonce
3(새 펌웨어) 같은 소켓을 TLS 1.3으로 감쌈. 인증서 확인은 하지 않음장면에서 3번(인증서·서명② 확인)이 빠진 상태: 엿보기는 막고 끼어들기는 못 막음
4로그인: 비밀번호 대신 계산값을 보냄실험 2 그대로
5장비가 성공/실패를 답함장비의 대조
6라이브·재생. 번호표 없이 연결 자체가 세션세션과 비슷하지만, 끊기면 처음부터

점검 목록

  • 로그인 후 개발자도구 → Application → Cookies에서 sessionid, csrftoken 확인
  • sessionid에 HttpOnly, Secure, SameSite가 켜져 있는지
  • CF_Authorization 쿠키가 있으면 앞단에 Cloudflare Access도 걸린 것
  • DirectIP 3단계에서 인증서 확인이 없으므로, 같은 네트워크에 끼어든 공격자는 막지 못함. 장비망 분리가 중요
  • 구형 펌웨어 장비가 TLS 1.0이나 암호화 없는 연결을 쓰는지
10 · 확장

기기 인증: 카메라와 NVR도 같은 뼈대

대상이 사람에서 기기로 바뀌었을 뿐, "처음 증명"과 "이후 유지"라는 구조는 같습니다.

웹 로그인카메라 ↔ NVR
누가사람 → 서버기기 → 기기
처음 증명ID/PW 입력장비 계정, 등록(페어링)
이후 유지세션 쿠키, 토큰연결 유지 또는 매 요청 재인증
대표 방식세션, JWT, OAuthHTTP Digest(RTSP·ONVIF), nonce 응답값, mTLS
대표 약점비밀번호 유출, 번호표 탈취기본 비밀번호, 인증서 확인 없는 통로

mTLS는 브라우저처럼 한쪽만 확인하는 게 아니라 양쪽이 서로 인증서와 서명②를 주고받아 확인하는 방식입니다. 사람보다 기기 간 통신에 주로 씁니다. DirectIP 3단계에 이것이 들어가면 끼어들기까지 막을 수 있습니다.

11 · 용어

용어 모음

인증 (AuthN)
너 누구야. 로그인.
인가 (AuthZ)
너 뭐 할 수 있어. 권한.
TLS
Transport Layer Security. 서버 확인 + 암호화 통로. SSL의 후속.
CA
인증서 발급 기관. 공개키가 브라우저·OS에 내장.
인증서
공개키 + 도메인 + 유효기간 + CA 서명.
서명
개인키로 만들고 공개키로 확인. 못 고치게 할 뿐 숨기지는 않음.
키 교환 (ECDHE)
재료만 교환하고 각자 같은 키를 계산. TLS 1.3의 방식.
전방 비밀성
나중에 서버 개인키가 털려도 과거 통신은 못 푸는 성질.
해시
한 방향 계산. 결과에서 입력을 못 되찾음.
HMAC
비밀값을 섞은 해시. 같은 비밀을 가진 쪽만 같은 결과.
nonce
한 번만 쓰는 값. 재전송 공격 방지. 공개해도 됨.
세션
번호표(쿠키) + 서버 장부. 즉시 무효화 가능.
JWT
내용 + 서명이 담긴 토큰. 장부 없이 검증, 즉시 무효화는 어려움.
XSS · CSRF
스크립트로 쿠키 탈취 · 쿠키 자동 첨부를 악용한 요청 위조.
OTP (TOTP)
미리 나눈 비밀 + 현재 시각 → 6자리. 2단계 인증.
mTLS
양쪽이 서로 인증서로 확인하는 TLS. 기기 간 통신.

다음에 이어 볼 것

  • OAuth 2.0 / OIDC: "구글로 로그인"처럼 인증을 남에게 맡기는 방식
  • 비밀번호 해싱 심화: 왜 일부러 느린 해시를 쓰는지
  • mTLS와 장비 인증서 운영