사전 다중 인증
개념

다중 인증

gabury1고친 사람 github-actions[bot]

다중 인증은 로그인할 때 비밀번호 말고 다른 종류의 증거를 하나 더 받아 본인인지 확인하는 방법입니다. 비밀번호만 훔친 사람은 계정에 들어가지 못합니다. 비밀번호를 넣은 뒤 휴대폰 앱에 뜬 숫자를 한 번 더 넣는 것이 흔한 모습입니다.

쉽고 빠른 이해

로그인 때 성격이 다른 증거를 둘 이상 요구하는 방법입니다. 비밀번호를 맞힌 뒤 휴대폰 인증 앱의 여섯 자리 숫자까지 넣어야 들어가는 식입니다.

비밀번호는 한 번 새면 누구나 씁니다. 가짜 로그인 화면에 적은 비밀번호도, 다른 사이트에서 털린 비밀번호도 공격자 손에 들어갑니다. 멀리 있는 공격자가 휴대폰까지 함께 훔치기는 어렵습니다.

어떻게 도나:

  1. 서버가 비밀번호를 확인합니다
  2. 맞으면 두 번째 증거를 요구합니다. 인증 앱의 숫자, 로그인 확인용 작은 장치인 보안 키, 지문 같은 것입니다
  3. 둘 다 맞아야 로그인이 끝납니다

대가도 있습니다. 로그인이 한 단계 길어집니다. 휴대폰을 잃으면 계정을 되찾는 절차가 따로 필요합니다.

그래서 뚫리면 피해가 큰 계정부터 겁니다. 관리자 계정, 돈이 움직이는 계정, 클라우드 설정을 바꾸는 계정이 그렇습니다.

상세

은행 창구에서 예금을 찾을 때를 떠올려 봅니다. 통장을 내고 비밀번호도 누릅니다. 길에서 통장을 주운 사람은 비밀번호를 모릅니다. 어깨너머로 비밀번호를 엿본 사람에게는 통장이 없습니다.

인증은 상대가 자기가 말하는 그 사람이 맞는지 확인하는 일입니다. 다중 인증은 이 확인에 서로 다른 종류의 증거를 둘 이상 쓰는 인증입니다. 영어로는 Multi-Factor Authentication 입니다. 줄여서 MFA 라고 부릅니다. 증거가 딱 둘이면 2FA(Two-Factor Authentication, 이중 인증)라고도 합니다.

예를 들어 사내 관리자 화면에 들어갈 때 비밀번호를 넣고, 이어서 휴대폰의 인증 앱이 보여 주는 숫자를 넣습니다. 비밀번호는 머릿속에 있습니다. 인증 앱은 손에 든 휴대폰에 있습니다. 두 증거가 사는 곳이 다릅니다.

비밀번호 하나로 모자란 까닭

비밀번호는 글자 몇 개라 옮겨 적기 쉽습니다. 한 번 새어 나가면 누가 입력하든 서버는 구별하지 못합니다.

새는 길 하나는 사용자가 직접 넘겨주는 것입니다. 진짜처럼 꾸민 가짜 로그인 화면에 사용자가 비밀번호를 적어 넣습니다. 이런 속임수를 피싱이라고 합니다.

다른 길은 비밀번호를 여러 사이트에 같이 쓰는 습관입니다. 한 사이트에서 털린 아이디와 비밀번호 목록을 공격자가 다른 사이트에 차례로 넣어 봅니다. 이 공격을 크리덴셜 스터핑이라고 부릅니다.

비밀번호 해싱은 서버에 저장된 비밀번호가 털려도 원래 글자를 알아내기 어렵게 합니다. 그러나 사용자가 입력하는 순간 빼앗긴 비밀번호는 막지 못합니다. 다중 인증을 걸면 비밀번호가 새도 두 번째 증거가 없으면 계정이 넘어가지 않습니다.

인증 요소 세 갈래

증거의 종류를 인증 요소라고 부릅니다. 요소는 흔히 셋으로 나눕니다.

요소 무엇인가 예
아는 것 머릿속에 든 비밀 비밀번호 · PIN(Personal Identification Number, 개인 식별 번호)
가진 것 손에 쥔 물건 휴대폰 · 보안 키 · 스마트카드
그 자신인 것 몸의 특징 지문 · 얼굴

셋째인 몸의 특징을 쓰는 방식은 생체 인증이라고 따로 부릅니다. 보안 키는 로그인 확인용으로 만든 작은 장치입니다.

