패스키는 왜 안전한가 ── 그림으로 이해하는 '비밀을 보내지 않는 인증'의 구조

· · 패스키, WebAuthn, FIDO2, 보안, 인증, 피싱 대책, 정보 시스템

「또 대형 서비스에서 비밀번호가 유출됐다」는 뉴스에 이제 아무도 놀라지 않게 되었습니다. 피싱 훈련을 매년 실시해도 걸려드는 사람이 0이 되지는 않습니다. 「비밀번호는 재사용하지 마라, 길게 만들어라, 정기 변경은…이제 안 해도 된다」──말하는 내용도 이랬다저랬다 해 왔습니다.

최근 몇 년 사이 급속히 확산된 패스키(passkey)는 이런 상황에 대한 답으로, Apple・Google・마이크로소프트 3사가 함께 추진하고 있는 인증 방식입니다.1 「지문이나 얼굴로 로그인할 수 있어 편리하다」는 식으로 소개되는 경우가 많지만, 본질은 거기에 있지 않습니다. 패스키의 진짜 가치는 안전성의 근거를 ‘인간의 주의력’에서 ‘프로토콜의 구조’로 옮겼다는 데 있습니다.

  • 비밀번호가 유출되는 건 이용자의 부주의 때문이니 교육하자 → 인간은 반드시 실수한다
  • 가짜 사이트를 알아볼 수 있도록 훈련하자 → 알아볼 수 없는 가짜 사이트를 만들 수 있다
  • 패스키라면 → 애초에 보낼 비밀이 없고, 가짜 사이트에서는 서명이 성립하지 않는다

이 글에서는 패스키가 왜 안전한지를, 비밀번호의 무엇이 무너져 있는지에서 출발해 그림으로 짚어봅니다. 그런 다음 「동기화되는 패스키는 정말 안전한가」「약점은 없는가」라는 당연한 의문에 정면으로 답하고, 마지막으로 웹 앱이나 Windows 환경에 도입할 때의 실무 요점을 정리합니다.

1. 먼저 결론

패스키가 안전한 이유는 다음 3가지로 집약됩니다.

  1. 서버에 비밀이 존재하지 않는다. 서버가 저장하는 것은 공개키뿐이며, 이는 유출되어도 악용할 수 없는 정보입니다. 데이터베이스가 통째로 유출되더라도 공격자가 가져갈 수 있는 「위장의 재료」가 없습니다.2
  2. 비밀이 네트워크를 흐르지 않는다. 로그인 시 전송되는 것은 그 자리에서만 유효한 난수(챌린지)에 대한 서명뿐입니다. 비밀키는 디바이스의 인증기에서 전혀 나오지 않으므로, 경로의 어디를 도청・중계해도 비밀을 손에 넣을 수 없습니다.2
  3. 가짜 사이트에서는 서명이 성립하지 않는다. 패스키는 사이트의 도메인에 연결되어 있으며, 브라우저가 도메인 대조를 강제합니다. 이용자가 가짜 사이트에 속더라도 진짜 사이트용 패스키는 애초에 후보로 나오지 않으며, 설령 서명을 중계하더라도 검증에서 탈락합니다.3

이 3가지는 독립된 방편이 아니라, ‘비밀을 공유하여 보내는’ 인증에서 ‘비밀을 갖고 있음을 서명으로 증명하는’ 인증으로의 전환이라는 하나의 설계 변경에서 모두 도출되는 결과입니다. 순서대로 살펴보겠습니다.

용어의 관계 ── 패스키・WebAuthn・FIDO2・CTAP

이 분야는 용어가 많은 데다 글마다 가리키는 범위가 다르므로, 먼저 관계만 짚어 두겠습니다. 패스키는 새로운 프로토콜이 아니라 기존 규격의 조합에 붙은 ‘이름’입니다.21

용어 정식 명칭 무엇을 가리키는가
WebAuthn Web Authentication API(W3C 권고) 브라우저와 웹사이트 사이의 규격. navigator.credentials 로 키 쌍 생성과 서명을 요청하는 API
CTAP Client to Authenticator Protocol(FIDO 얼라이언스) 브라우저와 외장 인증기 사이의 규격. USB・NFC・Bluetooth를 통해 보안 키나 스마트폰과 통신하는 부분
FIDO2 위 두 가지를 합친 프레임워크의 총칭. FIDO2 = WebAuthn + CTAP
패스키(passkey) FIDO2 자격 증명 중 비밀번호 대신 단독으로 로그인할 수 있는 것(검색 가능 자격 증명, discoverable credential)의 명칭

표1: 패스키는 FIDO2라는 토대 위의 명칭이며, 규격명이 아니다

즉 「패스키에 대응한다」는 것은 구현의 언어로 바꾸면 「WebAuthn을 구현한다」는 뜻입니다. CTAP은 외장 인증기를 사용할 때 브라우저와 OS가 알아서 처리해 주는 계층이므로, 웹 앱을 만드는 쪽이 직접 다룰 일은 없습니다.

2. 비밀번호 인증은 무엇이 무너져 있는가

패스키의 안전성을 이해하는 지름길은 비밀번호의 약점을 ‘위치’로 파악하는 것입니다. 비밀번호 인증에서는 비밀 그 자체가 인증할 때마다 전 구간을 이동합니다.

서버브라우저이용자서버브라우저이용자비밀(비밀번호)을 머릿속에 갖고 있음【약점①】추측 가능・재사용됨【약점②】가짜 사이트에도 똑같이입력할 수 있음(겉모습으로 구별 불가)【약점③】비밀이 경로를 흐름TLS로 보호되지만 종단에서는 평문으로 돌아옴【약점④】전체 이용자의 비밀(의 해시)이 집적유출되면 오프라인 무차별 대입의 표적이 됨비밀번호 입력비밀번호 자체를 전송저장된 해시와 대조

그림1: 비밀번호 인증에서는 비밀 그 자체가 전 구간에 존재한다

