SCRAM Authentication

임채령·2026년 2월 1일

Kafka에서 자주 쓰는 SCRAM 인증이란?

Kafka 보안 설정을 보다 보면 가장 자주 마주치는 인증 방식이 있다.
바로 SASL/SCRAM 이다.

처음 보면 용어도 어렵고,
“비밀번호를 안 보낸다는데 그럼 어떻게 인증을 하지?”라는 의문이 든다.

이 글에서는

  1. Kafka에서 SCRAM이 무엇인지 간단히 소개하고
  2. 실제 인증 흐름이 어떻게 동작하는지
  3. 왜 Kafka 같은 서버 간 통신에서 SCRAM이 많이 쓰이는지

흐름 중심으로 정리해본다.

SASL/SCRAM 이란?

SASL (Simple Authentication and Security Layer)

  • 인증을 위한 프레임워크
  • 실제 인증 방식은 플러그인처럼 붙는다

SCRAM (Salted Challenge Response Authentication Mechanism)

  • 비밀번호 기반 인증 메커니즘
  • 핵심 특징
    • 비밀번호를 네트워크로 보내지 않음
    • Salt + 반복 해시
    • Challenge–Response 방식

즉,

SASL = 인증 틀
SCRAM = 그 안에서 동작하는 실제 인증 방식

Kafka에서는 보통 다음을 사용한다.

  • SCRAM-SHA-256
  • SCRAM-SHA-512

2. Kafka에서 SCRAM이 자주 쓰이는 이유

:contentReference[oaicite:0]{index=0} 는
사람이 로그인하는 시스템이 아니다.

Kafka 환경을 보면 보통 이런 구조다.


Producer  →  Broker  ←  Consumer
↑           ↑
Connect     Stream App

특징은 다음과 같다.

  • 수많은 프로세스가 자동으로 접속
  • 로그인 UI 없음
  • 항상 켜져 있음
  • 내부 통신 비중이 큼

Kafka가 인증 방식에 요구하는 조건은 대략 이렇다.

  • 자동 인증 가능
  • 비밀번호 노출 위험 최소화
  • 외부 인증 서버 없이 동작
  • 성능 예측 가능

이 조건에 가장 잘 맞는 방식이 SCRAM이다.

3. SCRAM에서 말하는 Client / Server

SCRAM에서의 Client / Server는 역할 개념이다.

  • Client
    • 인증을 요청하는 쪽
    • 비밀번호를 알고 있음
  • Server
    • 인증을 검증하는 쪽
    • 비밀번호 원문은 없음

Kafka 기준으로 보면

  • Client → Kafka Producer / Consumer
  • Server → Kafka Broker

이 정도가 되겠다.

4. SCRAM 인증 흐름 (핵심)

아래는 Kafka Client가 Broker에 처음 연결할 때 일어나는 인증 흐름이다.

0단계: 사전 상태

서버(Kafka Broker)

사용자 생성 시점에 이미 다음 정보를 저장하고 있다.

  • salt
  • iterationCount
  • StoredKey
  • ServerKey

비밀번호 원문은 저장하지 않는다.

클라이언트(Kafka Client)

  • 설정 파일에 username / password를 가지고 있음

1단계: 인증 시작

Client → Server


username
clientNonce
  • 비밀번호는 보내지 않는다
  • “이 사용자로 인증하고 싶다”는 신호

2단계: 서버의 Challenge

Server → Client


salt
iterationCount
serverNonce (clientNonce 포함)

의미는 이렇다.

“이 salt와 반복 횟수로 계산해서
네가 진짜인지 증명해봐”

3단계: 클라이언트 내부 계산

이 단계는 네트워크로 전송되지 않는다.

클라이언트는 본인이 가진 비밀번호로 다음을 수행한다.

  1. password + salt
  2. iterationCount 만큼 반복 해시
  3. ClientKey 생성
  4. StoredKey 생성
  5. 인증용 메시지(AuthMessage) 구성
  6. ClientProof 생성

비밀번호를 알고 있는 쪽만 만들 수 있는 값이 생성된다.

4단계: 증명 제출

Client → Server