셋을 가르는 까닭은 훔치는 방법이 서로 다르기 때문입니다. 아는 것은 피싱이나 유출로 멀리서도 빼앗깁니다. 가진 것은 그 물건을 손에 넣어야 합니다. 그 자신인 것은 사람 몸에 붙어 있습니다.

요소가 다르면 공격자는 서로 다른 공격을 두 번 성공시켜야 합니다. 멀리 있는 공격자가 비밀번호를 알아냈어도 남의 휴대폰까지 손에 넣기는 어렵습니다. 다중 인증이 막는 힘은 이렇게 공격 방법이 겹치지 않는 데서 나옵니다.

단계가 둘인 것과 요소가 둘인 것

비밀번호를 넣고 다음 화면에서 「처음 다닌 학교」 같은 비밀 질문에 답한다고 해 봅니다. 확인은 두 번이지만 둘 다 아는 것입니다. 가짜 로그인 화면 하나가 둘을 한꺼번에 받아 갈 수 있습니다.

그래서 이런 로그인은 다중 인증으로 치지 않습니다. 확인을 몇 번 하는지가 아니라 요소가 몇 종류인지를 셉니다.

2단계 인증이라는 말도 자주 씁니다. 이 말은 흔히 다중 인증과 같은 뜻으로 쓰입니다. 그런데 이름이 말하는 것은 단계가 둘이라는 것뿐입니다. 두 번째 단계가 다른 요소를 쓰는지는 따로 봐야 합니다.

로그인 한 번이 지나가는 순서

인증 앱을 예로 로그인이 어떻게 흘러가는지 봅니다. 인증 앱은 휴대폰에 설치해 짧은 숫자를 만들어 주는 앱입니다. 등록할 때 서버와 앱이 비밀 값 하나를 나눠 가집니다. 그 뒤로는 둘이 이 비밀 값과 지금 시각으로 따로 계산해도 같은 숫자가 나옵니다.

서버는 비밀번호가 맞아도 바로 로그인시키지 않습니다. 비밀번호만 통과하고 두 번째 요소를 기다리는 상태를 따로 둡니다.

sequenceDiagram
    participant 사용자
    participant 앱 as 인증 앱
    participant 서버
    사용자->>서버: 아이디와 비밀번호
    Note over 서버: 맞으면 두 번째 요소를 기다리는 상태로 둔다
    서버-->>사용자: 인증 앱의 숫자를 달라
    사용자->>앱: 앱을 연다
    앱-->>사용자: 지금 시각의 숫자
    사용자->>서버: 그 숫자
    Note over 서버: 같은 비밀 값으로 계산해 맞춰 본다
    서버-->>사용자: 로그인 완료

그림에서 사용자는 서버와 인증 앱 사이를 한 번 오갑니다. 서버는 앱과 직접 통신하지 않습니다. 두 번째 요소까지 맞아야 기다리는 상태가 로그인 완료로 넘어갑니다.

두 번째 요소를 받는 방식

두 번째 요소는 대개 가진 것입니다. 무엇을 가졌는지 확인하는 방식이 여럿이라 아래에 모읍니다.

보안 키는 앞에서 본 로그인 확인용 작은 장치입니다. 패스키는 같은 일을 따로 장치 없이 휴대폰이나 노트북이 맡는 방식입니다.

방식 어떻게 받나 가진 것으로 치는 것
문자 메시지 코드 서버가 문자로 숫자를 보내고 사용자가 옮겨 적습니다 그 전화번호
인증 앱 코드 앱이 비밀 값과 시각으로 숫자를 만듭니다 비밀 값이 든 휴대폰
푸시 승인 서버가 앱에 알림을 보내고 사용자가 승인을 누릅니다 등록된 휴대폰
보안 키 · 패스키 기기 안에만 있는 키로 서버가 보낸 값에 답합니다 그 키가 든 기기

문자 메시지 방식은 SMS(Short Message Service)라는 휴대폰 문자 서비스를 씁니다. 따로 앱을 깔 필요가 없습니다. 대신 전화번호를 가진 것으로 치기 때문에 번호가 넘어가면 요소도 넘어갑니다.

인증 앱이 만드는 숫자는 일회용 비밀번호의 한 종류입니다. 일회용 비밀번호는 한 번 쓰고 버리는 짧은 비밀번호입니다. 엿본 사람이 나중에 다시 써도 통하지 않습니다.

일회용 비밀번호 가운데 시각을 재료로 쓰는 방식을 TOTP(Time-based One-Time Password, 시간 기반 일회용 비밀번호)라고 부릅니다.