공격자 입장에서 보면 이는 표적이 많아 공격하기 쉬운 구조입니다.

  • 약점①(이용자): 외울 수 있는 정도의 강도밖에 없고, 여러 사이트에서 재사용됩니다. 한 곳의 유출이 전체 계정으로 파급됩니다(비밀번호 목록형 공격, credential stuffing).
  • 약점②(입력의 순간): 진짜와 구별할 수 없는 가짜 사이트를 준비하면, 이용자는 스스로 비밀을 내어줍니다(피싱).
  • 약점③(경로): TLS가 있어 경로 자체의 도청은 어렵지만, 「정상적인 모습을 한 중계 지점」이 끼어들면 의미가 없습니다(후술할 AiTM).
  • 약점④(서버): 해시화하여 저장하고 있어도 데이터베이스가 유출되면 오프라인으로 무차별 대입을 당할 수 있습니다. 약한 비밀번호부터 순서대로 뚫립니다.

「그러면 일회용 코드(SMS나 TOTP)를 추가하면 되지 않을까」라는 것이 기존의 다요소 인증이지만, 이것도 공유된 비밀을 보내는 구조는 변하지 않습니다. TOTP는 서버와 인증 앱이 동일한 시드(비밀)를 공유하고 있으며, 생성된 6자리 코드도 결국 이용자가 가짜 사이트에 입력할 수 있습니다. 실제로 가짜 사이트가 진짜 서버로 실시간 중계하는 AiTM(Adversary-in-the-Middle, 중간자)형 피싱은 비밀번호+일회용 코드 조합을 그대로 가로채 돌파합니다. CISA(미국 사이버보안청)가 「피싱 저항성이 있는 MFA」로 꼽는 것이 FIDO/WebAuthn 방식과 스마트카드(PIV/CAC) 같은 PKI 기반 인증, 이 두 가지뿐이며, 그중에서도 FIDO를 골드 스탠더드로 자리매김한 이유가 여기에 있습니다.4

즉 문제는 비밀번호의 ‘강도’가 아니라 ‘비밀을 공유하고, 인증할 때마다 보낸다’는 구조 그 자체에 있습니다.

3. 패스키의 정체 ── 비밀을 보내지 않고, 갖고 있음을 증명한다

패스키는 W3C의 WebAuthn과 FIDO 얼라이언스의 CTAP이라는 두 표준(합쳐서 FIDO2) 위에 성립하는, 공개키 암호 기반의 자격 증명입니다.21 어렵게 들릴 수 있지만 구조는 단순합니다.

서버이용자의 디바이스로컬에서 대조수학적인 쌍 - 서명을 만드는 쪽공개키유출되어도 악용할 수 없는'검증 전용' 정보인증기 - 금고Windows Hello / Face ID /Android 화면 잠금 / 보안 키비밀키여기서 전혀 나가지 않음지문・얼굴・PIN= 금고 문을 여는 용도일 뿐이것도 밖으로 나가지 않음

그림2: 패스키의 실체는 사이트별 키 쌍이다. 비밀 쪽은 디바이스에서 나가지 않고, 서버는 검증용 공개키만 갖는다

  • 비밀키는 서명을 만들 수 있는 쪽의 키로, 디바이스 내 인증기(Windows Hello, iPhone의 Face ID/Touch ID, Android의 화면 잠금, 또는 YubiKey 같은 보안 키)에 보관되며 밖으로 나가지 않습니다.
  • 공개키는 서명을 검증할 수 있을 뿐인 쪽의 키로, 이를 서버에 맡깁니다. 공개키에서 비밀키를 역산하는 것은 계산량적으로 불가능하므로 유출되어도 무방한 정보입니다.
  • 지문이나 얼굴 같은 생체 정보는 금고 문을 로컬에서 여는 용도로만 사용되며, 이 역시 디바이스에서 나가지 않습니다. 서버로 생체 정보가 전송되는 일은 없습니다.1

등록: 공개키’만’ 전달한다

사이트에 패스키를 등록할 때의 흐름입니다.

인증기브라우저서버(example.com)인증기브라우저서버(example.com)서버가 받은 것은「유출되어도 악용할 수 없는 정보」뿐등록 요청(난수 챌린지 + 사이트 정보)이 사이트(example.com)용 키를 만들어줘지문・얼굴・PIN으로 본인 확인(로컬)새 키 쌍 생성비밀키는 내부에 보관공개키 + credential ID(키의 이름표)공개키 + credential ID 전송이 계정의 공개키로 저장

그림3: 등록 시 네트워크를 흐르고 서버에 저장되는 것은 공개키뿐이다

중요한 것은 이때 키 쌍이 사이트의 도메인(RP ID)에 연결되어 만들어진다는 점입니다. example.com 용으로 만들어진 패스키는 example.com 사이트에서만 사용할 수 있습니다(RP ID는 도메인 단위이므로, login.example.com 같은 동일 도메인 하위의 서브도메인 페이지에서는 사용할 수 있지만, 무관한 도메인에서는 사용할 수 없습니다). 이 연결이 후술할 피싱 저항성의 토대가 됩니다.3

또한 키 쌍은 사이트마다 매번 새롭게 만들어집니다. 사이트A와 사이트B의 패스키는 수학적으로 무관하므로 ‘재사용’이라는 개념 자체가 존재하지 않으며, 사이트 간에 이용자를 대조하는 재료로도 쓰일 수 없습니다.

인증: 그 자리에서만 유효한 서명을 돌려준다

로그인 시의 흐름입니다. 비밀번호 인증(그림1)과 비교해 보십시오.

인증기브라우저서버(example.com)인증기브라우저서버(example.com)경로를 흐르는 것은 일회용 서명뿐훔쳐도 다음번 챌린지에는 사용할 수 없음로그인 요청(그 자리에서만 유효한 난수 챌린지)example.com에 대한 서명 요청지문・얼굴・PIN으로 본인 확인(로컬)비밀키로 서명 생성챌린지 + 오리진 + RP ID 해시를 새겨 넣음서명(비밀키 그 자체가 아님)서명 전송저장된 공개키로 서명 검증챌린지・오리진・RP ID도 확인

그림4: 인증 시에도 비밀은 이동하지 않는다. 흐르는 것은 「그 자리에서만 유효한 증명 서류」뿐이다

서버는 매번 새로운 난수(챌린지)를 출제하고, 인증기는 「그 챌린지 + 지금 브라우저가 보고 있는 오리진 + RP ID의 해시」에 대해 서명합니다. 서버는 저장해 둔 공개키로 서명을 검증하고, 챌린지가 자신이 출제한 것인지, 오리진과 RP ID가 자사 사이트의 것인지를 확인합니다.5

