WebAuthn으로 강력한 인증 사용 설정

문제

피싱은 웹에서 가장 큰 보안 문제입니다. 지난해 해킹 관련 계정 보안 침해의 81% 가 취약하거나 도난당한 비밀번호를 사용한 것이었습니다. 이 문제에 대한 업계의 집단적 대응은 다중 인증(MFA)을 해왔지만, 구현은 단편화되어 있으며 대부분은 피싱을 적절하게 처리하지 못합니다. Google은 2013년부터 FIDO Alliance와 협력하고 있으며, 최근에는 W3C와 협력하여 모든 웹 애플리케이션에서 사용할 수 있는 표준화된 피싱 방지 프로토콜을 구현했습니다.

WebAuthn이란 무엇인가요?

웹 인증 API는 애플리케이션 범위(eTLD+k) 공개 키 사용자 인증 정보를 생성하고 시험하기 위해 웹 애플리케이션에 사용자 에이전트에서 인증자(USB/BLE/NFC 또는 플랫폼에 직접 빌드된 모듈을 통해 액세스되는 하드웨어 토큰인 경우가 많음)에 대한 액세스를 제공합니다. 이를 통해 다음과 같은 다양한 사용 사례가 지원됩니다.

  • 마찰이 적고 피싱을 방지하는 2단계 인증(2FA)(비밀번호와 함께 사용)
  • 패스워드리스, 생체 인식 기반 재승인
  • 비밀번호가 없는 원활한 피싱 방지 2단계 인증 (비밀번호가 없는 계정에 사용)

이 API는 대부분의 주요 브라우저에서 구현될 예정이며, 온라인에서 신원을 증명해야 할 때 경험하는 UI를 단순화하고 피싱을 크게 줄이기 위한 것입니다.

WebAuthn은 Credential Management API를 확장하고 PublicKeyCredential라는 새로운 사용자 인증 정보 유형을 추가합니다. WebAuthn은 브라우저와 인증자 간의 통신을 추상화하고 사용자가 다음을 수행할 수 있도록 합니다.

  1. 웹사이트의 공개 키 사용자 인증 정보를 만들고 등록합니다.
  2. 상응하는 비공개 키의 소유를 증명하여 웹사이트에 인증합니다.

인증자는 비공개/공개 키 쌍을 생성하고 동의를 수집할 수 있는 기기입니다. FIDO2 요구사항을 준수하는 한 간단한 탭이나 성공적인 디지털 지문 판독을 통해 서명에 관한 동의를 부여할 수 있습니다 (FIDO Alliance의 인증자를 위한 인증 프로그램이 있음). 인증자는 플랫폼에 내장 (예: 스마트폰의 지문 스캐너)되거나 USB, 저전력 블루투스 (BLE) 또는 근거리 무선통신 (NFC)을 통해 연결될 수 있습니다.

사용 방법

키 쌍 만들기 및 사용자 등록

사용자가 웹사이트에 사용자 인증 정보를 등록하려는 경우 (WebAuthn에서 '신뢰 당사자'라고 함):

  1. 신뢰 당사자가 챌린지를 생성합니다.
  2. 신뢰 당사자는 Credential Manager API를 통해 브라우저에 신뢰 당사자의 새 사용자 인증 정보를 생성하도록 요청하여 기기 기능(예: 기기가 생체 인식 등의 자체 사용자 인증)을 제공하는지 여부를 지정합니다.
  3. 인증자가 사용자 동의를 얻으면 키 쌍을 생성하고 공개 키와 서명된 증명(선택사항)을 웹사이트에 반환합니다.
  4. 웹 앱은 공개 키를 서버에 전달합니다.
  5. 서버는 향후 인증을 위해 사용자 인증 정보를 기억하기 위해 사용자 ID와 함께 공개 키를 저장합니다.
let credential = await navigator.credentials.create({ publicKey: {
  challenge: new Uint8Array([117, 61, 252, 231, 191, 241, ...]),
  rp: { id: "acme.com", name: "ACME Corporation" },
  user: {
    id: new Uint8Array([79, 252, 83, 72, 214, 7, 89, 26]),
    name: "jamiedoe",
    displayName: "Jamie Doe"
  },
  pubKeyCredParams: [ {type: "public-key", alg: -7} ]
}});

사용자 인증

웹사이트가 올바른 사용자와 상호작용하고 있다는 증거를 확보해야 하는 경우:

  1. 신뢰 당사자는 본인 확인 질문을 생성하고 사용자에게 등록된 사용자 인증 정보 목록을 브라우저에 제공합니다. 또한 사용자 인증 정보를 찾을 위치를 나타낼 수도 있습니다(예: 로컬 내장 인증자 또는 USB, BLE 등을 통한 외부 인증자).
  2. 브라우저에서 인증자에게 챌린지에 서명하도록 요청합니다.
  3. 인증자에 지정된 사용자 인증 정보 중 하나가 포함된 경우 인증자는 사용자 동의를 받은 후 서명된 어설션을 웹 앱에 반환합니다.
  4. 웹 앱은 신뢰 당사자가 확인할 수 있도록 서명된 어설션을 서버로 전달합니다.
  5. 서버에서 확인하면 인증 흐름이 성공한 것으로 간주됩니다.
let credential = await navigator.credentials.get({ publicKey: {
  challenge: new Uint8Array([139, 66, 181, 87, 7, 203, ...]),
  rpId: "acme.com",
  allowCredentials: [{
    type: "public-key",
    id: new Uint8Array([64, 66, 25, 78, 168, 226, 174, ...])
  }],
  userVerification: "required",
}});

https://webauthndemo.appspot.com/에서 직접 WebAuthn을 사용해 봅니다.

다음 단계

Chrome 67 베타는 navigator.credentials.get({publicKey: ...})navigator.credentials.create({publicKey:... }) 지원과 함께 제공되며 데스크톱에서 USB 전송을 통해 U2F/CTAP 1 인증자를 사용할 수 있습니다.

향후 출시에서는 BLE 및 NFC와 같은 더 많은 전송과 최신 CTAP 2선 프로토콜에 관한 지원이 추가됩니다. 또한 PIN 보호 인증자, 사용자 이름이나 비밀번호를 입력하는 대신 계정의 로컬 선택, 지문 등록 등 CTAP 2 및 WebAuthn을 통해 지원되는 고급 흐름도 개발하고 있습니다.

Microsoft Edge도 API를 지원하며 Firefox는 Firefox 60부터 WebAuthn을 지원합니다.

자료

더 자세한 문서를 만들기 위해 노력하고 있습니다.

Google I/O 2018의 '웹에서 가입 및 로그인의 새로운 소식' 세션에서는 WebAuthn을 다루었습니다.