TOTP 의 계산은 이렇습니다. 앱과 서버가 나눠 가진 비밀 값과 현재 시각을 해시 함수에 함께 넣습니다. 해시 함수는 입력을 섞어 원래 입력으로 되돌릴 수 없는 값을 만드는 함수입니다. 그 결과를 여섯 자리쯤의 짧은 숫자로 줄입니다. 시각은 몇십 초 단위로 끊어 넣으므로, 그 시간 안에서는 앱과 서버가 같은 숫자를 얻습니다.

비밀 값은 등록할 때 한 번만 건넵니다. 서버가 화면에 QR(Quick Response) 코드를 띄우면 앱이 그것을 찍어 비밀 값을 읽습니다. 그 뒤로 앱은 네트워크 없이도 숫자를 만듭니다.

푸시 승인은 숫자를 옮겨 적는 수고를 덜어 줍니다. 서버가 등록된 휴대폰으로 푸시 알림을 보냅니다. 사용자가 알림에서 승인을 누르면 앱이 그 결과를 서버에 돌려줍니다.

보안 키와 패스키는 공개 키 암호를 씁니다. 공개 키 암호는 짝을 이루는 키 두 개를 씁니다. 하나는 남에게 줘도 되는 공개 키입니다. 다른 하나는 주인만 갖는 개인 키입니다.

등록할 때 기기가 이 키 한 쌍을 만듭니다. 공개 키만 서버에 줍니다. 개인 키는 기기 밖으로 나가지 않습니다.

전자 서명은 개인 키로 만드는 표시입니다. 개인 키를 가진 쪽만 서명을 만들 수 있습니다. 짝이 되는 공개 키가 있으면 누구나 그 서명을 확인할 수 있습니다.

로그인할 때는 서버가 매번 다른 임의의 값을 보냅니다. 기기가 개인 키로 그 값에 서명합니다. 서버는 저장해 둔 공개 키로 그 서명을 확인합니다. 서명이 맞으면 그 개인 키가 든 기기가 지금 사용자 손에 있다는 뜻입니다.

이 방식을 브라우저에서 쓰게 하는 규격이 WebAuthn(Web Authentication)입니다.

두 번째 요소를 뚫는 공격

두 번째 요소가 있어도 뚫는 방법이 있습니다. 방식마다 약한 곳이 다릅니다.

휴대폰의 유심, 곧 SIM(Subscriber Identity Module) 카드는 통신사가 새로 발급해 줄 수 있습니다. 공격자가 통신사를 속여 피해자의 번호를 자기 SIM 카드로 옮기는 공격을 SIM 스와핑이라고 합니다. 그 뒤로 인증 문자는 공격자의 휴대폰으로 갑니다.

숫자를 옮겨 적는 방식은 문자든 앱이든 피싱에 뚫립니다. 가짜 로그인 화면이 비밀번호와 숫자를 받자마자 진짜 사이트에 대신 넣습니다. 숫자가 살아 있는 몇십 초 안에 끝내면 됩니다. 사용자와 진짜 사이트 사이에 끼어드는 이런 공격을 중간자 공격이라고 부릅니다.

푸시 승인은 사용자의 피로를 노립니다. 비밀번호를 손에 넣은 공격자가 로그인을 계속 시도하면 승인 알림이 끝없이 뜹니다. 지친 사용자가 한 번 눌러 주면 공격자가 들어옵니다. 이를 MFA 피로 공격이라고 합니다.

보안 키와 패스키는 이 피싱에 버팁니다. 개인 키는 등록한 사이트 주소, 곧 오리진에 묶여 있습니다. 가짜 사이트에서는 브라우저가 진짜 사이트용 키를 꺼내 쓰지 않습니다. 사용자가 속아도 기기는 속지 않습니다.

서버 구현에서 빠지기 쉬운 검사

다중 인증을 붙이는 백엔드 개발자가 가장 먼저 챙길 것은 두 번째 요소를 기다리는 상태입니다. 아래 그림은 한 세션이 거치는 상태를 보입니다.

stateDiagram-v2
    state "로그아웃" as out
    state "두 번째 요소 대기" as half
    state "로그인 완료" as done
    [*] --> out
    out --> half : 비밀번호가 맞음
    half --> done : 두 번째 요소가 맞음
    half --> out : 시간 초과 또는 실패 반복

두 번째 요소를 기다리는 세션은 두 번째 요소를 확인하는 요청 하나만 부를 수 있어야 합니다. 이 검사를 빠뜨리면 비밀번호만으로 다른 요청이 통과합니다. 두 번째 요소를 붙여 놓고도 없는 것과 같아집니다.