이 설계의 귀결로, 서두에서 언급한 3가지 이유 중 2가지가 이미 성립합니다.

  • 서버에 비밀이 없다: 저장되어 있는 것은 공개키뿐입니다. 유출되어도 공격자는 서명을 만들 수 없으므로, 비밀번호의 해시처럼 「가져가서 깨는」 일을 할 수 없습니다.
  • 비밀이 흐르지 않는다: 경로상의 서명을 훔치더라도 챌린지는 일회용이므로 재사용(리플레이)할 수 없습니다.

남은 하나, 「가짜 사이트에서는 서명이 성립하지 않는다」가 패스키의 가장 큰 장점입니다. 절을 나누어 살펴보겠습니다.

4. 피싱이 ‘구조적으로’ 성립하지 않는 이유

비밀번호에 대한 피싱이 성공하는 것은 진짜 비밀을 가짜 사이트에 입력할 수 있어 버리기 때문입니다. 사람은 example.comexamp1e.com을 (특히 피곤할 때는) 구별하지 못하지만, 비밀번호 입력란은 어느 사이트에서든 똑같이 동작합니다.

패스키에서는 이 대조를 사람이 아니라 브라우저가 기계적으로 수행합니다. WebAuthn의 사양상 브라우저는 「지금 표시 중인 오리진의 도메인」과 「패스키의 RP ID」가 대응하는 경우에만 인증기를 호출할 수 있습니다.3 가짜 사이트에 접속한 시점에 무슨 일이 벌어지는지를 그림으로 나타냅니다.

진짜 서버(example.com)가짜 사이트(examp1e.com)진짜로 중계하는 AiTM 프록시브라우저이용자진짜 서버(example.com)가짜 사이트(examp1e.com)진짜로 중계하는 AiTM 프록시브라우저이용자설령 어떤 방법으로 서명이 만들어지더라도,서명에는 examp1e.com이 새겨져 있으므로진짜 서버의 검증에서 반드시 탈락겉모습이 똑같은 로그인 화면에 접속(뒤에서) 진짜 로그인 처리를 시작챌린지챌린지를 가로채어 서명을 요구지금 오리진은 examp1e.comexample.com용 패스키는 후보로 낼 수 없음서명은 만들어지지 않음(이용자는 속을 방법이 없음)

그림5: AiTM형 피싱은 비밀번호+일회용 코드를 돌파하지만, 패스키에서는 서명 단계에서 성립하지 않는다

방어가 이중으로 되어 있다는 점에 주목하십시오.

  1. 후보로 나오지 않는다: 브라우저는 오리진에 대응하는 RP ID의 패스키만 나열합니다. 가짜 도메인상에서는 진짜 사이트용 패스키가 선택지에 나타나지 않으므로, 이용자는 「무심코 사용하는」 것조차 할 수 없습니다.
  2. 서명이 통과되지 않는다: 서명 대상에는 브라우저가 확인한 오리진과 RP ID의 해시가 포함됩니다. 진짜 서버는 검증 시 이를 대조하므로, 다른 오리진에서 만들어진 서명은 반드시 거부됩니다.5

비밀번호의 피싱 대책은 「이용자가 URL을 잘 살펴본다」는 인간의 노력에 의존했습니다. 패스키에서는 이용자가 가짜 사이트를 알아볼 필요가 애초에 없습니다. 이것이 「피싱 저항성(phishing-resistant)」이라는 말의 정확한 의미이며, CISA나 NIST(미국 국립표준기술연구소)가 FIDO/WebAuthn 방식을 특별 취급하는 이유입니다.46

지금까지의 내용을 공격 기법별로 정리합니다.

공격 비밀번호 비밀번호+TOTP 패스키
추측・무차별 대입 ✗ 약함 △ 코드는 막지만 원래 비밀번호는 약한 채로 ○ 추측 대상이 존재하지 않음
재사용(목록형 공격) ✗ 한 곳의 유출이 전체로 파급 △ 코드 미대응 사이트부터 무너짐 ○ 사이트마다 독립된 키
서버 DB 유출 ✗ 해시를 오프라인으로 무차별 대입 ✗ TOTP의 시드(공유 비밀)도 유출됨 ○ 공개키뿐
고전적 피싱(가짜 사이트에 입력시킴) ✗ 입력해 버림 ✗ 코드도 입력해 버림 ○ 후보로 나오지 않고 서명도 통과하지 않음
AiTM(실시간 중계) ✗ 그대로 가로채짐 ✗ 코드까지 가로채짐 ○ 오리진 대조로 서명이 성립하지 않음
리플레이(통신 재사용) ✗ 같은 비밀번호가 몇 번이든 유효 △ 본인이 사용하기 전에 가로채인 코드는 유효(사용된 코드의 재수락은 올바른 구현이라면 거부됨) ○ 챌린지가 매번 일회용

표2: 공격 기법별 저항성 비교. 패스키의 ‘○’는 어느 것이든 운영이나 주의력이 아니라 구조에서 비롯된다

5. ‘동기화되는 패스키’는 안전한가

여기까지의 설명을 읽으면 당연히 이런 의문이 듭니다. 「비밀키는 디바이스에서 나가지 않는다고 했는데, iPhone에서 만든 패스키를 iPad에서도 쓸 수 있는 건 왜지」──좋은 질문이며, 답은 「패스키에는 2가지 종류가 있다」입니다.

먼저 결론을 표로 정리해 두겠습니다. 이 절과 다음 절은 이 표의 각 행이 왜 그런지를 설명한다고 생각하고 읽어 주십시오.

관점 동기화형 패스키 디바이스 고정형 패스키
대표 예 iCloud 키체인, Google 비밀번호 관리자, 1Password 등의 비밀번호 관리자 보안 키(YubiKey 등), Windows Hello, Microsoft Authenticator 내 패스키
비밀키 보관 위치 플랫폼의 자격 증명 보관소. 같은 계정의 디바이스 간에 종단 간 암호화된 형태로 복제됨 인증기의 하드웨어 내부. TPM이나 보안 엘리먼트 밖으로는 나가지 않음
분실・기기 변경 시 같은 Apple ID/Google 계정으로 로그인하면 새 단말에 복원할 수 있음 그 인증기의 패스키는 소실됨. 예비 인증기의 복수 등록이 전제
단일 장애점 플랫폼의 클라우드 계정 물리 디바이스 그 자체
법인 관리의 적합성 키가 개인의 클라우드 계정에 들어가므로, 조직 측에서 소재 파악이나 일괄 실효가 어려움. BYOD나 소규모에는 적합함 관리자가 배포・실효할 수 있어 키의 소재가 명확함. 규정이 엄격한 환경에 적합함
NIST의 AAL 적합성 요건을 충족하면 AAL2. 비밀키를 내보낼(export) 수 있어 AAL3에는 사용할 수 없음6 하드웨어로 보호되어 키를 꺼낼 수 없는 인증기는 AAL3가 요구하는 요건에도 대응할 수 있음6