ClientProof

이 값은

  • 비밀번호 자체가 아니고
  • 이번 인증 세션에서만 유효한 증명값이다

5단계: 서버 검증 (핵심 로직)

서버는 클라이언트가 보낸 ClientProof를 그대로 믿지 않는다.
이미 서버는 검증에 필요한 기준값을 모두 가지고 있기 때문이다.

서버가 인증 시점에 가지고 있는 정보는 다음 세 가지다.

  • StoredKey
    • 사용자 생성 시점에 DB에 저장된 값
    • 비밀번호로부터 파생된 검증 기준값
  • AuthMessage
    • 클라이언트와 서버가 동일하게 알고 있는 인증용 메시지
  • ClientProof
    • 방금 클라이언트가 제출한 증명값

서버는 이 값들을 이용해 다음 과정을 수행한다.

1) ClientKey 복원

SCRAM에서 클라이언트는 ClientKey 자체를 보내지 않는다.
대신 ClientProof라는 값을 보낸다.

서버는 다음 연산을 통해 ClientKey를 역으로 복원한다.

ClientKey = ClientProof XOR hash(StoredKey + AuthMessage)

이 연산이 가능한 이유는 다음과 같다.

  • 서버는 StoredKey를 이미 DB에 저장하고 있고
  • AuthMessage 역시 서버와 클라이언트가 동일하게 알고 있기 때문이다

즉, 비밀번호를 몰라도 ClientKey를 복원할 수 있는 조건이 이미 갖춰져 있다.

2) StoredKey 검증

서버는 복원한 ClientKey를 다시 해시한다.

hash(ClientKey)

그리고 그 결과를 DB에 저장된 StoredKey와 비교한다.

hash(ClientKey) == StoredKey ?

3) 검증 결과 판단

  • 같으면
    → 이 ClientProof올바른 비밀번호로부터 생성되었다
    → 즉, 비밀번호를 알고 있는 클라이언트다
  • 다르면
    → 잘못된 비밀번호이거나 위조된 요청이다
    → 인증 실패

이 과정에서 서버는 비밀번호 원문을 한 번도 사용하지 않는다.
오직 이미 저장된 검증용 값(StoredKey)과
클라이언트가 제출한 증명값(ClientProof)만을 이용해 판단한다.

핵심 정리

  • 클라이언트는 비밀번호를 제출하지 않는다
  • 서버는 비밀번호를 알 필요가 없다
  • 서버는

    “이 증명값이 내가 알고 있는 StoredKey로부터 나올 수 있는 값인가?”
    만 확인한다

6단계: 서버도 자기 자신을 증명

Server → Client


ServerSignature

클라이언트는 이를 검증해

  • 가짜 서버(MITM)가 아님을 확인한다

7단계: 인증 완료

  • 클라이언트 ↔ 서버 상호 신뢰 성립
  • Kafka 연결 유지

5. 이 흐름의 핵심 포인트

  • 비밀번호는 단 한 번도 네트워크로 전송되지 않는다
  • 인증은

요청 → 도전 → 증명 → 검증

구조다

  • ClientProof는 재사용할 수 없다 (nonce 포함)
  • 서버 DB가 털려도 비밀번호는 알 수 없다

6. 왜 실사용자 로그인에는 잘 안 쓰일까?

SCRAM은 다음 전제를 가진다.

“클라이언트가 비밀번호를 직접 알고 있다”

이 전제는

  • 브라우저 로그인
  • 모바일 앱 로그인
  • SSO
  • 토큰 기반 인증

과는 잘 맞지 않는다.

SCRAM은

  • 세션 관리 불가능
  • 토큰 없음
  • 권한 전달 불가능

그래서 사람 로그인에는 OAuth/OIDC,
서버 간 인증에는 SCRAM이 주로 쓰인다.

7. 한 줄 요약

Kafka에서 SCRAM은
사람이 로그인하는 인증이 아니라
프로세스가 프로세스를 신뢰하기 위한 인증 방식이다.

Kafka, DB, 내부 메시징 시스템에서
SCRAM이 오래 살아남는 이유도 여기에 있다.

0개의 댓글