기다리는 상태는 오래 두지 않습니다. 시간이 지나거나 틀린 입력이 쌓이면 로그아웃으로 되돌립니다.

그 밖에 자주 빠지는 검사를 모으면 이렇습니다.

검사 빠뜨리면
숫자 입력 횟수 제한 여섯 자리 숫자는 백만 가지뿐이라 계속 넣어 보면 맞힙니다
한 번 쓴 숫자는 다시 안 받기 엿본 숫자를 살아 있는 시간 안에 한 번 더 쓸 수 있습니다
인증 앱 비밀 값을 암호화해 저장 데이터베이스가 털리면 공격자도 같은 숫자를 만듭니다

첫째 줄은 모든 경우를 차례로 넣어 보는 무차별 대입 공격을 막습니다. 둘째 줄은 가로챈 값을 다시 보내는 재전송 공격을 막습니다.

셋째 줄은 비밀번호와 다르게 다뤄야 합니다. 비밀번호는 해시만 저장하고 비교합니다. 인증 앱의 비밀 값은 서버가 매번 원래 값으로 숫자를 계산해야 하므로 해시로 둘 수 없습니다. 그래서 되돌릴 수 있는 암호화로 저장합니다. 암호화 키는 그 데이터베이스와 따로 둡니다.

휴대폰을 잃었을 때의 복구

휴대폰을 잃으면 두 번째 요소를 낼 수 없습니다. 그래서 등록할 때 한 번씩만 쓸 수 있는 복구 코드 여러 개를 미리 줍니다. 사용자는 이를 휴대폰과 떨어진 곳에 보관합니다.

복구 코드는 비밀번호처럼 해시로 저장합니다. 서버는 원래 값을 다시 계산할 일이 없습니다. 입력된 값과 맞춰 보기만 하면 됩니다.

복구 경로가 약하면 다중 인증 전체가 그만큼 약해집니다. 이메일 링크 하나로 두 번째 요소를 끌 수 있다면 공격자는 로그인 대신 그 길로 들어옵니다. 복구에도 로그인과 같은 무게의 확인을 겁니다.

대가와 쓰는 때

로그인에 단계가 하나 늘어납니다. 사용자는 로그인할 때마다 휴대폰을 꺼내야 합니다. 휴대폰을 잃어버리면 복구 절차를 밟아야 합니다. 운영하는 쪽에는 복구 문의를 처리하는 일이 생깁니다.

그래서 매번 묻지 않는 방식을 섞습니다. 한 번 확인한 기기는 한동안 기억해 둡니다. 새 기기나 낯선 위치에서 들어올 때만 다시 묻습니다. 접속의 위험도를 보고 물을지를 정하는 방식을 위험 기반 인증이라고 합니다.

먼저 거는 곳은 뚫렸을 때 피해가 큰 계정입니다. 관리자 계정, 돈이 움직이는 계정, 서버와 클라우드 설정을 바꿀 수 있는 계정이 그렇습니다. 비밀번호 변경이나 출금처럼 민감한 동작 직전에 두 번째 요소를 한 번 더 묻기도 합니다.

관련 항목

다중 인증을 이루는 인증 요소

인증 요소 · 비밀번호 · PIN · 보안 키 · 스마트카드 · 생체 인증

두 번째 요소를 만드는 방식

일회용 비밀번호 · TOTP · HOTP · 푸시 알림 · 패스키 · WebAuthn · FIDO2

다중 인증이 막으려는 공격

피싱 · 크리덴셜 스터핑 · 계정 탈취 · 비밀번호 스프레이 · 무차별 대입 공격

다중 인증을 뚫는 공격

SIM 스와핑 · 중간자 공격 · MFA 피로 공격 · 재전송 공격 · 세션 하이재킹

다중 인증을 받치는 암호 기술

공개 키 암호 · 전자 서명 · 해시 함수 · HMAC · 암호화 · 비밀번호 해싱

다중 인증과 함께 로그인을 이루는 기술

인증 · 세션 · 싱글 사인온 · OpenID Connect · 위험 기반 인증 · 복구 코드 · 비밀번호 재설정 · 오리진

다중 인증과 헷갈리는 이웃

2단계 인증 · 비밀번호 없는 인증 · 인증과 인가 · 인가

다른 이름: MFA · multi-factor authentication · 다요소 인증 · 2FA · two-factor authentication · 이중 인증