표3: 동기화형과 디바이스 고정형의 요약표. 어느 쪽을 선택할지는 ‘분실에 대한 강함’과 ‘키의 소재를 관리할 수 있음’ 중 어느 쪽을 취하느냐로 결정된다

디바이스 고정형 패스키보안 키(YubiKey 등) /Windows Hello /Microsoft Authenticator - Entra ID비밀키는 해당 하드웨어에서물리적으로 나가지 않음 - TPM 등으로 보호장점: 키의 소재가 한 곳으로 명확함주의: 분실에 대비해 복수 등록이 필수동기화형 패스키 - 소비자용 기본값iCloud 키체인 /Google 비밀번호 관리자 /1Password 등의 비밀번호 관리자같은 계정의 디바이스 간에종단 간 암호화하여 동기화사업자도 내용을 읽을 수 없음장점: 기기 변경・분실에 강함주의: 클라우드 계정 자체의 방어가 필요

그림6: 동기화형과 디바이스 고정형. 둘 다 ‘비밀키를 서버에 보내지 않는다’는 점은 같지만, 지키는 방식의 무게중심이 다르다

동기화형 패스키는 iCloud 키체인이나 Google 비밀번호 관리자가 비밀키를 같은 계정의 디바이스 간에 동기화하는 것입니다. 여기서 중요한 것은 동기화가 종단 간 암호화되어 있다는 점입니다. Apple도 Google도 패스키가 디바이스상에서 암호화된 후 동기화되며, 사업자 자신도 내용을 읽을 수 없다고 명언하고 있습니다.78 즉 「비밀키가 디바이스에서 나가지 않는다」는 원칙은 정확히는 「비밀키는 평문으로는 디바이스에서 나가지 않는다」로 완화되고, 그 대신 기기 변경이나 분실에 대한 내성을 얻습니다.

이 완화가 위협 모델을 어떻게 바꾸는지는 명확히 언어화해 두어야 합니다. 지켜야 할 곳이 ‘각 사이트의 서버’에서 ‘클라우드 계정 하나’로 집약됩니다. 각 사이트의 DB 유출이나 피싱에는 여전히 강한 채로, 이번에는 Apple ID/Google 계정 자체의 탈취가 단일 장애점이 됩니다. 그렇기 때문에 패스키를 맡기는 플랫폼 계정에는 최강의 보호(강력한 화면 잠금, 복구 수단 정리, 가능하다면 물리 보안 키)를 거는 것이 대전제입니다. NIST도 2024년 4월에 NIST SP 800-63B의 보충 문서(Supplement 1: Incorporating Syncable Authenticators Into NIST SP 800-63B)를 발표하여, 이 동기화형 패스키(syncable authenticator)가 요건을 충족하면 정부 기준의 AAL2(Authenticator Assurance Level 2, 인증기 보증 수준 2)를 충족할 수 있다고 공식적으로 자리매김했습니다. 다만 비밀키가 내보내질 수 있는 이상, 하드웨어로 격리된 환경을 요구하는 AAL3에는 동기화형을 사용하지 않기로 되어 있습니다.6

디바이스 고정형 패스키는 비밀키가 하드웨어에서 나가지 않는 유형입니다. YubiKey 같은 보안 키가 전형적이며, 법인용으로는 Microsoft Entra ID의 패스키(Microsoft Authenticator 내에 만드는 것)도 디바이스 고정형입니다.9 Windows의 Windows Hello도 TPM이 있으면 비밀키를 TPM 아래에서 보호합니다. 이 ‘키를 밖으로 내보내지 않는 하드웨어 금고’라는 구조 자체는, TPM 글에서 자세히 해설한 것과 같은 토대입니다.

참고로 「스마트폰의 패스키로 PC 브라우저에 로그인」할 때 QR 코드를 스캔하게 되는 것을 이상하게 여긴 적이 있을지도 모릅니다. 그것은 단순한 화면 전환이 아니라 Bluetooth로 스마트폰과 PC의 물리적 근접을 확인하는 하이브리드 방식(FIDO의 cross-device 인증)입니다. 원격의 공격자가 자신의 PC로의 로그인을 QR 코드를 통해 다른 사람에게 승인시키는 공격을, 근접 확인으로 무력화하고 있습니다.1

6. 은탄환이 아니다 ── 약점은 ‘사라지는’ 것이 아니라 ‘이동한다’

지금까지 패스키의 강점을 설명해 왔지만, 솔직히 말하면 패스키는 공격을 소멸시키는 것이 아니라 공격자를 더 약한 곳으로 몰아내는 기술입니다. 인증의 현관이 견고해졌을 때 공격자가 어디로 향하는지를 그림으로 나타냅니다.

공격자인증 그 자체챌린지 서명【견고함】계정 복구 흐름'패스키를 잃어버렸다'고 신고하여SMS나 메일로 재설정시키고,공격자의 패스키를 등록함병존하는 폴백비밀번호・SMS 로그인이남아 있으면 최약 링크는 그곳클라우드 계정동기화형이라면 Apple ID /Google 계정이 단일 장애점세션로그인 후 쿠키를 훔치면인증 방식은 무관함

그림7: 현관(인증)이 견고해지면 공격은 복구 흐름・병존 수단・클라우드 계정・세션으로 옮겨간다

실무에서 짚어 두어야 할 잔존 위험은 4가지입니다.

  1. 병존하는 폴백이 최약 링크가 된다. 패스키’도’ 쓸 수 있게 했을 뿐, 비밀번호나 SMS 로그인이 남아 있으면 공격자는 그쪽을 쓸 뿐입니다. 피싱 저항성은 계정 전체로 보면 가장 약한 로그인 수단의 수준에 의해 율속됩니다. 도입의 본거지는 패스키 추가가 아니라 폴백의 계획적인 축소・폐지입니다.
  2. 복구 흐름이 새로운 공격면이 된다. 「디바이스를 잃어버렸다」고 속여 지원 창구나 메일을 통한 재설정으로 끌고 가서, 공격자 자신의 패스키를 등록시키는 수법입니다. 실제로 견고한 인증을 우회해 헬프데스크를 속이는 사회공학은 대규모 침해의 상투적인 수단이 되었습니다. 인증을 견고히 한 만큼, 복구 흐름의 본인 확인을 어떻게 설계할지가 관건입니다.
  3. 동기화형에서는 클라우드 계정이 단일 장애점. 앞 절에서 설명한 대로입니다. 패스키를 맡기는 계정의 방어와, 조직에서 사용할 경우 「어느 플랫폼으로의 동기화를 허용할 것인가」에 대한 방침 결정이 필요합니다.
  4. 세션 탈취는 막을 수 없다. 패스키가 지키는 것은 로그인 순간뿐이며, 로그인 후의 세션 쿠키를 악성코드나 XSS로 도난당하면 인증 방식은 무관합니다. 토큰의 유효 기간・바인딩・디바이스 건전성 관리라는 별개 계층의 작업은 남습니다.

이는 「패스키는 그만두자」는 이야기가 아닙니다. 현관 자물쇠를 최신으로 바꿔도 창문 잠금은 별개의 일이라는 당연한 이야기입니다. 오히려 약점의 위치가 명확해지는 만큼, 방어 자원을 복구 흐름과 세션 관리에 집중 투입할 수 있게 됩니다.

7. 실무 도입 ── WebAuthn API와 Windows 환경

마지막으로 도입하는 쪽의 관점에서 요점을 짚어보겠습니다.

자사 웹 서비스에 패스키 로그인 붙이기

브라우저 쪽은 WebAuthn API의 두 함수만 있으면 됩니다. 등록은 navigator.credentials.create(), 인증은 navigator.credentials.get()을 호출합니다.

// 등록(브라우저 측)
const credential = await navigator.credentials.create({
  publicKey: {
    challenge: challengeFromServer,   // 서버가 생성한 일회용 난수
    rp: { id: "example.com", name: "Example" },
    user: { id: userIdBytes, name: "taro@example.com", displayName: "길동" },
    pubKeyCredParams: [{ type: "public-key", alg: -7 }],  // ES256
    authenticatorSelection: {
      residentKey: "required",        // 검색 가능 자격 증명(=패스키)으로 지정
      userVerification: "required",   // 생체 인증/PIN에 의한 본인 확인을 필수로 지정
    },
  },
});
// 공개키는 credential.response에서, credential ID는 최상위의
// credential.id / credential.rawId에서 꺼낸다. 등록 응답도 인증 시와
// 마찬가지로 챌린지・오리진・RP ID를 서버에서 검증한 뒤 저장한다

주요 파라미터의 의미는 다음과 같습니다.

파라미터 역할 구현 시 주의점
challenge 서버가 매번 생성하는 일회용 난수 추측할 수 없는 암호학적 난수를 사용한다. 서버 측에서 「자신이 발급한 미사용 값」임을 검증하고 소비한다
rp.id 자격 증명을 연결할 도메인(RP ID) 생략하면 호출한 쪽 오리진의 유효 도메인이 된다. login.example.com에서 example.com을 지정하는 것처럼, 등록 가능 도메인 범위에서만 지정할 수 있다
user.id 서버 내부의 사용자 식별자(user handle) 64바이트 이하의 불투명한 값. 이메일 주소나 사용자명 등 개인을 특정할 수 있는 정보를 그대로 넣지 않는다2
user.name / user.displayName 인증기나 브라우저의 UI에 표시되어 이용자가 계정을 선택하기 위한 문자열 표시 전용. 서버가 이 값을 신뢰하여 계정을 특정해서는 안 된다
pubKeyCredParams 수용할 공개키 알고리즘을 우선순위로 나열 -7(ES256)에 더해 -257(RS256)도 함께 적어 두면 수용 가능한 인증기의 폭이 넓어진다
authenticatorSelection 인증기에 요구하는 속성 residentKey: "required"로 패스키(검색 가능 자격 증명)가 되고, userVerification: "required"로 생체 인증・PIN에 의한 본인 확인이 필수가 된다

표4: navigator.credentials.create()의 주요 파라미터

검증 환경 주의: WebAuthn API는 보안 컨텍스트에서만 공개되므로, 순수한 http://로 배포한 페이지에서는 navigator.credentials 호출이 실패합니다. 예외는 http://localhost(및 127.0.0.1)로, 이들은 신뢰할 수 있는 오리진으로 취급되므로 개발 기기에서는 HTTPS화하지 않아도 그대로 시험해 볼 수 있습니다. 다만 RP ID는 오리진의 유효 도메인(또는 그 상위 도메인)이어야 하므로, localhost에서 만든 패스키는 운영 도메인에서는 사용할 수 없습니다. 손에 인증기가 없어도 Chrome 개발자 도구의 「WebAuthn」 탭에서 가상 인증기를 활성화하면, 등록부터 인증까지 일련의 흐름을 동작시켜 볼 수 있습니다.

// 인증(브라우저 측)
const assertion = await navigator.credentials.get({
  publicKey: {
    challenge: challengeFromServer,
    rpId: "example.com",
    userVerification: "required",
  },
  // 로그인란의 자동 완성 후보로 패스키를 제시한다. 사전에
  // PublicKeyCredential.isConditionalMediationAvailable()로 지원 여부를 확인하고,
  // 미지원 브라우저에서는 mediation을 붙이지 않는 일반 호출로 폴백한다
  mediation: "conditional",
  // (대상 <input>에 autocomplete="username webauthn" 지정이 필요)
});
// assertion.response의 서명을 서버에서 검증한다

본체는 서버 측 검증입니다. 최소한 다음을 반드시 수행합니다.5

  • 챌린지 대조: 자신이 발급한 미사용 챌린지인가. 일회용으로 처리하고 있는가(리플레이 대책). 나아가 발급 시의 브라우저 세션(로그인 시도)에 연결하여 저장하고, 같은 세션에서의 응답에만 소비를 허용할 것. 이 부분이 느슨하면, 공격자가 자신에게 온 챌린지에 대한 서명을 피해자의 브라우저를 경유해 흘려보내, 피해자를 공격자의 계정에 로그인시키는(로그인 CSRF) 여지가 생긴다.
  • 오리진 대조: clientDataJSONorigin이 자사 사이트의 정규 오리진인가(피싱 대책의 핵심).
  • RP ID 해시 대조: authenticatorDatarpIdHash가 자사 사이트의 RP ID의 SHA-256과 일치하는가.
  • 세리머니 종류와 플래그 확인: clientDataJSONtype이 인증이면 webauthn.get, 등록이면 webauthn.create인가. authenticatorData의 UP(사용자 존재) 플래그가 서 있는가. 사용자 검증(UV)을 요구했다면 UV 플래그도 서 있는가.
  • 서명 검증: 등록 시 저장한 공개키로 서명이 올바르게 검증되는가.
  • 계정과의 연결: 제시된 credential ID(와 userHandle)를 자신의 데이터베이스에서 조회하여, 그 자격 증명의 소유자에 대해 세션을 발급하고 있는가. 별도로 입력된 사용자명을 무조건 신뢰하면, 올바른 서명으로 타인을 사칭해 로그인시키는 구멍이 된다.
  • 서명 카운터 저장과 비교: authenticatorData의 signCount를 자격 증명마다 저장하고, 다음번 값이 이전보다 증가했는지 확인한다. 이전 값 이하(같은 값 포함)라면 인증기 복제(클론)의 징후로 취급한다. 다만 동기화형 패스키는 항상 0을 반환하는 구현이 많으므로, 0끼리인 경우만 예외로 허용한다.

이 검증을 직접 손으로 작성하는 것은 사고의 원인이 되므로, 실적 있는 라이브러리(.NET이라면 fido2-net-lib, Node.js라면 SimpleWebAuthn 등)를 사용하십시오. 사양의 세부 사항(CBOR 파싱, 알고리즘 합의, 챌린지 관리)은 라이브러리에 맡기고, 우리는 챌린지의 저장과 실효, 복수 패스키의 관리 UI, 복구 흐름 설계에 집중하는 것이 올바른 역량 배분입니다.

Windows 환경・사내 시스템의 경우

이 사이트의 독자층인 「Windows 업무 시스템을 맡고 있는 입장」에서는 다음 3가지만 짚어 두면 충분합니다.

  • Windows 클라이언트는 이미 대응 완료. Windows 11은 Windows Hello를 인증기로 하여 패스키의 생성・사용・관리(설정 > 계정 > 패스키)를 지원하며, 비밀키는 TPM이 있으면 하드웨어로 보호됩니다.10 브라우저(Edge/Chrome)를 경유한 WebAuthn은 Windows 10에서도 동작합니다.
  • Entra ID 환경에서는 ‘패스키=FIDO2 인증 방식’을 활성화한다. Microsoft Entra ID는 보안 키와 Microsoft Authenticator 앱 내 패스키(디바이스 고정형)를 지원하며, 조건부 액세스의 인증 강도에서 「피싱 저항성 MFA」를 요구하면 대상 리소스로의 액세스를 패스키 등으로 한정할 수 있습니다.9 NTLM이나 비밀번호 만료 정책의 세계에서의 이행은 단번에 진행되지 않으므로, NTLM과 Kerberos 글에서 다룬 인증 기반의 재점검과 병행하여 우선 관리자 계정부터 피싱 저항성 MFA를 의무화하는 것이 정석입니다.
  • 사내 웹 앱에서도 이점은 동일. 다만 HTTPS가 전제. WebAuthn API는 보안 컨텍스트에서만 동작하므로, 인트라넷 앱이라도(개발 시 localhost는 예외) HTTPS화와, RP ID로 사용할 수 있는 내부 도메인명 정비가 먼저입니다. 그것만 마치면 RP ID는 내부 도메인에 대해서도 작동합니다. 비밀번호 포스트잇과의 결별이라는 의미에서는, 외부용 서비스보다 사내 쪽이 효과가 더 빨리 나타나는 경우도 드물지 않습니다.

8. 정리

  • 비밀번호의 약점은 강도가 아니라 ‘비밀을 공유하고 인증할 때마다 보낸다’는 구조에 있다. 비밀이 이용자・입력란・경로・서버 모두에 존재하므로 공격 대상이 많다. 일회용 코드를 추가해도 AiTM형 피싱에는 중계되어 패배한다.
  • 패스키는 사이트별 공개키 암호의 키 쌍이며, 서버에는 유출되어도 악용할 수 없는 공개키만 전달하고, 로그인 시에는 일회용 챌린지에 대한 서명만을 보낸다. 서버에 비밀이 없고, 경로에도 비밀이 흐르지 않는다.
  • 서명에는 브라우저가 확인한 오리진과 RP ID가 새겨지므로, 가짜 사이트에서는 진짜용 패스키가 후보로 나오지 않고, 중계하더라도 검증에서 탈락한다. 이용자가 가짜 사이트를 알아볼 필요가 없다는 것이 ‘피싱 저항성’의 정체이며, 방어의 근거가 인간의 주의력에서 프로토콜의 구조로 옮겨갔다.
  • 동기화형 패스키는 종단 간 암호화로 동기화되어 기기 변경・분실에 강하다. 그 대신 지켜야 할 곳이 클라우드 계정으로 집약되므로, Apple ID/Google 계정 자체의 방어가 대전제가 된다. 법인은 디바이스 고정형(보안 키, Entra ID의 Authenticator 패스키)도 선택할 수 있다.
  • 패스키는 공격을 없애는 것이 아니라 약한 곳으로 몰아낸다. 병존하는 비밀번호, 계정 복구 흐름, 세션 탈취가 남은 공격면이며, 도입의 본거지는 폴백의 계획적 축소와 복구 흐름 강화에 있다.
  • 구현은 WebAuthn API의 create / get 두 함수 + 서버 검증. 검증은 직접 만들지 않고 실적 있는 라이브러리에 맡기며, 챌린지 관리・복수 패스키 UI・복구 설계에 힘을 쏟는다.

관련 글

관련 상담 영역

합동회사 코무라소프트에서는 사내 웹 시스템에 대한 패스키 로그인・WebAuthn 구현 지원, Entra ID 환경에서의 피싱 저항성 MFA 전개 설계, WinForms/WPF 등 Windows 업무 앱에 대한 인증 통합을 포함한 수탁 개발을 다루고 있습니다.

  1. FIDO 얼라이언스, PasskeysHow FIDO Works. 패스키가 FIDO 자격 증명으로서 비밀번호를 대체하는 것이라는 점, 생체 정보가 디바이스에서 전송되지 않고 로컬 대조에만 사용된다는 점, 2022년 5월에 Apple・Google・마이크로소프트가 FIDO 표준에 의한 패스워드리스 대응 확대를 공동으로 표명했다는 점, 디바이스를 넘나드는 이용(cross-device)에서는 QR 코드와 Bluetooth에 의한 근접 확인을 이용하는 하이브리드 방식이 사용된다는 점에 대해.  2 3 4 5

  2. W3C, Web Authentication: An API for accessing Public Key Credentials Level 2(W3C 권고). WebAuthn이 공개키 암호 기반의 자격 증명을 생성・이용하기 위한 API라는 점, 자격 증명의 비밀키는 인증기에 보관되며 서버(Relying Party)에는 공개키와 credential ID만 등록된다는 점, 인증은 서버가 보내는 챌린지에 대한 서명(어서션)으로 이루어진다는 점, 자격 증명의 범위와 보호에 관한 설계 목표에 대해. 아울러 API가 보안 컨텍스트에서만 공개된다는 점, RP ID가 생략 시 호출한 쪽 오리진의 유효 도메인이 된다는 점, user handle(user.id)이 최대 64바이트의 불투명한 값이며 사용자명이나 이메일 주소처럼 개인을 특정하는 정보를 포함해서는 안 된다는 점(§14.6.1 User Handle Contents)에 대해서도 본문에서 참조하고 있다.  2 3 4 5

  3. W3C, Web Authentication Level 2 — §5.1.3 Create / RP ID validation, §13.4.9 Regarding phishing. 공개키 자격 증명이 RP ID(Relying Party 식별자=도메인)에 범위 지정된다는 점, 브라우저(클라이언트)가 호출한 쪽 오리진의 등록 가능 도메인과 RP ID의 대응을 검증하며 대응하지 않을 경우 자격 증명의 생성・이용을 거부한다는 점, 이로 인해 가짜 오리진에서는 다른 사이트용 자격 증명에 접근할 수 없어 WebAuthn이 중간자형을 포함한 피싱 공격에 대한 저항성을 갖는다는 점에 대해.  2 3

  4. CISA, Implementing Phishing-Resistant MFA(2022년 10월 팩트시트). SMS나 음성, 푸시 알림, OTP를 사용하는 MFA가 피싱이나 AiTM(중계) 공격・MFA 피로 공격에 취약하다는 점, 피싱 저항성이 있는 방식으로 FIDO/WebAuthn 인증과 PKI 기반 인증(스마트카드 등)이 꼽히며 FIDO/WebAuthn 인증이 골드 스탠더드로 자리매김하고 있다는 점, 조직은 우선 고위험 계정부터 피싱 저항성 MFA로 이행해야 한다는 점에 대해.  2

  5. W3C, Web Authentication Level 2 — §7.2 Verifying an Authentication Assertion. 서버 측 검증 절차로서, clientDataJSON의 type・challenge(자신이 발급한 것과의 일치)・origin 검증, authenticatorData 내 rpIdHash가 기대하는 RP ID의 SHA-256 해시와 일치하는지의 검증, User Present / User Verified 플래그 확인, 저장된 공개키에 의한 서명 검증이 규정되어 있다는 점에 대해.  2 3

  6. NIST, Incorporating Syncable Authenticators Into NIST SP 800-63B(2024년 4월 보충 문서, SP 800-63B 제4판에 통합). 동기화 가능한 인증기(동기화형 패스키)의 비밀키가 요건을 충족하는 형태로 동기화 패브릭에 보관・복제되는 경우 AAL2를 충족할 수 있다는 점, 한편 AAL3의 암호 인증기에는 하드웨어로 보호・격리된 환경이 요구되므로 비밀키를 내보낼 수 있는 동기화형 인증기는 AAL3에서 사용하지 않기로 되어 있다는 점, WebAuthn처럼 오리진 검증을 수행하는 방식이 검증자 사칭 저항성(피싱 저항성)을 갖는다고 정리되어 있다는 점에 대해. 원문 PDF는 NIST SP 800-63B Supplement 1 2 3 4

  7. Apple 지원, 패스키 보안에 대해. 패스키가 iCloud 키체인으로 동기화된다는 점, iCloud 키체인이 종단 간 암호화되어 있어 Apple도 읽을 수 없다는 점, 동기화는 사용자 디바이스상의 키로 보호되며 속도 제한이 있는 에스크로를 통한 복구가 마련되어 있다는 점에 대해. 

  8. Google, Google 비밀번호 관리자에서의 패스키 보안. 패스키의 비밀키가 디바이스상에서 암호화된 후 동기화된다는 점, 종단 간 암호화로 인해 Google 자신도 비밀키의 내용에 접근할 수 없다는 점, 복원에는 단말기 화면 잠금 등에 기반한 보호가 요구된다는 점에 대해. 

  9. Microsoft Learn, Enable passkey (FIDO2) authentication in Microsoft Entra ID. Entra ID가 FIDO2 보안 키 및 Microsoft Authenticator의 패스키(디바이스 바인드)에 의한 피싱 저항성 있는 패스워드리스 인증을 지원한다는 점, 인증 방법 정책에서의 활성화와 조건부 액세스의 인증 강도(피싱 저항성 MFA)에 의한 요구가 가능하다는 점에 대해.  2

  10. Microsoft Learn, Passkey support on Windows. Windows 11이 Windows Hello를 이용한 패스키의 생성・사용을 지원한다는 점, 저장된 패스키를 설정 > 계정 > 패스키에서 관리할 수 있다는 점, Windows Hello의 자격 증명이 TPM을 사용할 수 있는 환경에서는 하드웨어로 보호된다는 점, 모바일 디바이스상의 패스키를 QR 코드를 통해 이용할 수 있다는 점에 대해. 

같은 태그를 공유하는 최신 기사입니다. 더 가까운 주제로 지식을 넓힐 수 있습니다.

이 기사와 가까운 토픽 페이지입니다. 기사를 출발점 삼아 관련 서비스와 다른 기사로 이어집니다.

자주 묻는 질문

이 기사 주제에 대해 상담 시 자주 나오는 질문을 모았습니다.

패스키와 비밀번호의 근본적인 차이는 무엇인가요?
비밀번호는 '이용자와 서버가 같은 비밀을 공유하고, 로그인할 때마다 그 비밀을 보내는' 구조입니다. 비밀이 이용자의 머릿속・입력란・통신 경로・서버의 데이터베이스 등 모든 곳에 존재하기 때문에 그 전부가 공격 대상이 됩니다. 패스키는 공개키 암호의 키 쌍을 사용하며, 비밀키가 서버로 보내지는 일이 없습니다. 디바이스 고정형에서는 비밀키가 인증기 밖으로 전혀 나가지 않고, 동기화형에서도 종단 간 암호화된 형태로만 밖으로 나갑니다. 서버에 저장되는 것은 공개키라는 '유출되어도 악용할 수 없는 정보'뿐이며, 로그인 시 전송되는 것도 그 자리에서만 유효한 챌린지에 대한 서명뿐입니다. 즉 비밀번호의 약점이었던 '공유된 비밀' 그 자체가 존재하지 않습니다. 게다가 키 쌍은 사이트마다 별도로 만들어지므로 재사용이라는 개념도 성립하지 않습니다.
생체 정보(지문・얼굴)는 서버로 전송되나요?
전송되지 않습니다. 지문이나 얼굴 데이터는 디바이스 안에서 '비밀키가 든 금고의 문을 여는' 용도로만 쓰이는 로컬 대조이며, FIDO의 설계상 생체 정보가 디바이스 밖으로 전송되는 일은 없습니다. 서버가 받는 것은 '이용자의 본인 확인(사용자 검증)이 이루어졌다'는 플래그가 선 서명뿐이며, 지문 자체는 물론 그 특징값도 전혀 포함되지 않습니다. 생체 인증을 사용할 수 없는 상황에서는 PIN으로 대체할 수 있지만, 이 PIN도 Windows Hello의 PIN과 마찬가지로 디바이스 로컬에서만 대조되는 것으로, 네트워크를 흐르지 않는다는 점이 비밀번호와 결정적으로 다릅니다.
패스키는 왜 피싱에 강한가요?
이용자가 가짜 사이트를 알아볼 필요가 애초에 구조상 없기 때문입니다. 패스키는 사이트의 도메인(RP ID)에 연결되어 만들어지며, 브라우저는 '지금 표시 중인 사이트의 도메인'에 대응하는 패스키만 후보로 내놓습니다. 진짜와 똑같은 가짜 도메인에 접속하더라도 진짜 사이트용 패스키는 선택지에 나타나지 않으므로, 이용자는 속을 방법이 없습니다. 게다가 서명에는 브라우저가 확인한 오리진과 RP ID의 해시가 새겨지므로, 설령 서명을 중계하더라도 진짜 서버 측의 검증에서 탈락합니다. 비밀번호나 SMS 코드처럼 '진짜 자격 증명을 가짜 사이트에 입력해 버리는' 사고가 구조적으로 일어날 수 없다는 것이, 교육이나 주의 환기에 의존하는 대책과의 근본적인 차이입니다.
스마트폰을 잃어버리면 계정에 들어갈 수 없게 되나요?
동기화형 패스키(iCloud 키체인이나 Google 비밀번호 관리자에 저장되는 것)라면, 같은 Apple ID/Google 계정으로 로그인한 새 디바이스에 복원할 수 있습니다. 다만 종단 간 암호화된 보관소의 복원에는 계정 비밀번호뿐 아니라 이전 단말의 화면 잠금(암호) 입력 등 추가적인 본인 확인이 요구되므로, 이런 복구 수단까지 함께 잃어버리면 복원할 수 없는 경우가 있습니다. 스마트폰 한 대에만 모든 것을 맡기지 않는 자세가 중요합니다. 디바이스 고정형(보안 키나 Windows Hello 등)은 단말과 운명을 함께하므로, 중요한 계정에는 여러 개의 패스키를 등록해 두는 것이 정석입니다. 많은 서비스가 계정 하나에 여러 패스키를 등록할 수 있습니다. 분실 시 무효화는 종류에 따라 절차가 달라진다는 점에 주의해야 합니다. 동기화형은 각 디바이스의 사본이 동일한 하나의 자격 증명이므로, 우선 플랫폼의 계정 쪽에서 분실 단말을 삭제하거나 원격 초기화하여 단말상의 사본을 사용할 수 없게 합니다(서비스 측의 계정 설정에서 해당 패스키를 삭제하면 모든 디바이스의 사본이 한꺼번에 무효화됩니다). 디바이스 고정형이라면 서비스 측에서 해당 인증기의 패스키를 삭제하면 잃어버린 키만 무효화할 수 있습니다. 조직에서 사용할 경우에는 '이용자가 스스로 복구할 수 있는 이중화'와 '분실 시 관리자가 실효시키는 절차'를 함께 설계해 두는 것이 중요합니다.
패스키에도 약점이 있나요?
있습니다. 다만 약점의 위치가 바뀐다는 표현이 정확합니다. 인증 그 자체는 공개키 암호로 견고해지므로, 공격자는 더 약한 주변부를 노립니다. 구체적으로는 비밀번호나 SMS 같은 기존 수단이 병존하고 있으면 그곳이 최약 링크로 남는다는 점, 계정 복구 흐름을 악용해 공격자가 자신의 패스키를 등록하는 수법, 동기화형에서는 클라우드 계정 자체의 탈취가 새로운 단일 장애점이 된다는 점입니다. 또한 로그인 후의 세션 쿠키를 훔치는 공격은 패스키로 막을 수 없으므로, 무관한 위협이 사라지는 것도 아닙니다. 도입 시에는 '패스키를 추가'하는 것뿐 아니라 복구 흐름의 강화와 폴백 수단의 계획적인 축소까지 포함하여 설계할 필요가 있습니다.

저자 프로필

기사 저자의 프로필 페이지입니다.

Go Komura

합동회사 코무라소프트 대표

Windows 소프트웨어 개발, 기술 상담, 장애 조사를 중심으로 재현이 어려운 장애 조사와 기존 자산이 남아 있는 프로젝트에 강점이 있습니다.

블로그 목록으로 돌아가기