웹 인증:
공개 키 자격 증명에 접근하기 위한 API
레벨 3

W3C 후보 권고안 스냅샷,

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2026/CR-webauthn-3-20260113/
최신 게시 버전:
https://www.w3.org/TR/webauthn-3/
편집자 초안:
https://w3c.github.io/webauthn/
이전 버전:
이력:
https://www.w3.org/standards/history/webauthn-3/
구현 보고서:
https://www.w3.org/2020/12/webauthn-report.html
피드백:
GitHub
편집자:
(Okta)
(Self-Issued Consulting)
(Microsoft)
(Yubico)
(Cisco)
이전 편집자:
(Google)
(Microsoft)
(Google)
(Google)
Jeff Hodges (formerly Google)
J.C. Jones (formerly Mozilla)
(PayPal)
(Microsoft)
(Nok Nok Labs)
기여자:
John Bradley (Yubico)
Christiaan Brand (Google)
Adam Langley (Google)
Giridhar Mandyam (Qualcomm)
Pascoe (Apple)
Nina Satragno (Google)
Ki-Eun Shin (SK Telecom)
Nick Steele (1Password)
Jiewen Tan (Apple)
Shane Weeden (IBM)
Mike West (Google)
Jeffrey Yasskin (Google)
Anders Åberg (Bitwarden)
테스트:
web-platform-tests webauthn/ (진행 중인 작업)

요약

이 명세서는 웹 애플리케이션이 강력하고 증명이 가능한, 범위 지정된 공개 키 기반 자격 증명을 생성하고 사용할 수 있는 API를 정의하며, 사용자를 강력하게 인증하는 목적을 가집니다. 개념적으로, 하나 이상의 공개 키 자격 증명이 각각 특정 범위WebAuthn Relying Party에 속하도록, 웹 애플리케이션의 요청에 따라 생성되어 바인딩인증기에 연결됩니다. 사용자 에이전트는 사용자 프라이버시를 보호하기 위해 인증기와 그들의 공개 키 자격 증명에 대한 접근을 중재합니다. 인증기는 사용자 동의(user consent) 없이는 어떠한 작업도 수행되지 않도록 보장할 책임이 있습니다. 인증기증명을 통해 자신의 속성에 대한 암호학적 증거를 의존 당사자에게 제공합니다. 이 명세서는 또한 서명 및 증명 기능을 포함한 WebAuthn 규격을 준수하는 인증기의 기능 모델을 설명합니다.

문서의 상태

이 섹션은 이 문서가 출판될 당시의 상태를 설명합니다. 현재 W3C 출판물 목록과 이 기술 보고서의 최신 개정본은 W3C 표준 및 초안 색인에서 찾을 수 있습니다.

웹 인증(Web Authentication) 명세가 후보 권고(Candidate Recommendation)를 넘어 진행되기 위해서는 두 개의 브라우저가 새로운 기능과 확장 기능을 지원하는 구현을 보여야 합니다. 명세는 Web Platform Tests의 Level 3를 통해 테스트됩니다.

이 문서는 웹 인증 작업 그룹권고 경로를 사용하여 후보 권고 스냅샷으로 출판하였습니다.

이 명세에 대한 의견과 피드백을 환영합니다. Github 이슈를 이용해 주세요. 토론은 public-webauthn@w3.org 아카이브에서도 찾아보실 수 있습니다.

후보 권고로서의 출판은 W3C 및 회원들의 지지를 의미하지 않습니다. 후보 권고 스냅샷은 광범위한 리뷰를 거쳤으며, 구현 경험을 모으고, 작업 그룹 구성원들이 로열티 없는 라이선스 제공 약속을 한 상태입니다.

이 문서는 초안이며 언제든지 업데이트, 대체 또는 폐기될 수 있습니다. 진행 중인 작업 이외의 인용은 부적절합니다.

이 후보 권고는 2026년 2월 10일 이전에는 권고안으로 발전할 것으로 기대하지 않습니다.

이 문서는 W3C 특허 정책에 따라 운영되는 그룹에 의해 작성되었습니다. W3C는 그룹의 결과물과 관련된 공개 특허 공시 목록을 유지합니다. 해당 페이지에는 특허 공시 방법도 포함되어 있습니다. 특정 특허에 대한 실질적 지식을 가진 개인은 그 특허가 필수 주장을 포함한다고 생각될 경우 W3C 특허 정책 6조에 따라 정보를 공시해야 합니다.

이 문서는 2025년 8월 18일 W3C 프로세스 문서에 의해 관리됩니다.

1. 소개

이 섹션은 규범적인 내용이 아닙니다.

이 명세서는 웹 애플리케이션이 강력하고 증명 가능한, 범위 지정된 공개 키 기반 자격 증명을 생성하고 사용할 수 있도록 하는 API를 정의하며, 사용자를 강력하게 인증하는 목적을 가지고 있습니다. 공개 키 자격 증명WebAuthn 인증기에 의해 WebAuthn 의존 당사자의 요청에 따라 생성되고 저장되며, 사용자 동의의 대상이 됩니다. 이후 해당 공개 키 자격 증명은 그 오리진에 속하는 의존 당사자만 접근할 수 있습니다. 이 범위 지정은 준수하는 사용자 에이전트인증기에 의해 공동으로 강제됩니다. 또한 서로 다른 의존 당사자 간의 프라이버시도 유지됩니다; 한 의존 당사자는 다른 의존 당사자에 범위 지정된 자격 증명의 속성이나 존재 여부조차도 감지할 수 없습니다.

의존 당사자는 사용자와 관련된 두 가지 구별되지만 관련된 절차 동안 Web Authentication API를 사용합니다. 첫 번째는 등록으로, 이 절차에서는 공개 키 자격 증명인증기에 생성되어 현재 사용자의 계정에 범위 지정됩니다(계정은 이미 존재할 수도 있고 이때 생성될 수도 있습니다). 두 번째는 인증으로, 이 절차에서는 의존 당사자에게 등록된 사용자의 존재와 동의를 증명하는 인증 어설션이 제시됩니다. 기능적으로, Web Authentication API는 Credential Management API를 확장한 PublicKeyCredential과, 이러한 자격 증명을 navigator.credentials.create()navigator.credentials.get()으로 사용하게 해 주는 인프라로 구성됩니다. 전자는 등록 동안 사용되며, 후자는 인증 동안 사용됩니다.

전반적으로, 준수하는 인증기공개 키 자격 증명을 보호하고, 사용자 에이전트와 상호 작용하여 Web Authentication API를 구현합니다. 준수하는 인증기는 (a) 범용 컴퓨팅 장치에서 소프트웨어로 실행되거나, (b) 기기 내 보안 실행 환경, 신뢰할 수 있는 플랫폼 모듈(TPM) 또는 보안 요소(SE) 상에서 동작하거나, (c) 장치 외부에서 구현될 수 있습니다. 장치 내에서 구현되는 인증기를 플랫폼 인증기(platform authenticators)라 부릅니다. 장치 외부에서 구현되는 인증기(예: 로밍 인증기)는 USB, 블루투스 저에너지(BLE), 근거리 무선 통신(NFC)과 같은 전송 수단을 통해 접근할 수 있습니다.

1.1. 명세 로드맵

많은 W3C 명세서가 주로 사용자 에이전트 개발자와 웹 애플리케이션 개발자(즉, "웹 저자")를 대상으로 하지만, Web Authentication의 특성상 이 명세서는 아래에 설명된 바와 같이 여러 대상이 올바르게 사용해야 합니다.

모든 대상은 먼저 § 1.2 사용 사례, § 1.3 샘플 API 사용 시나리오, 및 § 4 용어를 읽어야 하며, 전체 튜토리얼을 위해 [WebAuthnAPIGuide]도 참조해야 합니다. 그 밖에 이 문서의 의도된 주요 대상은 다음과 같습니다.

참고: Web Authentication API 자체와 함께, 이 명세서는 암호화 프로토콜WebAuthn/FIDO2 프로토콜—을 정의합니다. 이 프로토콜은 WebAuthn 의존 당사자 서버와 인증기 사이의 요청-응답 프로토콜로, 의존 당사자의 요청은 챌린지 및 의존 당사자가 제공하는 기타 입력 데이터로 구성되어 인증기로 전송됩니다. 이 요청은 HTTPS, 의존 당사자웹 애플리케이션, WebAuthn API, 그리고 사용자 에이전트와 인증기 간의 플랫폼별 통신 경로의 조합을 통해 전달됩니다. 인증기는 디지털 서명된 인증기 데이터 메시지 및 기타 출력 데이터를 응답으로 보내며, 이는 역방향 경로를 통해 의존 당사자 서버로 전달됩니다. 프로토콜 세부사항은 인증인지 등록인지에 따라 달라집니다. 그림은 그림 1그림 2를 참조하세요.

Web Authentication 배포의 종단 간 보안을 위해 각 구성 요소—의존 당사자 서버, 클라이언트, 및 인증기—의 역할과 § 13 보안 고려사항§ 14 개인정보 고려사항을 모든 대상이 이해하는 것이 중요합니다.

1.2. 사용 사례

아래 사용 사례 시나리오는 두 가지 매우 다른 유형의 인증기와 두 가지 일반적인 배포 유형에서의 자격 증명 사용을 설명하고, 추가 시나리오의 개요도 제공합니다. 추가 시나리오(샘플 코드 포함)는 이후 § 1.3 샘플 API 사용 시나리오에 제시되어 있습니다. 이 예제들은 예시용일 뿐이며, 기능 가용성은 클라이언트 및 인증기 구현에 따라 다를 수 있습니다.

1.2.1. 다중 장치 자격 증명을 사용하는 소비자

이 사용 사례는 소비자 중심의 의존 당사자가 사용자의 장치에 내장된 인증기를 활용하여 다중 장치 자격 증명(일반적으로 동기화된 패스키라고 함)을 사용한 피싱 저항 로그인 제공 방법을 보여줍니다.

1.2.1.1. 등록
1.2.1.2. 인증

1.2.2. 단일 장치 자격 증명을 사용하는 인력

이 사용 사례는 인력 중심의 의존 당사자가 USB 보안 키와 같은 로밍 인증기와 내장 지문 센서와 같은 플랫폼 인증기의 조합을 활용하여 사용자가 다음을 가질 수 있도록 하는 방법을 보여줍니다:

1.2.2.1. 등록

이 예에서는 사용자의 고용주가 장치 바인딩된 패스키로 미리 구성된 보안 키를 우편으로 보냅니다.

임시 PIN이 채널 밖(예: RCS 메시지 등)을 통해 사용자에게 전송되었습니다.

1.2.2.2. 인증

1.2.3. 기타 사용 사례 및 구성

다음과 같은 다양한 추가 사용 사례 및 구성도 가능합니다(예시는 제한되지 않음):

1.3. 샘플 API 사용 시나리오

이 섹션은 규범적인 내용이 아닙니다.

이 섹션에서는 공개 키 자격 증명의 수명 주기에서 발생하는 몇 가지 이벤트와 이 API를 사용하는 해당 샘플 코드를 살펴봅니다. 이는 예시 흐름이며 API 사용 범위를 제한하지 않습니다.

이전 섹션과 마찬가지로, 이 흐름은 자체 디스플레이가 있는 패스키 로밍 인증기를 사용하는 사용 사례에 초점을 맞춥니다. 이러한 인증기의 예로는 스마트폰이 있습니다. 다른 인증기 유형도 이 API에 의해 지원되며 이는 클라이언트 플랫폼의 구현에 따라 달라집니다. 예를 들어, 이 흐름은 클라이언트 장치에 내장된 인증기의 경우에도 수정 없이 작동합니다. 자체 디스플레이가 없는 인증기(스마트 카드와 유사한)의 경우에도 특정 구현 고려사항이 충족되면 흐름이 작동합니다. 구체적으로, 클라이언트 플랫폼은 인증기가 표시했을 프롬프트를 대신 표시해야 하고, 인증기는 클라이언트 플랫폼이 모든 인증기 자격 증명을 열거할 수 있도록 허용해야 하여 클라이언트가 적절한 프롬프트를 표시할 정보를 가질 수 있어야 합니다.

1.3.1. 등록

이것은 최초 흐름으로, 새 자격 증명이 생성되어 서버에 등록됩니다. 이 흐름에서 WebAuthn 의존 당사자는 플랫폼 인증기(platform authenticators)나 로밍 인증기(roaming authenticators) 중 특정 선호를 갖지 않습니다.

  1. 사용자가 example.com을 방문하면 스크립트를 제공합니다. 이 시점에서 사용자는 이미 기존 사용자 이름과 비밀번호 또는 추가 인증기 등 의존 당사자가 허용하는 다른 수단으로 로그인했을 수 있으며, 또는 새 계정을 생성하는 중일 수 있습니다.

  2. 의존 당사자 스크립트가 아래 코드 스니펫을 실행합니다.

  3. 클라이언트 플랫폼이 인증기를 검색하고 찾습니다.

  4. 클라이언트가 필요한 경우 페어링 동작을 수행하면서 인증기에 연결합니다.

  5. 인증기는 사용자에게 생체 인식 또는 다른 권한 제스처를 제공하라는 적절한 UI를 표시합니다.

  6. 인증기는 클라이언트에 응답을 반환하며, 클라이언트는 다시 의존 당사자 스크립트에 응답을 반환합니다. 사용자가 인증기 선택을 거부하거나 권한 제공을 거부한 경우 적절한 오류가 반환됩니다.

  7. 새 자격 증명이 생성된 경우,

    • 의존 당사자 스크립트는 새로 생성된 자격 증명 공개 키를 서버에 전송하며, 인증기의 출처 및 특성에 관한 증명(attestation)과 같은 추가 정보를 함께 보냅니다.

    • 서버는 자격 증명 공개 키를 데이터베이스에 저장하고 이를 사용자 및 증명에서 나타난 인증 특성과 연관시키며, 나중에 사용할 친숙한 이름도 저장합니다.

    • 스크립트는 향후 사용자 경험을 개선하기 위해 자격 증명 ID와 같은 데이터를 로컬 스토리지에 저장할 수 있습니다.

새 키를 생성하고 등록하는 샘플 코드는 다음과 같습니다:

if (!window.PublicKeyCredential) { /* 클라이언트가 지원하지 않습니다. 오류를 처리하십시오. */ }

var publicKey = {
  // 챌린지는 서버에서 생성됩니다; 보안 고려 사항을 참조하세요
  challenge: new Uint8Array([21,31,105 /* 서버에서 생성된 29개의 추가 임의 바이트 */]),

  // 신뢰 당사자:
  rp: {
    name: "ACME Corporation"
  },

  // 사용자:
  user: {
    id: Uint8Array.from(window.atob("MIIBkzCCATigAwIBAjCCAZMwggE4oAMCAQIwggGTMII="), c=>c.charCodeAt(0)),
    name: "alex.mueller@example.com",
    displayName: "Alex Müller",
  },

  // 이 신뢰 당사자는 EdDSA, ES256, RS256 자격 증명 중 하나를 허용하며,
  // EdDSA 자격 증명을 우선적으로 사용합니다.
  pubKeyCredParams: [
    {
      type: "public-key",
      alg: -8 // "EdDSA"는 IANA COSE 알고리즘 레지스트리에 등록됨
    },
    {
      type: "public-key",
      alg: -7 // "ES256"은 IANA COSE 알고리즘 레지스트리에 등록됨
    },
    {
      type: "public-key",
      alg: -257 // "RS256"은 본 명세서에 의해 등록된 값
    }
  ],

  authenticatorSelection: {
    // 가능하다면 UV를 사용하려고 시도합니다. 이것이 기본값입니다.
    userVerification: "preferred"
  },

  timeout: 300000,  // 5분
  excludeCredentials: [
    // 이 자격 증명 중 하나가 있는 인증기는 다시 등록하지 않습니다
    {"id": Uint8Array.from(window.atob("ufJWp8YGlibm1Kd9XQBWN1WAw2jy5In2Xhon9HAqcXE="), c=>c.charCodeAt(0)), "type": "public-key"},
    {"id": Uint8Array.from(window.atob("E/e1dhZc++mIsz4f9hb6NifAzJpF1V4mEtRlIPBiWdY="), c=>c.charCodeAt(0)), "type": "public-key"}
  ],

  // excludeCredentials 검사를 U2F로 등록된 자격 증명까지 이전 호환성 지원
  extensions: {"appidExclude": "https://acme.example.com"}
};

// 참고: 아래 호출로 인증기에 UI가 표시됩니다.
navigator.credentials.create({ publicKey })
  .then(function (newCredentialInfo) {
    // 새 자격 증명 정보를 서버로 전송하여 검증 및 등록합니다.
  }).catch(function (err) {
    // 적합한 인증기가 없거나 사용자가 동의를 거부했습니다. 적절하게 처리하십시오.
  });

1.3.2. 사용자 검증 플랫폼 인증기를 사용한 등록 예시

이 예시는 WebAuthn 의존 당사자가 특히 공개 키 자격 증명사용자 검증 플랫폼 인증기으로 생성하는 데 관심이 있을 때의 흐름입니다.

  1. 사용자가 example.com을 방문하고 로그인 버튼을 클릭하면 login.example.com으로 리디렉션됩니다.

  2. 사용자가 사용자 이름과 비밀번호로 로그인합니다. 로그인 성공 후 사용자는 다시 example.com으로 리디렉션됩니다.

  3. 의존 당사자 스크립트가 아래 코드 스니펫을 실행합니다.

    1. 사용자 에이전트는 사용자 검증 플랫폼 인증기가 사용 가능한지 확인합니다. 사용 불가능하면 이 흐름을 종료합니다.

    2. 의존 당사자는 사용자에게 함께 자격 증명을 생성할지 묻습니다. 원치 않으면 흐름을 종료합니다.

    3. 사용자 에이전트 및/또는 운영체제는 적절한 UI를 표시하고 사용자가 사용 가능한 플랫폼 인증기 중 하나를 사용하여 자격 증명을 생성하도록 안내합니다.

    4. 자격 증명 생성에 성공하면 의존 당사자 스크립트는 새 자격 증명을 서버로 전달합니다.

if (!window.PublicKeyCredential) { /* Client not capable of the API. Handle error. */ }

PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable()
    .then(function (uvpaAvailable) {
        // If there is a user-verifying platform authenticator
        if (uvpaAvailable) {
            // Render some RP-specific UI and get a Promise for a Boolean value
            return askIfUserWantsToCreateCredential();
        }
    }).then(function (userSaidYes) {
        // If there is a user-verifying platform authenticator
        // AND the user wants to create a credential
        if (userSaidYes) {
            var publicKeyOptions = { /* Public key credential creation options. */};
            return navigator.credentials.create({ "publicKey": publicKeyOptions });
        }
    }).then(function (newCredentialInfo) {
        if (newCredentialInfo) {
            // Send new credential info to server for verification and registration.
        }
    }).catch(function (err) {
        // Something went wrong. Handle appropriately.
    });

1.3.3. 인증

이것은 이미 등록된 자격 증명을 가진 사용자가 웹사이트를 방문하여 해당 자격 증명으로 인증하려는 흐름입니다.

  1. 사용자가 example.com을 방문하면 스크립트를 제공합니다.

  2. 스크립트는 가능한 한 많은 정보를 제공하여 사용자에 대해 허용 가능한 자격 증명의 선택을 좁히기 위해 클라이언트에게 인증 어설션을 요청합니다. 이 정보는 등록 후 로컬에 저장된 데이터나 사용자에게 사용자 이름을 묻는 등의 다른 수단으로 얻을 수 있습니다.

  3. 의존 당사자 스크립트가 아래 코드 스니펫 중 하나를 실행합니다.

  4. 클라이언트 플랫폼이 인증기를 검색하고 찾습니다.

  5. 클라이언트가 필요한 경우 페어링 동작을 수행하면서 인증기에 연결합니다.

  6. 인증기는 사용자의 주의가 필요하다는 알림을 표시합니다. 알림을 열면 사용자는 자격 증명을 생성할 때 제공된 계정 정보를 사용하여 허용 가능한 자격 증명의 친숙한 선택 메뉴와, 이러한 키를 요청하는 오리진에 대한 일부 정보를 보게 됩니다.

  7. 인증기는 사용자로부터 생체 인식 또는 다른 권한 제스처를 얻습니다.

  8. 인증기는 클라이언트에 응답을 반환하고, 클라이언트는 다시 의존 당사자 스크립트에 응답을 반환합니다. 사용자가 자격 증명 선택을 거부하거나 권한 제공을 거부한 경우 적절한 오류가 반환됩니다.

  9. 어설션이 성공적으로 생성되어 반환된 경우,

    • 스크립트는 어설션을 서버로 보냅니다.

    • 서버는 어설션을 검사하여 자격 증명 ID를 추출하고, 데이터베이스에서 등록된 자격 증명 공개 키를 찾아 어설션 서명을 검증합니다. 유효한 경우, 어설션의 자격 증명 ID에 연관된 신원을 찾아 그것을 인증된 것으로 간주합니다. 만약 자격 증명 ID가 서버에서 인식되지 않으면(예: 비활성으로 인해 등록 해제된 경우) 인증은 실패합니다; 각 의존 당사자는 이를 자체 방식으로 처리합니다.

    • 서버는 이제 인증 성공 시 수행할 작업(성공 페이지 반환, 인증 쿠키 설정 등)을 수행합니다.

만약 의존 당사자 스크립트가 로컬에 저장된 데이터 등과 같이 자격 증명 목록을 좁히는 힌트를 갖고 있지 않다면, 인증을 수행하는 샘플 코드는 다음과 같을 수 있습니다:

if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }

// credentialId is generated by the authenticator and is an opaque random byte array
var credentialId = new Uint8Array([183, 148, 245 /* more random bytes previously generated by the authenticator */]);
var options = {
  // The challenge is produced by the server; see the Security Considerations
  challenge: new Uint8Array([4,101,15 /* 29 more random bytes generated by the server */]),
  timeout: 300000,  // 5 minutes
  allowCredentials: [{ type: "public-key", id: credentialId }]
};

navigator.credentials.get({ "publicKey": options })
    .then(function (assertion) {
    // Send assertion to server for verification
}).catch(function (err) {
    // No acceptable credential or user refused consent. Handle appropriately.
});

반면, 의존 당사자 스크립트가 자격 증명 목록을 좁히는 데 도움이 되는 힌트를 가지고 있다면, 다음과 같은 샘플 코드가 될 수 있습니다. 이 샘플은 자격 증명 속성 확장을 사용하는 방법도 보여줍니다.

if (!window.PublicKeyCredential) { /* Client not capable. Handle error. */ }

var encoder = new TextEncoder();
var acceptableCredential1 = {
    type: "public-key",
    id: encoder.encode("BA44712732CE")
};
var acceptableCredential2 = {
    type: "public-key",
    id: encoder.encode("BG35122345NF")
};

var options = {
  // The challenge is produced by the server; see the Security Considerations
  challenge: new Uint8Array([8,18,33 /* 29 more random bytes generated by the server */]),
  timeout: 300000,  // 5 minutes
  allowCredentials: [acceptableCredential1, acceptableCredential2],
  extensions: { 'credProps': true }
};

navigator.credentials.get({ "publicKey": options })
    .then(function (assertion) {
    // Send assertion to server for verification
}).catch(function (err) {
    // No acceptable credential or user refused consent. Handle appropriately.
});

1.3.4. 인증 작업 중단

아래 예시는 개발자가 AbortSignal 매개변수를 사용하여 자격 증명 등록 작업을 중단하는 방법을 보여줍니다. 인증 작업에도 유사한 절차가 적용됩니다.

const authAbortController = new AbortController();
const authAbortSignal = authAbortController.signal;

authAbortSignal.onabort = function () {
    // Once the page knows the abort started, inform user it is attempting to abort.
}

var options = {
    // A list of options.
}

navigator.credentials.create({
    publicKey: options,
    signal: authAbortSignal})
    .then(function (attestation) {
        // Register the user.
    }).catch(function (error) {
        if (error.name === "AbortError") {
            // Inform user the credential hasn't been created.
            // Let the server know a key hasn't been created.
        }
    });

// Assume widget shows up whenever authentication occurs.
if (widget == "disappear") {
    authAbortController.abort();
}

1.3.5. 운영 중지(Decommissioning)

다음은 자격 증명 운영 중지(제거)를 원할 수 있는 가능한 상황들입니다. 이 모든 상황은 서버 측에서 처리되며 여기 지정된 API의 지원을 필요로 하지 않습니다.

1.4. 플랫폼별 구현 지침

이 명세서는 일반적인 사례에서 Web Authentication을 사용하는 방법을 정의합니다. 특정 플랫폼 지원(예: 앱)과 연계하여 Web Authentication을 사용할 때는 추가 지침과 제한 사항에 대해서는 플랫폼별 문서와 가이드를 참조하는 것이 권장됩니다.

2. 준수

이 명세서는 세 가지 준수 클래스(conformance classes)를 정의합니다. 이들 각 클래스는 해당 클래스의 준수 구성원이 다른 클래스의 비준수 또는 적대적 구성원에 대해 안전하도록 지정되어 있습니다.

2.1. 사용자 에이전트

사용자 에이전트는 준수로 간주되기 위해 § 5 Web Authentication API에 설명된 대로 동작해야 합니다. 준수하는 사용자 에이전트는 이 명세서에 제시된 알고리즘을 원하는 방식으로 구현할 수 있지만, 최종 결과는 명세서의 알고리즘으로 얻을 수 있는 결과와 구별되지 않아야 합니다.

준수하는 사용자 에이전트는 또한 이 명세서의 IDL 단편을 준수하는 구현이어야 하며, 이는 "Web IDL" 명세에 설명되어 있습니다. [WebIDL]

2.1.1. DOMString 유형으로서의 열거형 호환성

열거형 타입은 Web IDL의 다른 부분에서 참조되지 않는데, 이는 명세서와 구현을 업데이트하지 않고 다른 값을 사용하는 것을 금지하게 되기 때문입니다. 이전 호환성을 위해 클라이언트 플랫폼의존 당사자는 알려지지 않은 값을 처리해야 합니다. 이 명세서의 열거형은 문서화 및 레지스트리 용도로 존재합니다. 열거형이 다른 곳에 표현될 때는 DOMString으로 타입이 지정됩니다. 예를 들어 transports와 같이.

2.2. 인증기

WebAuthn 인증기§ 6 WebAuthn 인증기 모델에 정의된 작업을 제공해야 하며, 그 동작은 해당 섹션에 설명된 대로 동작해야 합니다. 이는 인증기가 준수하는 사용자 에이전트에 의해 사용 가능하도록 하기 위한 기능적 및 보안 요건의 집합입니다.

§ 1.2 사용 사례에 설명된 바와 같이, 인증기는 사용자 에이전트의 기반이 되는 운영체제에 구현될 수도 있고, 외부 하드웨어에 또는 둘의 조합으로 구현될 수도 있습니다.

2.2.1. FIDO U2F와의 하위 호환성

인증기가 오직 § 8.6 FIDO U2F 증명 문장 형식만을 지원하는 경우, 사용자 핸들(user handle)을 저장할 메커니즘이 없으므로 반환되는 userHandle은 항상 null이 됩니다.

2.3. WebAuthn 의존 당사자

WebAuthn 의존 당사자는 이 명세서가 제공하는 모든 보안 혜택을 얻기 위해 § 7 WebAuthn 의존 당사자 작업에 설명된 대로 동작해야 합니다. 자세한 논의는 § 13.4.1 WebAuthn 의존 당사자를 위한 보안 혜택을 참조하세요.

2.4. 모든 준수 클래스

위의 준수 클래스 구성원들이 수행하는 모든 CBOR 인코딩은 CBOR 표준에 따라 CTAP2 표준의 정형화된(Canonical) CBOR 인코딩 형식을 사용하여 수행되어야 합니다. 위 준수 클래스의 모든 디코더는 CTAP2 정형화 CBOR 인코딩 형식으로 유효하게 인코딩되지 않은 CBOR을 거부해야 하며, 중복 맵 키가 있는 메시지도 거부하는 것이 권장됩니다.

3. 종속성

이 명세서는 아래 및 참조로 정의된 용어에 나열된 여러 다른 기본 명세들에 의존합니다.

Base64url encoding

용어 Base64url Encoding[RFC4648]의 섹션 5에 정의된 URL 및 파일명 안전 문자 집합을 사용하는 base64 인코딩을 가리키며, 모든 꼬리의 '=' 문자는(섹션 3.2에서 허용된 대로) 생략되고 줄바꿈, 공백 또는 기타 추가 문자가 포함되지 않은 것을 의미합니다.

CBOR

이 명세서의 여러 구조(증명 문장 및 확장 등)는 Compact Binary Object Representation(CBOR)의 CTAP2 정형화(Canonical) CBOR 인코딩 형식으로 인코딩됩니다. CBOR 자체는 [RFC8949][FIDO-CTAP]에 정의되어 있습니다.

CDDL

이 명세서는 모든 CBOR 인코딩 데이터를 기술하기 위해 CBOR Data Definition Language(CDDL)를 사용하며, 이는 [RFC8610]에 정의되어 있습니다.

COSE

CBOR Object Signing and Encryption(COSE) 관련 규격으로는 [RFC9052][RFC9053]가 있습니다. 또한 IANA COSE Algorithms 레지스트리([IANA-COSE-ALGS-REG])는 원래 [RFC8152]에 의해 설립되었고 이들 규격들에 의해 갱신되어 사용됩니다.

Credential Management

이 문서에 설명된 API는 Credential 개념을 정의한 [CREDENTIAL-MANAGEMENT-1]의 확장입니다.

DOM

DOMException 및 이 명세서에서 사용하는 DOMException 값들은 [DOM4]에 정의되어 있습니다.

ECMAScript

%ArrayBuffer%[ECMAScript]에 정의되어 있습니다.

URL

domain, host, port, scheme, valid domainvalid domain string과 같은 개념들은 [URL]에 정의되어 있습니다.

Web IDL

이 명세서의 많은 인터페이스 정의와 모든 IDL은 [WebIDL]에 의존합니다. 이 업데이트된 Web IDL 표준은 이제 비동기 상호작용을 위한 우선 메커니즘인 Promise에 대한 지원을 추가합니다.

FIDO AppID

호출 애플리케이션의 FacetID 결정호출자의 FacetID가 AppID에 대해 권한이 있는지 결정하는 알고리즘(앱ID 확장에서만 사용)은 [FIDO-APPID]에 정의되어 있습니다.

문서 내에서 대문자로만 나타나는 경우(여기와 같이) "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY" 및 "OPTIONAL"과 같은 핵심 단어들은 BCP 14의 규정에 따라 해석됩니다. 자세한 내용은 [RFC2119][RFC8174]를 참조하세요.

4. 용어

증명(Attestation)

일반적으로 attestation(증명)은 증언하거나 확인하거나 인증함을 의미합니다. WebAuthn 맥락에서 증명인증기와 그것이 생성하는 데이터의 출처에 대한 검증 가능한 증거를 제공하는 데 사용됩니다. 여기에는 자격 증명 ID, 자격 증명 키 쌍, 서명 카운터 등과 같은 항목이 포함됩니다.

증명 문장(attestation statement)증명 객체 내에서 등록 절차 동안 제공됩니다. 또한 § 6.5 증명그림 6도 참고하세요. 클라이언트증명 문장aaguid 부분을 의존 당사자에게 어떻게 전달하는지는 증명 전달 방식에서 설명합니다.

증명 인증서(Attestation Certificate)

증명 키 쌍에 대한 X.509 인증서로, 인증기가 제조 및 기능을 증명하기 위해 사용합니다. 등록 시점에 인증기증명 비밀 키로 생성하여 반환하는 의존 당사자 특정 자격 증명 공개 키(및 추가 데이터)에 서명합니다. 의존 당사자증명 인증서에 담긴 증명 공개 키을 사용하여 증명 서명을 검증합니다. 자체 증명(self attestation)의 경우에는 인증기가 별도의 증명 키 쌍이나 증명 인증서를 가지지 않는 점을 참조하세요(self attestation 참조).

인증(Authentication)
인증 절차(Authentication Ceremony)

사용자와 그 사용자의 클라이언트 플랫폼(하나 이상의 인증기를 포함하거나 연결함)이 협력하여 의존 당사자에게 사용자가 이전에 등록한 자격 증명 개인 키를 제어하고 있음을 암호학적으로 증명하는 절차를 말합니다(등록 참조). 여기에는 사용자 존재 확인 또는 사용자 검증이 포함됩니다.

WebAuthn 인증 절차§ 7.2 인증 어설션 검증에 정의되어 있으며, 의존 당사자navigator.credentials.get()publicKey 인수와 함께 호출하여 시작됩니다. 도입부는 § 5 Web Authentication API를 참조하고, 구현 예시는 § 1.3.3 인증을 참조하세요.

인증 어설션(Authentication Assertion)
어설션(Assertion)

AuthenticatorAssertionResponse 객체는 인증기authenticatorGetAssertion 작업의 결과로 반환하는 암호학적으로 서명된 응답입니다.

이는 [CREDENTIAL-MANAGEMENT-1] 명세서의 일회용 credentials와 대응됩니다.

인증기(Authenticator)
WebAuthn 인증기

하드웨어 또는 소프트웨어로 존재하는 암호학적 엔터티로서, 특정 의존 당사자에 대해 사용자를 등록하고 이후에 등록된 공개 키 자격 증명의 소유를 증명할 수 있으며, 선택적으로 사용자를 검증하여 의존 당사자에게 전달할 수 있습니다. 인증기는 등록 시 및 어설션 시 증명을 통해 자신의 유형 및 보안 특성에 관한 정보를 보고할 수 있습니다.

WebAuthn Authenticator로밍 인증기, 클라이언트 장치에 통합된 전용 하드웨어 서브시스템, 또는 클라이언트클라이언트 장치의 소프트웨어 구성요소일 수 있습니다. WebAuthn 인증기는 지역적 맥락에서만 동작하도록 제한되지 않으며, 클라이언트 측 하드웨어 외부의 서버에 자격 증명 키 쌍을 생성하거나 저장할 수 있습니다.

일반적으로 인증기는 하나의 사용자만 갖는 것으로 가정됩니다. 여러 자연인이 하나의 인증기에 대한 접근을 공유하는 경우, 해당 자연인들은 그 인증기의 맥락에서는 동일한 사용자로 간주됩니다. 만약 인증기 구현이 분리된 구획에서 다수의 사용자를 지원하면, 각 구획은 다른 사용자의 자격 증명에 접근할 수 없는 단일 사용자로서 별개의 인증기로 간주됩니다.

권한 제스처(Authorization Gesture)

권한 제스처절차의 일부로 사용자가 인증기와 수행하는 물리적 상호작용을 의미하며, 예를 들어 등록 또는 인증과 같은 절차에서 사용됩니다. 이러한 권한 제스처를 수행함으로써 사용자는 사용자 동의를 제공합니다(즉, 절차의 진행을 허가합니다). 이는 인증기가 가능하면 사용자 검증을 포함할 수 있으며, 또는 단순한 사용자 존재 테스트일 수 있습니다.

백업됨(Backed Up)

공개 키 자격 증명 소스는 생성 인증기 이외의 인증기에서 나타날 수 있도록 어떤 방식으로든 백업될 수 있습니다. 백업은 피어 투 피어 동기화, 클라우드 동기화, 로컬 네트워크 동기화, 수동 내보내기/가져오기 등 여러 메커니즘을 통해 발생할 수 있습니다. 자세한 내용은 § 6.1.3 자격 증명 백업 상태를 참조하세요.

백업 허용성(Backup Eligibility)
백업 가능(Backup Eligible)

Public Key Credential Source의 생성 시점에 생성 인증기가 해당 공개 키 자격 증명 소스가 백업될 수 있는지 여부를 결정합니다. 백업 허용성은 인증기 데이터플래그와 현재 백업 상태에 의해 신호됩니다. 백업 허용성은 자격 증명 속성이며 주어진 공개 키 자격 증명 소스에 대해 영구적입니다. 백업 가능인 공개 키 자격 증명 소스는 다중 장치 자격 증명(multi-device credential)이라 부르며, 백업 불가능한 것은 단일 장치 자격 증명(single-device credential)이라 부릅니다. 자세한 내용은 § 6.1.3 자격 증명 백업 상태를 참조하세요.

백업 상태(Backup State)

현재 다중 장치 자격 증명의 백업 상태는 현재 관리 인증기(managing authenticator)에 의해 결정됩니다. 백업 상태는 인증기 데이터플래그로 신호되며 시간이 지나면서 변경될 수 있습니다. 또한 백업 허용성§ 6.1.3 자격 증명 백업 상태를 참조하세요.

생체 인증기(Biometric Authenticator)

생체 인식(biometric recognition)을 구현하는 모든 인증기를 말합니다.

생체 인식(Biometric Recognition)

개인의 생물학적·행동적 특징을 기반으로 한 자동 인식입니다([ISOBiometricVocabulary]).

바인딩된 자격 증명(Bound credential)
"Authenticator contains a credential"
"Credential created on an authenticator"

공개 키 자격 증명 소스 또는 공개 키 자격 증명은 그 관리 인증기바인딩(bound)되어 있다고 합니다. 이는 오직 그 관리 인증기만이 그에 바인딩된 어설션을 생성할 수 있음을 의미합니다.

이를 "관리 인증기(managing authenticatorcontains 바인딩된 자격 증명을 포함한다)" 또는 "바인딩된 자격 증명이 그 관리 인증기에서 생성되었다(created on)"고 표현할 수 있습니다. 다만 서버 측 자격 증명은 인증기 내부의 영구 메모리에 물리적으로 저장되지 않을 수 있으므로, "바인딩된(bound to)"이 기본 용어입니다. 자세한 내용은 § 6.2.2 자격 증명 저장 방식을 참조하세요.

절차(Ceremony)

절차 개념은 인간 노드와 컴퓨터 노드가 함께 작동하고 사용자 인터페이스, 사람 간 통신, 데이터가 포함된 물리적 객체의 전달을 포함하는 통신 링크를 갖는 네트워크 프로토콜 개념의 확장입니다. 프로토콜에서는 아웃-오브-밴드인 것이 절차에서는 인-밴드일 수 있습니다. 이 명세서에서 등록인증은 절차이며, 권한 제스처는 종종 이러한 절차의 구성 요소입니다.

클라이언트(Client)
WebAuthn 클라이언트

여기서는 단순히 클라이언트라고도 합니다. 또한 준수하는 사용자 에이전트도 참조하세요. WebAuthn Client는 일반적으로 사용자 에이전트에 구현된 중개자 역할을 하며, 개념적으로는 Web Authentication API를 하부에서 구현하고 [[Create]](origin, options, sameOriginWithAncestors)[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 같은 내부 메서드를 구현합니다. 이는 하부의 인증기 연산에 대한 입력을 마샬링하고, 그 결과를 Web Authentication API의 호출자에게 반환하는 역할을 합니다.

WebAuthn ClientWebAuthn Client Device 상에서 실행되며, 이는 서로 구분됩니다.

클라이언트 장치(Client Device)
WebAuthn 클라이언트 장치

WebAuthn Client가 실행되는 하드웨어 장치, 예를 들어 스마트폰, 노트북 또는 데스크톱 컴퓨터와 그 하드웨어에서 실행되는 운영체제를 의미합니다.

WebAuthn Client device클라이언트의 구분은 다음과 같습니다:

하나의 클라이언트 장치클라이언트는 함께 클라이언트 플랫폼을 구성합니다.

클라이언트 플랫폼(Client Platform)

클라이언트 장치클라이언트가 함께 클라이언트 플랫폼을 이룹니다. 단일 하드웨어 장치는 서로 다른 운영체제 및/또는 클라이언트를 실행하여 서로 다른 시점에 여러 개의 별개의 클라이언트 플랫폼의 일부가 될 수 있습니다.

클라이언트 측(Client-Side)

일반적으로 이는 사용자의 클라이언트 플랫폼, 인증기 및 이를 모두 연결하는 모든 요소들의 결합을 의미합니다.

클라이언트 측 검색 가능한 공개 키 자격 증명 소스
클라이언트 측 검색 가능한 자격 증명
검색 가능한 자격 증명(Discoverable Credential)
패스키(Passkey)
[DEPRECATED] 거주 자격 증명(Resident Credential)
[DEPRECATED] 거주 키(Resident Key)

참고: 역사적으로, 클라이언트 측 검색 가능한 크리덴셜거주(레지던트) 크리덴셜 또는 거주(레지던트) 키로도 알려져 있습니다. ResidentKeyresidentKey라는 용어는 WebAuthn APIAuthenticator Model 모두에서 (예: 딕셔너리 멤버 이름, 알고리즘 변수명, 연산 파라미터 등) 널리 사용되고 있으므로, 이름에 resident라는 단어 사용은 하위 호환성을 위해 변경되지 않았습니다. 또한 이곳에서 거주 키(resident key)클라이언트 측 검색 가능한 크리덴셜과 동의어로 정의됩니다.

클라이언트 측 검색 가능한 공개키 크리덴셜 소스(영어 약칭: 검색 가능한 크리덴셜(Discoverable Credential))는, 검색 가능하며, 인증 절차에서 Relying Party가 어떠한 credential ID도 제공하지 않을 때 사용할 수 있는 public key credential source입니다. 즉, Relying Partynavigator.credentials.get() 호출 시 비어 있는 allowCredentials 인자를 주는 경우를 뜻합니다. 즉, Relying Party가 반드시 사용자를 먼저 식별할 필요가 없음을 의미합니다.

결과적으로, 검색 가능한 크리덴셜 지원 authenticator는 단지 RP ID만 주어져도 검색 가능한 크리덴셜에 대해 assertion signature를 생성할 수 있습니다. 이는 public key credential sourceauthenticator 또는 클라이언트 플랫폼에 저장되어 있어야 함을 뜻합니다. 이는 서버 측 공개키 크리덴셜 소스(Server-side Public Key Credential Source)와 대조적이며, 후자는 authenticator에게 RP IDcredential ID가 모두 제공되어야 하지만 클라이언트 측public key credential source를 저장할 필요는 없습니다.

참조: 클라이언트 측 크리덴셜 저장 방식비검색형(non-discoverable) 크리덴셜도 참고하십시오.

참고: 클라이언트 측 검색 가능한 크리덴셜인증 절차에서 credential ID가 제공되는 경우(즉, navigator.credentials.get() 호출 시 비어 있지 않은 allowCredentials 인자와 함께 호출할 때)에도 사용할 수 있습니다.

준수하는 사용자 에이전트(Conforming User Agent)

하부의 클라이언트 장치와 협력하여 Web Authentication API 및 본 명세서에 주어진 알고리즘을 구현하고, 인증기의존 당사자 간 통신을 처리하는 사용자 에이전트를 말합니다.

자격 증명 ID(Credential ID)

확률적으로 고유한 바이트 시퀀스로서 공개 키 자격 증명 소스와 그에 따른 인증 어설션을 식별합니다. 길이는 최대 1023 바이트입니다.

자격 증명 ID는 인증기에 의해 두 가지 형태로 생성됩니다:

  1. 적어도 16바이트이며 최소 100비트의 엔트로피를 포함하는 경우, 또는

  2. 공개 키 자격 증명 소스 자체를, 그 안의 Credential IDmutable items를 제외한 채로 암호화하여 오직 해당 관리 인증기만 복호화할 수 있게 하는 형태. 이 형태는 인증기를 거의 상태 비저장(state-light)으로 만들 수 있으며, 필요한 상태는 의존 당사자가 저장합니다.

    참고: [FIDO-UAF-AUTHNR-CMDS]는 "Security Guidelines"에서 암호화 기법에 대한 지침을 포함합니다.

의존 당사자는 이 두 가지 자격 증명 ID 형태를 구분할 필요가 없습니다.

자격 증명 키 쌍(Credential Key Pair)
자격 증명 개인 키(Credential Private Key)
자격 증명 공개 키(Credential Public Key)
사용자 공개 키(User Public Key)

자격 증명 키 쌍인증기에 의해 생성되며 특정 WebAuthn 의존 당사자에게 범위 지정됩니다. 이는 공개 키 자격 증명의 핵심 요소입니다.

자격 증명 공개 키는 자격 증명 키 쌍의 공개 키 부분입니다. 이 자격 증명 공개 키등록 절차 중에 의존 당사자에게 반환됩니다.

자격 증명 개인 키는 자격 증명 키 쌍의 개인 키 부분입니다. 자격 증명 개인 키는 특정 인증기 - 즉 그 관리 인증기에 바인딩되며, 소유자나 인증기 자체에도 노출되어서는 안 됩니다.

자체 증명(self attestation)의 경우에는 자격 증명 키 쌍증명 키 쌍으로도 사용된다는 점을 참조하세요(self attestation 참조).

참고: 자격 증명 공개 키는 FIDO UAF의 [UAFProtocol] 및 FIDO U2F의 [FIDO-U2F-Message-Formats]에서 'user public key'로 언급되며, 이 명세서의 일부 관련 부분에서도 동일하게 사용됩니다.

자격 증명 속성(Credential Properties)

자격 증명 속성은 해당 공개 키 자격 증명 소스의 특징적인 속성으로, 예를 들어 그것이 클라이언트 측 검색 가능한 자격 증명인지 또는 서버 측 자격 증명인지 등을 포함합니다.

자격 증명 레코드(Credential Record)

§ 7 WebAuthn 의존 당사자 작업에 정의된 알고리즘을 구현하기 위해, 의존 당사자는 등록된 공개 키 자격 증명 소스의 일부 속성을 저장해야 합니다. 자격 증명 레코드 struct는 이러한 속성들의 추상화입니다. 자격 증명 레코드는 등록 절차 동안 생성되며 이후의 인증 절차에서 사용됩니다. 의존 당사자는 필요하거나 사용자가 요청할 때 자격 증명 레코드를 삭제할 수 있습니다.

다음의 항목들§ 7.1 새 자격 증명 등록§ 7.2 인증 어설션 검증의 모든 단계를 구현하기 위해 권장됩니다:

type

해당 공개 키 자격 증명 소스type.

id

해당 공개 키 자격 증명 소스Credential ID.

publicKey

해당 공개 키 자격 증명 소스자격 증명 공개 키.

signCount

해당 공개 키 자격 증명 소스를 사용한 어떤 절차에서든지 반환된 인증기 데이터의 최신 서명 카운터 값입니다.

transports

getTransports() 호출 시 해당 공개 키 자격 증명 소스등록될 때 반환한 값입니다.

참고: getTransports()이 반환한 값에서 항목을 수정하거나 제거하면 사용자 경험에 부정적 영향을 주거나 해당 자격 증명의 사용을 방해할 수 있습니다.

uvInitialized

해당 credential 중 이 공개 키 자격 증명 소스에 대해 UV 플래그가 설정된 적이 있는지를 나타내는 불리언 값입니다.

이 값이 true이면 의존 당사자는 해당 UV 플래그인증 절차에서 인증 요소(authentication factor)로 간주할 수 있습니다. 예를 들어 의존 당사자uvInitializedtrue이고 UV 플래그가 설정되어 있으면 비록 사용자 검증이 요구되지 않았더라도 비밀번호 프롬프트를 건너뛸 수 있습니다.

이 값이 false인 경우(이를 true로 업데이트할 수 있는 인증 절차를 포함하여), UV 플래그authentication factor로 신뢰되어서는 안 됩니다. 이는 공개 키 자격 증명 소스가 처음으로 UV 플래그를 1로 설정했을 때, 아직 의존 당사자와 해당 인증기의 사용자 검증 사이에 신뢰 관계가 확립되지 않았기 때문입니다. 따라서 uvInitializedfalse에서 true로 업데이트할 때는 WebAuthn의 사용자 검증에 상응하는 추가적인 authentication factor에 의한 승인이 필요할 것을 권장합니다.

backupEligible

BE 플래그의 값으로, 해당 공개 키 자격 증명 소스가 생성될 때의 값을 나타냅니다.

backupState

해당 공개 키 자격 증명 소스를 사용하는 어떤 절차에서든지 반환된 인증기 데이터BS 플래그의 최신 값을 나타냅니다.

다음의 항목들은 선택사항(OPTIONAL)입니다:

attestationObject

해당 공개 키 자격 증명 소스등록될 때의 attestationObject 속성 값입니다. 이를 저장하면 의존 당사자가 이후에 자격 증명의 증명 문장을 참조할 수 있게 됩니다.

attestationClientDataJSON

해당 공개 키 자격 증명 소스등록될 때의 clientDataJSON 속성 값입니다. 이를 위의 attestationObject 항목과 함께 저장하면 의존 당사자가 나중에 증명 서명을 재검증할 수 있게 됩니다.

rpId

rp.id 파라미터 값은 자격 증명 등록 시 create() 작업에서 지정됩니다. 이 값은 자격 증명의 핵심 속성으로, 어디에서 사용할 수 있는지 결정합니다. 등록 시 이 값을 저장하면, 이후 사용 내역 감사, 인증 문제 해결, 또는 관련 오리진을 통해 다른 도메인에서 사용할 때 도움이 될 수 있습니다.

WebAuthn 확장은 확장을 처리하는 데 필요한 추가 항목들을 정의할 수 있습니다. 의존 당사자는 필요에 따라 추가적인 항목을 포함하거나 구현에 필요하지 않은 항목을 생략할 수 있습니다.

자격 증명 레코드에 대한 자격 증명 기술자(credential descriptor)는 다음 내용을 가진 PublicKeyCredentialDescriptor 값입니다:

type

해당 type of the credential record.

id

해당 id of the credential record.

transports

해당 transports of the credential record.

생성 인증기(Generating Authenticator)

생성 인증기(Generating Authenticator)는 특정 공개 키 자격 증명 소스의 생성을 초래하는 authenticatorMakeCredential 작업에 관여한 인증기입니다. 생성 인증기단일 장치 자격 증명의 경우 해당 자격 증명의 관리 인증기와 동일합니다. 다중 장치 자격 증명의 경우에는 생성 인증기가 현재 특정 인증 작업에 참여하는 관리 인증기와 같을 수도 있고 다를 수도 있습니다.

사람이 이해하기 쉬운 식별자(Human Palatability)

사람이 기억하고 재현하기 쉬운 식별자는 일반적으로 무작위로 생성된 비트 시퀀스와 달리 일반 사용자들이 기억하고 재현할 수 있도록 의도된 식별자입니다([EduPersonObjectClassSpec] 참조).

비검색 가능 자격 증명(Non-Discoverable Credential)

이것은 credential로서, 자격 증명 ID를 제공하여 allowCredentials 인수를 지정하고 navigator.credentials.get()을 호출해야 하는 자격 증명입니다. 이는 서버 측 자격 증명과 관련이 있습니다.

등록 가능한 오리진 레이블(Registrable Origin Label)

도메인의 도메인 레이블 중 첫 번째 레이블로서, 호스트의 등록 가능한 도메인의 첫 번째 레이블입니다. 등록 가능한 도메인이 null이면 null을 반환합니다. 예를 들어 example.co.ukwww.example.de의 등록 가능한 오리진 레이블은 각각 example입니다(단, co.ukde가 퍼블릭 서픽스일 때).

공개 키 자격 증명(Public Key Credential)

일반적으로 크리덴셜(credential)은 한 엔티티가 다른 엔티티에게 본인을 인증하기 위해 제시하는 데이터입니다 [RFC4949]. 공개키 크리덴셜(public key credential)이라는 용어는 다음 중 하나를 의미합니다: 공개키 크리덴셜 소스, attestation이 추가될 수도 있는 크리덴셜 공개키(credential public key)(이는 공개키 크리덴셜 소스와 대응됨), 또는 인증 어서션(authentication assertion). 어떤 의미인지는 일반적으로 문맥에 따라 결정됩니다.

참고: 이는 [RFC4949]의 정의에 대한 의도적 위반입니다. 영어에서 "credential"은 a) 어떤 진술을 증명하기 위해 제시되는 것과 b) 여러 번 사용될 목적으로 만들어진 것을 동시에 의미할 수 있습니다. 공개 키 시스템에서 단일 데이터가 두 가지 요건을 안전하게 만족시키는 것은 불가능합니다. [RFC4949]은 credential을 여러 번 사용될 수 있는 것(공개 키)으로 정의하지만, 이 명세서는 영어 용어의 유연성을 허용합니다. 이 명세서는 관련 데이터를 더 구체적인 용어로 구분합니다:
"Authentication information" (possibly including a private key)

Public key credential source

"Signed value"

Authentication assertion

[RFC4949] "credential"

Credential public key 또는 attestation object

등록 시점에 인증기는 비대칭 키 쌍을 생성하고 해당 의존 당사자로부터의 정보를 공개 키 자격 증명 소스에 저장합니다. 공개 키 부분의존 당사자에게 반환되며, 의존 당사자는 이를 활성 사용자 계정에 저장합니다. 이후 해당 의존 당사자는 그 등록된 자격 증명 공개 키를 사용하여 결과적인 인증 어설션을 검증합니다. 이 공개 키 자격 증명은 등록된 RP ID로 식별된 동일한 엔터티에서만 인증에 사용될 수 있습니다.

공개 키 자격 증명 소스(Public Key Credential Source)

credential source ([CREDENTIAL-MANAGEMENT-1])로서, 인증기인증 어설션을 생성하는 데 사용하는 것입니다. 공개 키 자격 증명 소스는 다음과 같은 struct항목들으로 구성됩니다:

type

값은 PublicKeyCredentialType이며, 기본값은 public-key입니다.

id

자격 증명 ID(Credential ID)입니다.

privateKey

자격 증명 개인 키입니다.

rpId

신뢰 당사자 식별자는, 이 공개키 자격 증명 소스범위로 지정된 신뢰 당사자의 것입니다. 이 값은 rp.id 매개변수 및 create() 작업에 의해 결정됩니다.

userHandle

공개 키 자격 증명 소스가 생성될 때 연결된 사용자 핸들입니다. 이 항목(item)은 null일 수도 있지만, 검색 가능한 자격 증명(discoverable credentials)의 경우 user handle이 항상 채워져 있어야 합니다.

otherUI

인증자(authenticator)가 UI에 정보를 제공할 때 사용하는 선택적 추가 정보입니다. 예를 들어 사용자의 displayName이 포함될 수 있습니다. otherUImutable item이며, 공개 키 자격 증명 소스에 업데이트 가능성을 저해하지 않도록 묶여서는 안 됩니다.

authenticatorMakeCredential 작업은 공개 키 자격 증명 소스특정 관리 인증자(managing authenticator)에 바인딩하여 생성하고, 그 자격 증명 공개키를 반환합니다. 이 공개키는 자격 증명 개인키와 연관되어 있습니다. 신뢰 당사자는 이 자격 증명 공개키를 사용하여 이 공개 키 자격 증명 소스가 만든 인증 어설션을 검증할 수 있습니다.

속도 제한(Rate Limiting)

속도 제한(일명 스로틀링)은 인증자가 연속된 인증 실패 시도 횟수를 제한함으로써 무차별 대입(brute force) 공격을 방지하기 위해 제어를 구현하는 역할입니다. 제한에 도달하면 인증자는 각 시도가 반복될수록 지연 시간을 기하급수적으로 증가시키거나, 현재 인증 방식을 비활성화하고 사용 가능한 경우 다른 인증 요소(authentication factor)를 표시해야 합니다. 속도 제한사용자 검증(user verification)의 일부로 자주 구현됩니다.

등록(Registration)
등록 절차(Registration Ceremony)

사용자, 신뢰 당사자, 그리고 사용자의 클라이언트 플랫폼(최소 하나 이상의 인증자를 포함하거나 연결된)이 함께 공개키 자격 증명을 생성하고 이를 사용자 계정에 연결하는 ceremony입니다. 여기에는 사용자 존재 테스트 또는 사용자 검증을 수행하는 것도 포함됩니다. 성공적으로 등록 절차를 마치면 사용자는 인증 절차를 통해 인증 받을 수 있습니다.

WebAuthn 등록 절차§ 7.1 새 자격 증명 등록에서 정의되며, 신뢰 당사자navigator.credentials.create() 작업을 publicKey 인자로 호출함으로써 시작됩니다. 입문 개요는 § 5 Web 인증 API에서, 구현 예시는 § 1.3.1 등록에서 확인할 수 있습니다.

신뢰 당사자(Relying Party)
WebAuthn 신뢰 당사자(WebAuthn Relying Party)

웹 애플리케이션의 주체로, Web Authentication API를 이용해 사용자를 등록인증합니다.

신뢰 당사자 구현은 보통 Web Authentication API를 호출하는 클라이언트 측 스크립트와 클라이언트신뢰 당사자 서버 동작 및 기타 애플리케이션 로직을 실행하는 서버 측 구성요소로 이루어집니다. 두 구성요소 간의 통신은 반드시 HTTPS 또는 이에 준하는 전송 보안으로 이루어져야 하며, 그 이외 사항은 본 명세의 범위를 벗어납니다.

참고: 신뢰 당사자 용어는 X.509나 OAuth 등 다른 맥락에서도 자주 쓰입니다. 하지만 한 맥락에서 신뢰 당사자로 동작한다고 해서 다른 맥락에서도 반드시 신뢰 당사자인 것은 아닙니다. 본 명세에서 WebAuthn 신뢰 당사자는 약칭으로 단순히 신뢰 당사자라고도 하며, WebAuthn 맥락의 신뢰 당사자를 명시적으로 지칭합니다. 실제로 WebAuthn 환경은 더 광범위한 맥락(예: OAuth 기반) 안에 내장될 수 있습니다.

신뢰 당사자 식별자(Relying Party Identifier)
RP ID

WebAuthn API 맥락에서, 신뢰 당사자 식별자유효 도메인 문자열로, 특정 등록 또는 인증 절차가 실행되는 WebAuthn 신뢰 당사자를 식별합니다. 공개 키 자격 증명은 최초 등록시의 같은 주체(RP ID로 구분)에 대해서만 인증에 사용할 수 있습니다.

기본적으로, WebAuthn 동작의 RP ID는 호출자의 origin유효 도메인으로 설정됩니다. 이 기본값은 호출자가 제공하는 RP ID 값이 호출자의 origin유효 도메인등록 가능한 도메인 접미사이거나 동일한 경우에 한해 대체할 수 있습니다. 자세한 내용은 § 5.1.3 새 자격 증명 생성 - PublicKeyCredential의 [[Create]](origin, options, sameOriginWithAncestors) 내부 메서드§ 5.1.4 기존 자격 증명을 사용한 어설션 생성을 참고하세요.

RP ID호스트도메인 이름을 기반으로 합니다. (origin과 달리) 자체적으로 스킴이나 포트를 포함하지 않습니다. 공개 키 자격 증명RP ID는 해당 자격 증명의 범위(scope)를 결정합니다. 다시 말해, 해당 공개 키 자격 증명을 사용할 수 있는 origin의 집합을 결정합니다:

예를 들어, origin이 https://login.example.com:1337신뢰 당사자의 경우, RP IDlogin.example.com(기본), example.com은 가능하지만, m.login.example.com, com은 허용되지 않습니다. 또 다른 예시로 http://localhost:8000도 origin이 localhost이므로 유효합니다.

이는 쿠키 등 널리 배포된 환경 자격 증명(ambient credentials, 예: [RFC6265])의 동작과 맞추기 위함입니다. 여기서의 처리 범위는 document.domain의 setter가 제공하는 "동일 출처"보다 완화되어 있음을 유의하세요.

이러한 origin 값 제한은 WebAuthn 클라이언트에 적용됩니다.

다른 규격에서 WebAuthn 공개 키 자격 증명을 네이티브 모바일 앱 등 Web 플랫폼 이외 환경에서 사용하도록 WebAuthn API와 유사하게 구현하는 경우에는, 호출자를 신뢰 당사자 식별자에 바인딩하는 규칙을 다르게 정의할 수 있습니다. 다만, RP ID 문법은 반드시 유효 도메인 문자열이나 URI([RFC3986] [URL]) 규격을 따라야 합니다.

서버 측 공개 키 자격 증명 소스(Server-side Public Key Credential Source)
서버 측 자격 증명(Server-side Credential)
[DEPRECATED] 비상주 자격 증명(Non-Resident Credential)

참고: 서버 측 자격 증명은 과거에는 비상주 자격 증명(non-resident credential)으로 알려졌습니다. 하위 호환성을 위해 WebAuthn APIAuthenticator Model 구성요소 중 resident 관련 이름은 변경되지 않았습니다.

서버 측 공개 키 자격 증명 소스 또는 약칭으로 서버 측 자격 증명공개 키 자격 증명 소스 중에서 오직 신뢰 당사자navigator.credentials.get()allowCredentials 인자로 그 자격 증명 ID를 제공할 때에만 인증 절차에서 사용할 수 있습니다. 즉, 신뢰 당사자가 자격 증명의 저장 및 식별 관리를 책임져야 하며, 사용자를 미리 식별해서 자격 증명 ID 목록을 제공할 수 있어야 합니다.

클라이언트 측에서 공개 키 자격 증명 소스를 저장하는 것은 서버 측 자격 증명에는 필요하지 않습니다. 반면, 클라이언트 측 검색 가능한 자격 증명(client-side discoverable credential)은 사용자를 미리 식별하지 않고도 자격 증명 IDnavigator.credentials.get() 인자에 제공할 수 있습니다.

참고: 서버 측 자격 증명 저장 방식(server-side credential storage modality)비검색 자격 증명(non-discoverable credential)도 참고하세요.

사용자 존재 테스트(Test of User Presence)

사용자 존재 테스트권한 부여 제스처(authorization gesture)의 한 형태이자, 사용자가 인증자와 단순히 접촉(다른 방식도 있음)하는 기술적 절차로, Boolean(참/거짓) 결과를 제공합니다. 이 테스트는 사용자 검증(user verification)에는 해당하지 않습니다. 사용자 존재 테스트는 본질적으로 생체 인식이 불가능하며, 공유 비밀번호나 PIN 등 비밀 입력도 포함하지 않습니다.

사용자 계정(User Account)

본 명세의 맥락에서 사용자 계정은 일련의 자격 증명 ([CREDENTIAL-MANAGEMENT-1])을 신뢰 당사자 소유의 일부 리소스에 매핑한 것으로, 신뢰 당사자에 의해 관리 및 허가됩니다. 신뢰 당사자공개 키 자격 증명에 대해 사용자 핸들을 할당하고, 자격 증명 기록(credential record)을 사용자 계정에 저장함으로써 자격 증명을 사용자 계정과 연결합니다. 이 매핑, 자격 증명 집합, 권한 정보는 시간이 지남에 따라 변할 수 있습니다. 사용자 계정 하나가 여러 자연인(게 사용자)에 의해 접근될 수도 있고, 한 자연인이 여러 사용자 계정에 접근할 수도 있습니다. 이는 사용자/신뢰 당사자 동작에 따라 달라질 수 있습니다.

사용자 동의(User Consent)

사용자 동의란 사용자가 요청받는 내용에 동의하는 것(예: 안내문을 읽고 이해함)을 의미합니다. 권한 부여 제스처절차(ceremony)의 한 부분으로, 사용자 동의(user consent)를 표시하는 데 자주 사용됩니다.

사용자 핸들(User Handle)

사용자 핸들은 사용자 계정의 식별자로, 신뢰 당사자 user. id 에 지정합니다(등록 때). 검색 가능한 자격 증명(discoverable credentials)은 이 식별자를 저장하고, 인증 절차(authentication ceremonies)에서, response. userHandle 에 반드시 반환해야 합니다. (단, allowCredentials 인자로 시작한 경우)

사용자 핸들의 주요 역할은 이러한 인증 절차에서 사용자 계정을 식별하는 것입니다. 자격 증명 ID도 사용할 수 있지만, 자격 증명 ID인증자가 정해 각 자격 증명마다 독립적이고, user handle신뢰 당사자가 지정해 같은 자격 증명 집합 모두에 동일하게 할당해야 한다는 점이 다릅니다.

인증자RP ID와 사용자 핸들의 쌍공개 키 자격 증명 소스에 매핑합니다. 이로 인해 인증자는 하나의 user handle신뢰 당사자별로 최다 하나의 검색 가능한 자격 증명만 저장합니다. 따라서 사용자 핸들인증자가 등록 절차(registration ceremony) 중 기존 검색 가능한 자격 증명을 새 것으로 교체해야 하는지 판단하는 데에도 사용됩니다.

사용자 핸들은 최대 64바이트 길이의 불투명한 바이트 시퀀스로, 사용자에게 표시해서는 안 됩니다. 개인정보 식별 정보가 포함되어선 안 되며, § 14.6.1 사용자 핸들 내용 참조.

사용자가 존재함(User Present)

사용자 존재 테스트가 성공적으로 완료되면 사용자가 "존재한다"고 간주합니다.

사용자 검증(User Verification)

인증자authenticatorMakeCredentialauthenticatorGetAssertion 동작 호출을 로컬에서 허가하는 기술적 과정입니다. 사용자 검증(user verification)은 다양한 권한 부여 제스처로 유도될 수 있습니다. 예를 들어 터치 후 PIN, 비밀번호 입력, 생체 인식(biometric recognition) 등 (지문 등) ([ISOBiometricVocabulary])이 목적입니다. 이는 개별 사용자의 식별을 구분하려는 의도를 갖습니다. 자세한 내용은 § 6.2.3 인증 요소 능력(Authentication Factor Capability) 참조.

사용자 검증만으로 신뢰 당사자가 사용자 본인을 정확히 식별할 수 있는 것은 아니지만, 똑같은 자격 증명으로 2회 이상 사용자 검증이 수행됐다면 항상 동일 사용자가 해당 과정을 실행했음을 표현합니다. 단, 하나의 인증자를 여러 자연인이 공유하면 논리적 동일 사용자와 실제 자연인이 반드시 일치하진 않습니다.

참고: 자연인 구분은 클라이언트 플랫폼인증자의 역량에 크게 달려 있습니다. 예를 들어, 단일 사용자가 쓰는 기기로 설계되었지만, 여러 자연인이 지문을 등록하거나 같은 PIN을 공유할 수 있는 경우라면 여러 계정(user account)에도 접근 가능할 수 있습니다.

참고: authenticatorMakeCredentialauthenticatorGetAssertion 호출은 인증자에서 관리하는 키 자료의 사용을 의미합니다.

보안을 위해, 사용자 검증자격 증명 개인키 사용은 모두 반드시 인증자가 정의하는 논리(적) 보안 경계 안에서 이루어져야 합니다.

사용자 검증 절차는 무차별 대입 공격에 대한 방어책으로 속도 제한(rate limiting)을 구현할 수 있습니다.

사용자 검증됨(User Verified)

사용자 검증 과정이 성공적으로 완료되면, 사용자가 "검증됨"으로 간주합니다.

5. 웹 인증 API

이 절에서는 공개 키 자격 증명을 생성하고 사용하는 API를 규범적으로 명세합니다. 기본 개념은 자격 증명이 사용자에게 속하고 인증기에 의해 관리되며, WebAuthn 인증기WebAuthn Relying Party클라이언트 플랫폼을 통해 상호작용한다는 것입니다. Relying Party 스크립트는 (사용자 동의(user’s consent)를 얻어) 브라우저에 Relying Party가 향후 사용할 새 자격 증명을 생성하도록 요청할 수 있습니다. 아래 그림 을 참조하세요.

등록 흐름

스크립트는 또한 기존 자격 증명으로 인증 작업을 수행하는 것에 대해 사용자의 허가를 요청할 수 있습니다. 아래 그림 을 참조하세요.

인증 흐름

이러한 모든 작업은 인증기에서 수행되며 사용자를 대신해 클라이언트 플랫폼에 의해 중개됩니다. 스크립트가 자격 증명 자체에 접근하는 일은 전혀 없으며, 오직 객체 형태로 된 자격 증명에 대한 정보만 받게 됩니다.

위의 스크립트 인터페이스 외에도, 인증기는 사용자 인터페이스를 구현(MAY)하거나 해당 기능을 구현하는 클라이언트 소프트웨어와 함께 제공될 수 있습니다. 이러한 인터페이스는 예를 들어 인증기를 초기 상태로 재설정하거나 인증기의 현재 상태를 검사하는 데 사용될 수 있습니다. 다시 말해, 이러한 인터페이스는 기록, 저장된 암호, 쿠키 등과 같은 사용자 상태를 관리하기 위해 브라우저가 제공하는 사용자 인터페이스와 유사합니다. 자격 증명 삭제와 같은 인증기 관리 작업은 그러한 사용자 인터페이스의 책임으로 간주되며 스크립트에 노출된 API에서는 의도적으로 제외됩니다.

이 API의 보안 특성은 클라이언트와 인증기가 함께 동작함으로써 제공됩니다. 자격 증명을 보유하고 관리하는 인증기는 모든 작업이 특정 기원(origin)에 범위가 지정되어 있으며, 응답에 기원을 포함시켜 다른 기원에 대해 재생(replay)될 수 없도록 보장합니다. 구체적으로는, § 6.3 Authenticator Operations에 정의된 바와 같이 요청자의 전체 기원이 포함되어 서명되며, 이는 새 자격 증명이 생성될 때 생성되는 attestation object와 WebAuthn 자격 증명이 생성하는 모든 assertion에 포함됩니다.

추가로 사용자 프라이버시를 유지하고 악의적인 Relying Party가 다른 Relying Party에 속한 공개 키 자격 증명의 존재를 탐지하는 것을 방지하기 위해, 각 자격 증명범위가 지정되어 Relying Party 식별자 또는 RP ID에 한정됩니다. 이 RP ID는 모든 작업에 대해 클라이언트가 인증기에 제공하며, 인증기는 Relying Party에 의해 생성된 자격 증명이 동일한 RP ID로 요청된 작업에서만 사용될 수 있도록 보장합니다. 이렇게 기원(origin)RP ID를 분리하면 단일 Relying Party가 여러 기원을 유지하는 경우에도 API를 사용할 수 있게 됩니다.

클라이언트는 이러한 보안 조치를 돕기 위해 각 작업에 대해 Relying Party기원(origin)RP ID를 인증기에 제공합 니다. 이것은 WebAuthn 보안 모델의 핵심 부분이므로, 사용자 에이전트는 이 API를 보안 컨텍스트(secure contexts)에서만 호출자에게 노출합니다. 특히 웹 컨텍스트의 경우, 이는 오류 없이 설정된 보안 전송(예: TLS)을 통해 접근되는 컨텍스트만 포함합니다.

Web Authentication API는 다음 섹션에 제시된 Web IDL 조각들의 합집합으로 정의됩니다. 결합된 IDL 목록은 IDL 색인에 제공됩니다.

5.1. PublicKeyCredential 인터페이스

PublicKeyCredential 인터페이스는 Credential [CREDENTIAL-MANAGEMENT-1]로부터 상속되며, 새 자격 증명이 생성되거나 새 assertion이 요청될 때 호출자에게 반환되는 속성을 포함합니다.

[SecureContext, Exposed=Window]
interface PublicKeyCredential : Credential {
    [SameObject] readonly attribute ArrayBuffer              rawId;
    [SameObject] readonly attribute AuthenticatorResponse    response;
    readonly attribute DOMString?                            authenticatorAttachment;
    AuthenticationExtensionsClientOutputs getClientExtensionResults();
    static Promise<boolean> isConditionalMediationAvailable();
    PublicKeyCredentialJSON toJSON();
};
id

이 속성은 Credential 에서 상속되지만, PublicKeyCredentialCredential의 getter를 오버라이드하여, 객체의 base64url 인코딩을 반환합니다. [[identifier]] 내부 슬롯에 포함된 데이터를 반환합니다.

rawId

이 속성은 ArrayBuffer[[identifier]] 내부 슬롯에서 반환합니다.

response, of type AuthenticatorResponse, readonly

이 속성은 인증기의 응답을 포함합니다. 클라이언트가 공개 키 인증 정보를 생성하거나 인증 어서션을 요청했을 때의 응답입니다. 만약 PublicKeyCredentialcreate() 에 대한 응답으로 생성된다면, 이 속성의 값은 AuthenticatorAttestationResponse 입니다. 그렇지 않으면, PublicKeyCredentialget() 에 대한 응답으로 생성되었으며, 이 속성의 값은 AuthenticatorAssertionResponse 가 됩니다.

authenticatorAttachment, of type DOMString, readonly, nullable

이 속성은 인증기 부착 모달리티를 보고합니다. navigator.credentials.create() 또는 navigator.credentials.get() 메서드가 성공적으로 완료된 시점의 모달리티입니다. 값은 AuthenticatorAttachment 의 멤버여야 합니다. Relying Parties 는 알 수 없는 값을 null로 취급해야 합니다.

참고: 만약 registration이나 authentication ceremony의 결과로 authenticatorAttachment 값이 "cross-platform"이면서 동시에 isUserVerifyingPlatformAuthenticatorAvailabletrue 를 반환하면, 사용자는 해당 ceremony로밍 인증기를 사용한 것입니다. 사용 가능한 플랫폼 인증기가 있으므로 Relying Party가 사용자가 플랫폼 인증기 를 등록하도록 안내할 수 있습니다. 이는 보다 원활한 사용자 경험을 가능하게 합니다.

인증기부착 모달리티는 시간이 흐르며 변할 수 있습니다. 예를 들어, 모바일폰은 처음엔 플랫폼 부착만 지원하다가 이후 업데이트로 크로스 플랫폼 부착도 지원할 수 있습니다.

getClientExtensionResults()

이 작업은 [[clientExtensionsResults]] 값을 반환합니다. 이 값은 이며, 확장자 식별자클라이언트 확장 출력 항목이 포함되어 있습니다. 각 확장은 클라이언트 확장 처리에 의해 생성됩니다.

isConditionalMediationAvailable()

PublicKeyCredential 은 이 메서드를 오버라이드하여 조건부 매개변수 사용 가능 여부를 나타냅니다. navigator.credentials.get() 동안. WebAuthn Relying Parties는 이를 설정하기 전에 사용 가능 여부를 확인해야 합니다. options.mediation조건부로 설정하기 전에.

호출 시, true 값이면 조건부 사용자 중재가 가능하면 그 값이 resolve되고, 그렇지 않으면 false 입니다.

이 메서드는 인자가 없으며, Boolean 값을 반환하는 promise를 돌려줍니다.

conditionalGet 기능은 이 promise가 true 로 resolve되는 것과 동일합니다.

참고: 이 메서드가 없으면, 조건부 사용자 중재navigator.credentials.get() 에서 사용할 수 없습니다.

참고: 이 메서드는 사용 여부를 나타내지 않습니다. 조건부 사용자 중재navigator.credentials.create() 에서 사용할 수 있는지에 대한 여부를 알 수 없습니다. 해당 내용은 conditionalCreate 기능을 getClientCapabilities() 에서 확인해야 합니다.

toJSON()

이 작업은 RegistrationResponseJSON 또는 AuthenticationResponseJSON 을 반환합니다. JSON 타입의 표현으로 PublicKeyCredential 과 동일하며, Relying Party 서버에 application/json 페이로드로 전송하기에 적합합니다. 클라이언트일반 방식으로 값을 JSON 타입으로 직렬화 해야 하지만, ArrayBuffer 값을 DOMString 으로 인코딩할 땐 base64url 인코딩을 반드시 먼저 적용해야 합니다.

RegistrationResponseJSON.clientExtensionResults 또는 AuthenticationResponseJSON.clientExtensionResults 멤버는 반드시 getClientExtensionResults() 결과로 설정되어야 하며, ArrayBuffer 값은 DOMString 값으로 base64url 인코딩해야 합니다. 이는 ArrayBuffer 확장자가 IANA "WebAuthn Extension Identifiers" registry [IANA-WebAuthn-Registries]에 등록되어 있지만, § 9 WebAuthn Extensions에는 정의되지 않은 확장자가 포함될 수 있습니다.

AuthenticatorAttestationResponseJSON.transports 멤버는 반드시 getTransports() 결과로 설정해야 합니다.

AuthenticatorAttestationResponseJSON.publicKey 멤버는 반드시 getPublicKey() 결과로 설정해야 합니다.

AuthenticatorAttestationResponseJSON.publicKeyAlgorithm 멤버는 반드시 getPublicKeyAlgorithm() 결과로 설정해야 합니다.

typedef DOMString Base64URLString;
// The structure of this object will be either
// RegistrationResponseJSON or AuthenticationResponseJSON
typedef object PublicKeyCredentialJSON;

dictionary RegistrationResponseJSON {
    required DOMString id;
    required Base64URLString rawId;
    required AuthenticatorAttestationResponseJSON response;
    DOMString authenticatorAttachment;
    required AuthenticationExtensionsClientOutputsJSON clientExtensionResults;
    required DOMString type;
};

dictionary AuthenticatorAttestationResponseJSON {
    required Base64URLString clientDataJSON;
    required Base64URLString authenticatorData;
    required sequence<DOMString> transports;
    // The publicKey field will be missing if pubKeyCredParams was used to
    // negotiate a public-key algorithm that the user agent doesn't
    // understand. (See section “Easily accessing credential data” for a
    // list of which algorithms user agents must support.) If using such an
    // algorithm then the public key must be parsed directly from
    // attestationObject or authenticatorData.
    Base64URLString publicKey;
    required COSEAlgorithmIdentifier publicKeyAlgorithm;
    // This value contains copies of some of the fields above. See
    // section “Easily accessing credential data”.
    required Base64URLString attestationObject;
};

dictionary AuthenticationResponseJSON {
    required DOMString id;
    required Base64URLString rawId;
    required AuthenticatorAssertionResponseJSON response;
    DOMString authenticatorAttachment;
    required AuthenticationExtensionsClientOutputsJSON clientExtensionResults;
    required DOMString type;
};

dictionary AuthenticatorAssertionResponseJSON {
    required Base64URLString clientDataJSON;
    required Base64URLString authenticatorData;
    required Base64URLString signature;
    Base64URLString userHandle;
};

dictionary AuthenticationExtensionsClientOutputsJSON {
};
[[type]]

PublicKeyCredential 인터페이스 객체[[type]] 내부 슬롯의 값은 문자열 "public-key"입니다.

참고: 이는 type 속성 getter를 통해 반영됩니다. 이 getter는 Credential에서 상속받습니다.

[[discovery]]

PublicKeyCredential 인터페이스 객체[[discovery]] 내부 슬롯의 값은 "remote"입니다.

[[identifier]]

내부 슬롯에는 인증기가 선택한 자격 증명 ID가 포함됩니다. 자격 증명 ID는 자격 증명을 조회할 때 사용되며, 같은 유형의 모든 자격 증명, 모든 인증기를 통틀어 매우 높은 확률로 전역적으로 고유한 값을 갖도록 되어 있습니다.

이 API는 식별자의 형식을 제한하지 않습니다. 단, 1023바이트를 넘지 않아야 하며, 인증기가 키를 고유하게 선택할 수 있을 정도로 충분해야 합니다. 예를 들어, 온보드 저장소가 없는 인증기는 자격 증명 개인 키를 인증기에 심어진 대칭 키로 감싸서 식별자를 만들 수도 있습니다.

[[clientExtensionsResults]]

내부 슬롯에는 신뢰하는 당사자신뢰하는 당사자navigator.credentials.create() 또는 navigator.credentials.get() 호출 시 요청한 클라이언트 확장 처리 결과가 포함됩니다.

PublicKeyCredential인터페이스 객체Credential[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) 구현을 상속받고, [[Create]](origin, options, sameOriginWithAncestors), [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors), [[Store]](credential, sameOriginWithAncestors) 각각에 대해 자체 구현을 정의합니다.

CredentialsContainerpreventSilentAccess() 메서드를 호출해도 PublicKeyCredential 자격 증명에는 아무런 영향이 없습니다. 항상 사용자 상호작용이 필요하기 때문입니다.

5.1.1. CredentialCreationOptions 딕셔너리 확장

navigator.credentials.create() 통한 등록을 지원하기 위해 이 문서는 CredentialCreationOptions 딕셔너리를 다음과 같이 확장합니다:

partial dictionary CredentialCreationOptions {
    PublicKeyCredentialCreationOptions      publicKey;
};

5.1.2. CredentialRequestOptions 딕셔너리 확장

navigator.credentials.get() 을 통한 인증(assertion) 획득을 지원하기 위해, 이 문서는 CredentialRequestOptions 딕셔너리를 다음과 같이 확장합니다:

partial dictionary CredentialRequestOptions {
    PublicKeyCredentialRequestOptions      publicKey;
};

5.1.3. 새 자격 증명 만들기 - PublicKeyCredential의 [[Create]](origin, options, sameOriginWithAncestors) 내부 메서드

PublicKeyCredential인터페이스 객체의 구현인 [[Create]](origin, options, sameOriginWithAncestors) 내부 메서드[CREDENTIAL-MANAGEMENT-1]WebAuthn Relying Party 스크립트가 navigator.credentials.create() 를 호출하여 새 공개 키 자격 증명 소스를 생성하도록 요청할 수 있게 하며, 이는 authenticator에 바인딩된 것입니다.

다음을 설정함으로써 options.mediationconditional 로 설정하면, Relying Parties는 사용자가 이미 자격 증명 생성을 동의한 경우 두드러진 모달 UI 없이 자격 증명을 등록하고자 함을 나타낼 수 있습니다. Relying Party는 먼저 getClientCapabilities() 를 사용하여 클라이언트conditionalCreate 기능을 지원하는지 확인해야 하며, 이 기능이 없을 경우 사용자에게 보이는 오류를 방지해야 합니다. 클라이언트는 의식해야 하며, requireUserPresencerequireUserVerificationFALSE로 설정해야 합니다. 단, 인증 절차 도중 명시적으로 수행될 수 있는 경우는 예외입니다, 즉 options.mediationconditional 로 설정된 경우입니다.

어떤 navigator.credentials.create() 작업도 AbortController 를 활용하여 중단될 수 있습니다; 자세한 지침은 DOM § 3.3 AbortController 및 AbortSignal 객체를 API에서 사용하는 방법를 참조하십시오.

내부 메서드는 세 개의 인수를 받습니다:

origin

이 인수는 호출하는 create() 구현에 의해 결정된 관련 설정 객체origin입니다.

options

이 인수는 CredentialCreationOptions 객체이며, 그 options.publicKey 멤버는 생성될 public key credential의 원하는 속성을 지정하는 PublicKeyCredentialCreationOptions 객체를 포함합니다.

sameOriginWithAncestors

이 인수는 Boolean 값으로, 호출자의 environment settings object조상들과 동일한 출처인지일 때만 true입니다. 호출자가 교차 출처인 경우에는 false입니다.

Note:내부 메서드의 호출은 permissions policy에 의해 허용되었음을 나타내며, 이는 [CREDENTIAL-MANAGEMENT-1] 수준에서 평가됩니다. § 5.9 Permissions Policy 통합을 참조하십시오.

Note: 이 알고리즘은 동기적입니다: Promise 의 해결/거부는 navigator.credentials.create() 에 의해 처리됩니다.

이 알고리즘에서 사용되는 모든 BufferSource 객체는 동기화 문제를 피하기 위해 알고리즘 시작 시 스냅샷되어야 합니다. 구현은 바이트의 복사본을 가져와 관련 알고리즘 부분에 그 복사본을 사용하는 것을 권장합니다.

이 메서드가 호출되면 사용자 에이전트는 다음 알고리즘을 실행해야 합니다:

  1. 단언: options.publicKey가 존재함.

  2. 만약 sameOriginWithAncestorsfalse라면:

    1. 만약 options.mediation 가 존재하고 값이 conditional인 경우:

      1. "NotAllowedError" DOMException 을 throw합니다.

    2. 만약 호출하는 create() 구현에 의해 결정되는 관련 전역 객체일시적 활성화(transient activation)를 갖지 않는다면:

      1. "NotAllowedError" DOMException 을 throw합니다.

    3. 관련 전역 객체의 사용자 활성화 소비(Consume user activation)를 수행합니다.

    4. 크리덴셜을 생성하는 origintop-level origin과 다르고, relevant global object (즉, 사용자가 주소창에서 볼 수 있는 origin과 다를 경우), 클라이언트는 이러한 사실을 사용자에게 명확하게 알려야 합니다.

  3. pkOptionsoptions.publicKey의 값으로 둡니다.

  4. 만약 pkOptions.timeout 이 존재하면, 그 값이 클라이언트가 정의한 합리적 범위 내에 있는지 확인하고, 그렇지 않으면 가장 가까운 값으로 조정합니다. 타이머 lifetimeTimer을 이 조정된 값으로 설정합니다. 만약 pkOptions.timeout 이 존재하지 않으면, lifetimeTimer을 클라이언트 특정 기본값으로 설정합니다.

    WebAuthn 절차의 타임아웃에 대한 합리적 범위와 기본값에 관한 지침은 권장 범위 및 기본값 섹션을 참조하십시오.

    클라이언트는 장애가 있는 사용자를 고려한 인지적 지침을 타임아웃에 반영해야 합니다.

  5. 만약 길이가 pkOptions.user.id 가 1에서 64 바이트(포함) 사이가 아니라면 TypeError 를 throw합니다.

  6. callerOriginorigin로 둡니다. 만약 callerOriginopaque origin이라면 "NotAllowedError" DOMException 을 throw합니다.

  7. effectiveDomaincallerOrigineffective domain으로 둡니다. 만약 effective domain유효한 도메인이 아니면 "SecurityError" DOMException 을 throw합니다.

    Note: effective domainhost로 해석될 수 있고, 이는 도메인, IPv4 주소, IPv6 주소, opaque host, 또는 empty host 등 다양한 방식으로 표현될 수 있습니다. 여기서는 domain 형식만 허용됩니다. 이는 단순화를 위한 것이며 PKI 기반 보안과 결합된 직접 IP 주소 식별 사용의 다양한 문제를 고려한 것입니다.

  8. 만약 pkOptions.rp.id

    존재하는 경우

    만약 pkOptions.rp.ideffectiveDomain의 registrable domain 접미사가 아니고 같지도 않다면, 그리고 클라이언트가

    관련 출처 요청를 지원하는 경우
    1. rpIdRequestedpkOptions.rp.id의 값으로 둡니다.

    2. related origins validation procedurecallerOriginrpIdRequested를 인수로 실행합니다. 결과가 false이면 "SecurityError" DOMException 을 throw합니다.

    관련 출처 요청를 지원하지 않는 경우

    "SecurityError" DOMException 을 throw합니다.

    존재하지 않는 경우

    pkOptions.rp.ideffectiveDomain으로 설정합니다.

    Note: pkOptions.rp.id 는 호출자의 RP ID를 나타냅니다. RP ID는 호출자의 origineffective domain이 기본값입니다. 단, 호출자가 pkOptions.rp.id 를 명시적으로 설정한 경우는 예외입니다.

  9. credTypesAndPubKeyAlgs을 새 리스트로 두고, 그 항목들이 PublicKeyCredentialTypeCOSEAlgorithmIdentifier 의 쌍이 되도록 합니다.

  10. 만약 pkOptions.pubKeyCredParams크기

    0인 경우

    다음의 PublicKeyCredentialTypeCOSEAlgorithmIdentifier 쌍들을 credTypesAndPubKeyAlgs추가합니다:

    0이 아닌 경우

    각각의 current에 대해 pkOptions.pubKeyCredParams:

    1. 만약 current.type 이 이 구현에서 지원되지 않는 PublicKeyCredentialType 을 포함하면, continue합니다.

    2. algcurrent.alg 으로 둡니다.

    3. Append current.typealg의 쌍을 credTypesAndPubKeyAlgs에 추가합니다.

    만약 credTypesAndPubKeyAlgs비어있다면, "NotSupportedError" DOMException 을 throw합니다.

  11. clientExtensions을 새 으로, authenticatorExtensions을 새 으로 둡니다.

  12. 만약 pkOptions.extensions 가 존재하면, 각각 extensionIdclientExtensionInput에 대해 pkOptions.extensions:
    1. 만약 extensionId가 이 클라이언트 플랫폼에서 지원되지 않거나 등록 확장(registration extension)이 아니면, continue합니다.

    2. Set clientExtensions[extensionId]을 clientExtensionInput으로 설정합니다.

    3. 만약 extensionIdauthenticator 확장이 아니면, continue합니다.

    4. authenticatorExtensionInputclientExtensionInput에 대해 extensionId클라이언트 확장 처리 알고리즘을 실행한 결과인 (CBOR)로 둡니다. 만약 알고리즘이 오류를 반환하면, continue합니다.

    5. Set authenticatorExtensions[extensionId]을 base64url 인코딩authenticatorExtensionInput으로 설정합니다.

  13. collectedClientData를 다음 필드를 가진 새 CollectedClientData 인스턴스로 둡니다:

    type

    문자열 "webauthn.create".

    challenge

    base64url 인코딩pkOptions.challenge.

    origin

    callerOrigin직렬화.

    crossOrigin

    이 내부 메서드에 전달된 sameOriginWithAncestors 인수의 값의 역수입니다.

    topOrigin

    callerOrigin직렬화로, 만약 같은 내부 메서드에 전달된 sameOriginWithAncestors 인수가 false이면 최상위(origin)의 직렬화를, 그렇지 않으면 undefined를 넣습니다.

  14. clientDataJSONcollectedClientData로부터 구성된 JSON 호환 직렬화로 둡니다.

  15. clientDataHashclientDataJSON로 표현된 직렬화된 클라이언트 데이터의 해시입니다.

  16. 만약 options.signal 이 존재하고 aborted 상태라면, signal중단 이유를 throw합니다.

  17. issuedRequests를 새 ordered set으로 둡니다.

  18. authenticators는 언제든지 특정 시점에 집합인 값을 나타내며, 각 항목은 해당 시점에 이 클라이언트 플랫폼에서 이용 가능한 authenticator를 식별하는 플랫폼 특정 핸들입니다.

    Note: authenticator가 "available"로 간주되는 기준은 의도적으로 명시되어 있지 않습니다. 이것은 authenticators가 다양한 방식(예: USB를 통한 hot-plug 연결, NFC 또는 Bluetooth를 통한 검색, 혹은 client에 영구적으로 내장됨 등)으로 client에 의해 인식될 수 있음을 의미합니다.

  19. 만약 options.mediation 가 존재하고 값이 conditional인 경우:

    1. 만약 사용자 에이전트가 최근에 인증을 중재하지 않았거나, 해당 인증의 출처가 callerOrigin이 아니거나, 사용자가 이 유형의 자격 증명 생성에 동의하지 않았다면 "NotAllowedError" DOMException 을 throw합니다.

      어떤 시점에 인증 의식(ceremony)이 완료되었다고 사용자 에이전트가 판단하는지는 사용자 에이전트에 달려 있습니다. 그 인증 의식은 Web Authentication API 이외의 다른 수단으로 수행될 수도 있습니다.

  20. hints 값을 고려하여 사용자 인터페이스를 적절히 구성하십시오; 구체적인 방식은 사용자 에이전트가 판단합니다.

  21. lifetimeTimer를 시작합니다.

  22. While lifetimeTimer가 만료되지 않은 동안, 다음 동작들을 lifetimeTimer와 각 authenticator의 상태 및 응답에 따라 수행합니다:
    If lifetimeTimer가 만료되면,

    각각의 authenticator에 대해 issuedRequests에서 authenticatorCancel 연산을 호출하고, issuedRequests에서 해당 authenticator제거합니다.

    사용자가 프로세스를 취소하는 UI 옵션을 선택하면,

    각각의 authenticator에 대해 issuedRequests에서 authenticatorCancel 연산을 호출하고, 제거합니다. 그리고 "NotAllowedError" DOMException 을 throw합니다.

    만약 options.signal 이 존재하고 aborted 상태이면,

    각각의 authenticator에 대해 issuedRequests에서 authenticatorCancel 연산을 호출하고, 제거합니다. 그 다음 signal중단 이유를 throw합니다.

    만약 어떤 authenticator가 이 클라이언트 장치에서 사용 가능해지면,

    Note: 이에는 lifetimeTimer 시작 시 이미 사용 가능했던 authenticator의 경우도 포함됩니다.

    1. authenticator는 이제 후보 authenticator입니다.

    2. 만약 pkOptions.authenticatorSelection 이 존재하면:

      1. 만약 pkOptions.authenticatorSelection.authenticatorAttachment 이 존재하고 그 값이 현재 authenticatorauthenticator attachment modality와 같지 않으면, continue합니다.

      2. 만약 pkOptions.authenticatorSelection.residentKey

        존재하고 required로 설정된 경우

        만약 해당 authenticator클라이언트 사이드에서 검색 가능한 공개 키 자격 증명 소스를 저장할 수 없다면, continue합니다.

        존재하고 preferred 또는 discouraged로 설정된 경우

        효과 없음.

        존재하지 않는 경우

        만약 pkOptions.authenticatorSelection.requireResidentKeytrue로 설정되어 있고 해당 authenticator클라이언트 사이드에서 검색 가능한 공개 키 자격 증명 소스를 저장할 수 없다면, continue합니다.

      3. 만약 pkOptions.authenticatorSelection.userVerificationrequired 로 설정되어 있고 해당 authenticatoruser verification을 수행할 수 없다면, continue합니다.

    3. requireResidentKey자격 증명 생성에 대한 실질적 resident key 요구로 두고, 다음과 같이 Boolean 값으로 결정합니다:

      만약 pkOptions.authenticatorSelection.residentKey

      존재하며 required로 설정된 경우

      requireResidentKeytrue로 설정합니다.

      존재하며 preferred로 설정된 경우

      authenticator

      클라이언트 측 자격 증명 저장 방식을 지원하는 경우

      requireResidentKeytrue로 설정합니다.

      클라이언트 측 자격 증명 저장 방식을 지원하지 않거나 클라이언트가 인증기의 기능을 판단할 수 없는 경우

      requireResidentKeyfalse로 설정합니다.

      존재하며 discouraged로 설정된 경우

      requireResidentKeyfalse로 설정합니다.

      존재하지 않는 경우

      requireResidentKeypkOptions.authenticatorSelection.requireResidentKey의 값으로 설정합니다.

    4. userVerification자격 증명 생성에 대한 실질적 사용자 검증 요구로 두고 Boolean 값으로 다음과 같이 결정합니다. 만약 pkOptions.authenticatorSelection.userVerification

      required로 설정된 경우
      1. options.mediationconditional로 설정되고 사용자 검증 이 ceremony 동안 수집될 수 없는 경우, ConstraintError DOMException을 throw합니다.

      2. userVerificationtrue로 설정합니다.

      preferred로 설정된 경우

      authenticator

      사용자 검증을 지원하는 경우

      userVerificationtrue로 설정합니다.

      사용자 검증을 지원하지 않는 경우

      userVerificationfalse로 설정합니다.

      discouraged로 설정된 경우

      userVerificationfalse로 설정합니다.

    5. enterpriseAttestationPossible를 Boolean 값으로 두고 다음과 같이 결정합니다. 만약 pkOptions.attestation

      설정이 enterprise인 경우

      만약 사용자 에이전트가 pkOptions.rp.id 에 대해 enterprise attestation을 지원하려고 하면 enterpriseAttestationPossibletrue로 설정합니다 (위의 8단계 참조). 그렇지 않으면 false입니다.

      그 외

      enterpriseAttestationPossiblefalse로 설정합니다.

    6. attestationFormats을 문자열의 리스트로 두고, 초기값은 pkOptions.attestationFormats 의 값으로 설정합니다.

    7. 만약 pkOptions.attestation

      설정이 none인 경우

      attestationFormats을 문자열 "none"만 포함하는 단일 요소 리스트로 설정합니다.

    8. excludeCredentialDescriptorList을 새 리스트로 둡니다.

    9. 각각의 자격 증명 설명자 C에 대해 pkOptions.excludeCredentials에서:

      1. 만약 C.transports비어있지 않고, 그리고 authenticatorC.transports에 명시되지 않은 전송 방식으로 연결되어 있다면, 클라이언트는 continue할 수 있습니다.

        Note: 만약 클라이언트가 continue하기로 선택하면, C.transports 의 힌트가 정확하지 않은 경우 동일한 authenticator에 바인딩된 여러 자격 증명이 의도치 않게 등록될 수 있습니다. 예를 들어, 저장된 전송 힌트는 소프트웨어 업그레이드로 인해 새로운 연결 옵션이 추가되면 부정확해질 수 있습니다.

      2. 그렇지 않으면, Append CexcludeCredentialDescriptorList에 추가합니다.

      3. authenticator에서 authenticatorMakeCredential 연산을 호출하고, 인수로 clientDataHash, pkOptions.rp, pkOptions.user, requireResidentKey, userVerification, credTypesAndPubKeyAlgs, excludeCredentialDescriptorList, enterpriseAttestationPossible, attestationFormats, 및 authenticatorExtensions를 사용합니다.

    10. Append authenticatorissuedRequests에 추가합니다.

    If 어떤 authenticator가 이 클라이언트 장치에서 더 이상 사용 불가능하게 되면,

    Remove 해당 authenticatorissuedRequests에서 제거합니다.

    If 어떤 authenticator가 사용자가 작업을 취소했다고 상태를 반환하면,
    1. Remove 해당 authenticatorissuedRequests에서 제거합니다.

    2. 남아있는authenticator에 대해 authenticatorCancel 연산을 호출하고, 제거합니다.

      Note: Authenticators는 "사용자가 전체 작업을 취소했다"는 표시를 반환할 수 있습니다. 사용자 에이전트가 이 상태를 사용자에게 어떻게 표시하는지는 명시되지 않습니다.

    If 어떤 authenticator가 "InvalidStateError" 와 동등한 오류 상태를 반환하면,
    1. Remove 해당 authenticatorissuedRequests에서 제거합니다.

    2. 남아있는authenticator에 대해 authenticatorCancel 연산을 호출하고, 제거합니다.

    3. "InvalidStateError" DOMException 을 throw합니다.

    Note: 이 오류 상태는 별도로 처리됩니다. 왜냐하면 해당 authenticatorexcludeCredentialDescriptorList가 해당 authenticator에 바인딩된 자격 증명을 식별하고 사용자가 해당 작업에 동의한 경우에만 이 오류를 반환하기 때문입니다. 이러한 명시적 동의가 있으므로 이 경우가 Relying Party에 대해 구분 가능한 것은 허용됩니다.

    If 어떤 authenticator가 "InvalidStateError" 와 동등하지 않은 오류 상태를 반환하면,

    Remove 해당 authenticatorissuedRequests에서 제거합니다.

    Note: 이 경우는 작업에 대한 사용자 동의를 의미하지 않으므로, 잠재적으로 식별 정보를 누설할 수 있는 오류 세부 정보는 Relying Party에게 숨겨집니다. 자세한 내용은 § 14.5.1 Registration Ceremony Privacy를 참조하십시오.

    If 어떤 authenticator가 성공을 나타내면,
    1. Remove 해당 authenticatorissuedRequests에서 제거합니다. 이 authenticationtor는 이제 선택된 authenticator가 됩니다.

    2. credentialCreationData를 다음 항목을 가진 struct로 둡니다:

      attestationObjectResult

      그 값은 성공적인 authenticatorMakeCredential 연산에서 반환된 바이트입니다.

      Note: 이 값은 § 6.5.4 Generating an Attestation Object에서 정의된 attObj입니다.

      clientDataJSONResult

      그 값은 clientDataJSON의 바이트입니다.

      attestationConveyancePreferenceOption

      그 값은 pkOptions.attestation의 값입니다.

      clientExtensionResults

      그 값은 AuthenticationExtensionsClientOutputs 객체로, 각 확장 식별자클라이언트 확장 출력 항목들을 포함합니다. 이 항목들은 pkOptions.extensions에 있는 각 클라이언트 확장에 대해 해당 확장의 클라이언트 확장 처리 알고리즘을 실행하여 생성된 클라이언트 확장 출력들을 포함합니다.

    3. constructCredentialAlg을 전역 객체 global을 인수로 받는 알고리즘으로 두고, 그 단계는 다음과 같습니다:

      1. 만약 credentialCreationData.attestationConveyancePreferenceOption의 값이

        none

        잠재적으로 고유 식별 가능한 정보를 식별 불가능한 버전으로 대체합니다:

        1. 만약 attested credential data의 aaguid 가 16 바이트 0이면, credentialCreationData.attestationObjectResult.fmt 이 "packed"이고, credentialCreationData.attestationObjectResult 에서 "x5c"가 없으면, self attestation이 사용되는 것이므로 추가 작업이 필요 없습니다.

        2. 그렇지 않으면:

          1. credentialCreationData.attestationObjectResult.fmt 을 "none"으로 설정하고, credentialCreationData.attestationObjectResult.attStmt 를 빈 CBOR 맵으로 설정합니다. (§ 8.7 None Attestation Statement Format 및 § 6.5.4 Generating an Attestation Object 참조).

        indirect

        클라이언트는 aaguidattestation statement를 더 개인정보 친화적이거나 검증이 용이한 버전으로 대체할 수 있습니다(예: Anonymization CA 사용).

        direct 또는 enterprise

        authenticatorAAGUIDattestation statement를 변경 없이 Relying Party에 전달합니다.

      2. attestationObject를 새 ArrayBuffer 로 생성하고, global%ArrayBuffer%를 사용하여 credentialCreationData.attestationObjectResult의 바이트를 포함시킵니다.

      3. idattestationObject.authData.attestedCredentialData.credentialId 로 둡니다.

      4. pubKeyCred를 새 PublicKeyCredential 객체로 생성하고, 그 필드는 다음과 같습니다:

        [[identifier]]

        id

        authenticatorAttachment

        해당 authenticator의 현재 authenticator attachment modality와 일치하는 AuthenticatorAttachment 값을 가집니다.

        response

        새로운 AuthenticatorAttestationResponse 객체로, 그 필드는 다음과 같습니다:

        clientDataJSON

        새로운 ArrayBuffer, global%ArrayBuffer%를 사용하여 생성되며, credentialCreationData.clientDataJSONResult 의 바이트를 포함합니다.

        attestationObject

        attestationObject

        [[transports]]

        해당 authenticator가 지원하는 것으로 알려진 0개 이상 고유한 DOMString의 시퀀스이며, 사전식(lexicographical) 정렬되어 있습니다. 값들은 AuthenticatorTransport 의 멤버여야 하지만, 클라이언트 플랫폼는 알 수 없는 값을 무시해야 합니다.

        만약 사용자 에이전트가 이 정보를 공개하고 싶지 않으면, 개인정보를 보호하기 위해 임의의 시퀀스를 대체할 수 있습니다. 이 시퀀스는 여전히 유효해야 하며, 즉 사전식으로 정렬되고 중복이 없어야 합니다. 예: 빈 시퀀스를 사용할 수 있습니다. 어떤 선택을 하든, 이 경우 사용자 에이전트는 Relying Party의 동작이 최적이 아닐 위험을 감수합니다.

        만약 사용자 에이전트가 어떠한 전송 정보도 가지고 있지 않다면, 이 필드를 빈 시퀀스로 설정해야 합니다.

        Note: 특정 authenticator가 지원하는 전송을 사용자 에이전트가 어떻게 발견하는지는 이 사양의 범위를 벗어나지만, attestation certificate(예: [FIDO-Transports-Ext])의 정보, CTAP2 같은 authenticator 프로토콜에서 전달된 메타데이터, 또는 플랫폼 인증기(platform authenticators)에 대한 특수 지식 등을 포함할 수 있습니다.

        [[clientExtensionsResults]]

        새로운 ArrayBuffer, global%ArrayBuffer%를 사용하여 생성되며, credentialCreationData.clientExtensionResults 의 바이트를 포함합니다.

      5. pubKeyCred를 반환합니다.

    4. 남아있는authenticator에 대해 issuedRequests에서 authenticatorCancel 연산을 호출하고, 제거합니다.

    5. constructCredentialAlg을 반환하고 이 알고리즘을 종료합니다.

  23. "NotAllowedError" DOMException 을 throw합니다.

위 과정 중, 사용자 에이전트는 사용자가 authenticator를 선택하고 승인하는 과정을 안내하기 위해 일부 UI를 표시해야 합니다. 만약 options.mediationconditional 로 설정된 경우, 이전에 사용자 에이전트가 결정한 수단으로 자격 증명 생성에 동의된 경우가 아니면 두드러진 모달 UI를 표시해서는 안 됩니다.

5.1.3.1. 생성 요청 예외

이 섹션은 규범적이지 않습니다.

WebAuthn 의존 당사자navigator.credentials.create() 호출에서 여러 예외를 만날 수 있습니다. 일부 예외는 발생 원인이 여러 가지일 수 있으므로, WebAuthn 의존 당사자는 WebAuthn 사용에 따라 실제 원인을 추론해야 합니다.

Note: 이 사양 외부에 정의된 것을 포함하여 어떤 WebAuthn 확장의 처리 중에 발생할 수 있는 예외는 여기에 나열되지 않습니다.

다음 DOMException 예외들이 발생할 수 있습니다:

AbortError

절차가 AbortController에 의해 취소되었습니다. § 5.6 Abort Operations with AbortSignal 및 § 1.3.4 Aborting Authentication Operations를 참조하십시오.

ConstraintError

다음 중 하나입니다: residentKeyrequired로 설정되었으나 사용 가능한 인증기가 resident key를 지원하지 않았거나, userVerificationrequired로 설정되었으나 사용 가능한 인증기가 사용자 검증을 수행할 수 없었습니다.

InvalidStateError

절차에서 사용된 인증기가 사용자가 자격 증명 등록에 동의한 후 excludeCredentials에 있는 항목을 인식했습니다.

NotSupportedError

pubKeyCredParams의 어떤 항목도 type 속성으로 public-key를 갖지 않았거나, 인증기pubKeyCredParams에 지정된 서명 알고리즘들을 전혀 지원하지 않았습니다.

SecurityError

effective domain이 유효한 도메인이 아니었거나, rp.ideffective domain과 같지 않거나 registrable domain 접미사가 아니었습니다. 후자의 경우, 클라이언트관련 출처 요청을 지원하지 않거나 관련 출처 검증 절차가 실패했습니다.

NotAllowedError

사용자가 절차를 중단하는 것과 같은 일반적인 원인을 포함하여 다양한 가능한 이유를 포괄하는 포괄적 오류입니다. 이들 원인 중 일부는 이 규격 전반에 문서화되어 있으며, 다른 것들은 클라이언트 특정입니다.

다음 단순 예외들이 발생할 수 있습니다:

TypeError

options 인수가 유효한 CredentialCreationOptions 값이 아니었거나, user.id의 값이 비어 있거나 64바이트보다 길었습니다.

5.1.4. 기존 자격 증명을 사용하여 어설션 생성

WebAuthn 의존 당사자navigator.credentials.get({publicKey:..., ...}) 를 호출하여 기존의 공개 키 자격 증명을 찾아 사용자 동의 하에 사용합니다. Relying Party 스크립트는 선택적으로 어떤 공개 키 자격 증명 소스가 허용되는지 나타내는 일부 기준을 지정할 수 있습니다. 클라이언트 플랫폼은 지정된 기준에 맞는 공개 키 자격 증명 소스를 찾아 스크립트가 사용할 수 있도록 사용자가 하나를 선택하도록 안내합니다. 예를 들어 프라이버시 유지를 위해 공개 키 자격 증명 소스가 존재하더라도 사용자가 전체 상호작용을 거부할 수 있습니다. 사용자가 공개 키 자격 증명 소스를 선택하면, 사용자 에이전트는 § 6.3.3 The authenticatorGetAssertion Operation을 사용하여 Relying Party가 제공한 챌린지 및 기타 수집된 데이터를 서명하여 인증 어설션을 만들고, 이를 자격 증명으로 사용합니다.

이 사양은 navigator.credentials.get() 구현이 [CREDENTIAL-MANAGEMENT-1]에 따라 PublicKeyCredential.[[CollectFromCredentialStore]]() 를 호출하여 사용자 중재(대략 이 사양의 권한 부여 제스처) 없이 사용 가능해야 하는 어떤 자격 증명들을 수집하고, 그 중 정확히 하나를 찾지 못하면 PublicKeyCredential.[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 를 호출하여 사용자가 공개 키 자격 증명 소스를 선택하도록 합니다.

이 사양이 어떤 어설션을 생성하려면 권한 부여 제스처를 요구하므로, PublicKeyCredential[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) 의 기본 동작, 즉 빈 집합을 반환하는 동작을 상속합니다. PublicKeyCredential[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 구현은 다음 섹션에 명세되어 있습니다.

일반적으로 사용자 에이전트는 작업을 완료할 수 있는 인증기를 선택하고 승인하도록 사용자에게 안내하기 위해 일부 UI를 표시해야 합니다. options.mediationconditional 로 설정하면 Relying Parties는 자격 증명이 발견되지 않는 한 두드러진 모달 UI를 표시해서는 안 된다고 표시할 수 있습니다. Relying Party는 먼저 isConditionalMediationAvailable() 또는 getClientCapabilities() 를 사용하여 클라이언트conditionalGet 기능을 지원하는지 확인하여 이 기능이 없을 경우 사용자에게 보이는 오류를 방지해야 합니다.

어떤 navigator.credentials.get() 작업도 AbortController 를 이용해 중단할 수 있습니다; 자세한 지침은 DOM § 3.3 AbortController 및 AbortSignal 객체를 API에서 사용하는 방법를 참조하십시오.

5.1.4.1. PublicKeyCredential의 [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 내부 메서드

internal method는 세 개의 인수를 받습니다:

origin

이 인수는 호출하는 get() 구현에 의해 결정된 relevant settings objectorigin입니다. 즉, CredentialsContainerRequest a Credential 추상 연산에 해당합니다.

options

이 인수는 CredentialRequestOptions 객체이며, 그 options.publicKey 멤버는 검색할 public key credential의 원하는 속성을 지정하는 PublicKeyCredentialRequestOptions 객체를 포함합니다.

sameOriginWithAncestors

이 인수는 Boolean 값이며, 호출자의 environment settings object조상들과 same-origin인지에 따라 true가 됩니다. 호출자가 교차 출처인 경우에는 false입니다.

참고: 이 내부 메서드의 호출은 permissions policy에 의해 허용되었음을 나타내며, 이는 [CREDENTIAL-MANAGEMENT-1] 수준에서 평가됩니다. 자세한 내용은 § 5.9 Permissions Policy integration을 참조하세요.

참고: 이 알고리즘은 동기적입니다: Promise 의 해결/거절은 navigator.credentials.get()에서 처리됩니다.

이 알고리즘에서 사용되는 모든 BufferSource 객체는 알고리즘이 시작될 때 스냅샷되어야 하며, 동기화 문제를 피하기 위해 구현체는 버퍼 소스가 보유한 바이트의 복사본을 얻는 것을 권장합니다.

이 메서드가 호출되면 사용자 에이전트는 다음 알고리즘을 반드시 실행해야 합니다:

  1. 단언: options.publicKey 가 존재함을 확인합니다.

  2. pkOptionsoptions.publicKey의 값으로 둡니다.

  3. 만약 options.mediation 가 존재하고 그 값이 conditional인 경우:

    1. credentialIdFilterpkOptions.allowCredentials의 값으로 둡니다.

    2. pkOptions.allowCredentialsempty로 설정합니다.

      참고: 이렇게 하면 non-discoverable credentialsconditional 요청 동안 사용되는 것을 방지합니다.

    3. lifetimeTimer를 무한(infinity) 값으로 설정합니다.

      참고: lifetimeTimer가 무한으로 설정되는 이유는 사용자가 문서의 전체 수명 동안 "webauthn" autofill detail token이 지정된 input 폼 컨트롤을 통해 상호작용할 수 있도록 하기 위함입니다. 예를 들어 사용자가 해당 입력 필드를 클릭하면 사용자 에이전트는 발견된 자격 증명 목록을 렌더링하여 사용자가 선택하도록 하거나 "다른 방법 시도" 옵션을 제공할 수 있습니다.

  4. 그 밖의 경우(else):

    1. credentialIdFilter를 빈 list로 둡니다.

    2. 만약 pkOptions.timeout 이 존재하면, 그 값이 client가 정의한 합리적 범위 내에 있는지 확인하고, 아니면 가장 가까운 유효값으로 수정합니다. 그 조정된 값으로 lifetimeTimer를 설정합니다. 만약 존재하지 않으면 client-특정 기본값으로 설정합니다.

      타임아웃의 합리적 범위 및 기본값에 대한 지침은 recommended range and default for a WebAuthn ceremony timeout를 참조하세요.

      사용자 에이전트는 특수한 필요가 있는 사용자를 위해 타임아웃을 정할 때 인지적 지침을 고려해야 합니다.

  5. callerOriginorigin으로 둡니다. 만약 callerOriginopaque origin이면 "NotAllowedError" DOMException을 던집니다.

  6. effectiveDomaincallerOrigineffective domain으로 둡니다. 만약 해당 effective domain이 유효한 domain이 아니면 "SecurityError" DOMException을 던집니다.

    참고: effective domainhost로 해석될 수 있으며, 이는 domain, ipv4 주소, ipv6 주소, opaque host, 또는 empty host 등 다양한 방식으로 표현될 수 있습니다. 여기서는 domain 형식의 호스트만 허용됩니다. 이는 단순화 목적 및 PKI 기반 보안과 직접 IP 주소 식별을 함께 사용할 때 발생하는 여러 문제를 고려한 것입니다.

  7. 만약 pkOptions.rpId
    존재하는 경우

    만약 pkOptions.rpIdeffectiveDomain의 registrable domain suffix가 아니고 같지도 않다면, 그리고 클라이언트가

    related origin requests를 지원하는 경우
    1. rpIdRequestedpkOptions.rpId의 값으로 둡니다.

    2. related origins validation procedurecallerOriginrpIdRequested로 실행합니다. 결과가 false이면 "SecurityError" DOMException을 던집니다.

    related origin requests를 지원하지 않는 경우

    "SecurityError" DOMException을 던집니다.

    존재하지 않는 경우

    pkOptions.rpIdeffectiveDomain으로 설정합니다.

    참고: rpId는 호출자의 RP ID를 나타냅니다. RP ID는 호출자가 명시적으로 pkOptions.rpId를 설정하지 않은 경우 호출자의 origineffective domain으로 기본 설정됩니다.

  8. clientExtensions를 새 map으로, authenticatorExtensions를 새 map으로 둡니다.

  9. 만약 pkOptions.extensions 가 존재하면, 각각의 extensionIdclientExtensionInput에 대해:

    1. 만약 extensionId가 이 client platform에서 지원되지 않거나 인증 확장(authentication extension)이 아니면 계속합니다.

    2. Set clientExtensions[extensionId]을 clientExtensionInput으로 설정합니다.

    3. 만약 extensionIdauthenticator extension이 아니면 계속합니다.

    4. authenticatorExtensionInputextensionIdclient extension processing 알고리즘을 clientExtensionInput에 실행하여 얻은 (CBOR) 결과로 둡니다. 만약 알고리즘이 오류를 반환하면 계속합니다.

    5. Set authenticatorExtensions[extensionId]을 base64url 인코딩authenticatorExtensionInput으로 설정합니다.

  10. collectedClientData를 새 CollectedClientData 인스턴스로 하고 그 필드는 다음과 같습니다:

    type

    문자열 "webauthn.get".

    challenge

    pkOptions.challengebase64url 인코딩.

    origin

    callerOrigin직렬화.

    crossOrigin

    이 내부 메서드에 전달된 sameOriginWithAncestors 인수의 값의 역값입니다.

    topOrigin

    만약 이 내부 메서드에 전달된 sameOriginWithAncestors 인수가 false이면 callerOrigintop-level origin직렬화이고, 그렇지 않으면 undefined입니다.

  11. clientDataJSONcollectedClientData로부터 구성된 JSON-호환 직렬화로 둡니다.

  12. clientDataHashclientDataJSON로 표현된 직렬화된 클라이언트 데이터의 해시로 둡니다.

  13. 만약 options.signal 이 존재하고 중단(aborted) 상태라면, options.signal중단 사유(abort reason)를 throw 하십시오.

  14. issuedRequests를 새 ordered set으로 둡니다.

  15. savedCredentialIds를 새 map으로 둡니다.

  16. authenticators는 주어진 순간에 이 client platform에서 현재 사용 가능한 각 authenticator를 식별하는 플랫폼별 핸들들의 집합을 나타내는 값입니다.

    참고: 어떤 것이 "사용 가능"한 authenticator인지에 대한 기준은 의도적으로 명시하지 않았습니다; 이는 인증기가 USB로 핫플러그되거나 NFC/Bluetooth로 검색되거나 플랫폼에 내장되는 등 다양한 메커니즘으로 클라이언트가 인식하는 방식을 나타냅니다.

  17. silentlyDiscoveredCredentials를 새 map으로 두고, 그 entriesDiscoverableCredentialMetadataauthenticator의 형태입니다.

  18. hints 값을 고려하여 사용자 인터페이스를 적절히 구성합니다.

  19. lifetimeTimer를 시작합니다.

  20. While lifetimeTimer가 만료되지 않은 동안, lifetimeTimerauthenticators의 상태 및 응답에 따라 각 authenticator에 대해 다음 작업을 수행합니다:

    만약 lifetimeTimer가 만료되면,

    각각의 authenticator에 대해 issuedRequests에서 authenticatorCancel을 호출하고 제거합니다.

    만약 사용자가 프로세스를 취소하는 UI 옵션을 사용하면,

    각각의 authenticator에 대해 issuedRequests에서 authenticatorCancel을 호출하고 제거합니다. 그런 다음 "NotAllowedError" DOMException을 던집니다.

    만약 options.signal 이 존재하고 중단(aborted) 상태이면,

    authenticatorissuedRequests에서 대상으로 하여 authenticatorCancel 작업을 authenticator에 수행하고, 제거 authenticatorissuedRequests에서 합니다. 그런 다음 options.signal중단 사유를 throw 합니다.

    만약 options.mediationconditional 이고 사용자가 input 또는 textarea 폼 컨트롤과 상호작용하고 해당 폼 컨트롤의 autocomplete 속성의 non-autofill credential type"webauthn"인 경우,
    참고: "webauthn" autofill detail token은 반드시 "Normal" 또는 "Contact" 형식의 마지막 autofill detail token 바로 뒤에 나타나야 합니다. 예를 들어:
    • "username webauthn"

    • "current-password webauthn"

    1. 만약 silentlyDiscoveredCredentials가 비어 있지 않다면(not empty):

      1. silentlyDiscoveredCredentials에서 DiscoverableCredentialMetadata을 사용자가 선택하도록 선택적으로 안내합니다. 프롬프트는 각 DiscoverableCredentialMetadataotherUI 값(예: namedisplayName)을 표시해야 합니다.

        사용자가 선택한 경우, credentialMetadata를 선택된 DiscoverableCredentialMetadata로 둡니다.

      2. 만약 사용자가 credentialMetadata를 선택하면,

        1. publicKeyOptionspkOptions의 임시 복사본으로 둡니다.

        2. authenticatorsilentlyDiscoveredCredentials[credentialMetadata]의 값으로 둡니다.

        3. publicKeyOptions.allowCredentials 를 단일 항목을 포함하는 list로 설정합니다. 그 단일 PublicKeyCredentialDescriptor 항목의 id 값은 credentialMetadataid 값으로 설정하고, 해당 항목의 id 값은 credentialMetadatatype으로 설정합니다.

        4. issuing a credential request to an authenticator 알고리즘을 authenticator, savedCredentialIds, publicKeyOptions, rpId, clientDataHash, 및 authenticatorExtensions를 인수로 실행합니다.

          만약 이것이 false를 반환하면 계속합니다.

        5. Append authenticatorissuedRequests에 추가합니다.

    만약 options.mediationconditional이 아니고, issuedRequests가 비어 있으며, pkOptions.allowCredentials 가 비어 있지 않고, 거기서 어떤 authenticator도 사용 가능해지지 않을 것이라면,

    사용자에게 적합한 자격 증명을 찾을 수 없음을 알립니다. 사용자가 대화 상자를 확인하면 "NotAllowedError" DOMException을 던집니다.

    참고: 한 가지 방법으로, client platform은 현재 pkOptions.allowCredentials의 각 PublicKeyCredentialDescriptor 항목의 transports 멤버를 검사하여 어떤 authenticator도 더 이상 사용 가능해지지 않을 것임을 판단할 수 있습니다. 예를 들어 모든 PublicKeyCredentialDescriptor 항목이 internal만을 나열하지만 모든 플랫폼 authenticator를 이미 시도해 보았다면, 요청을 충족할 가능성이 없습니다. 또는 모든 항목이 클라이언트 플랫폼이 지원하지 않는 전송을 나열할 수도 있습니다.

    만약 authenticator가 이 client device에서 사용 가능해지면,

    참고: 여기에는 lifetimeTimer 시작 시 이미 사용 가능했던 경우도 포함됩니다.

    1. 만약 options.mediationconditional 이고 authenticatorsilentCredentialDiscovery 연산을 지원하면:

      1. collectedDiscoveredCredentialMetadataauthenticator에서 silentCredentialDiscovery 연산을 rpId를 인수로 하여 호출한 결과로 둡니다.

      2. 각각의 credentialMetadata에 대해 collectedDiscoveredCredentialMetadata:

        1. 만약 credentialIdFilter가 비어 있거나 또는 credentialIdFiltercredentialMetadataid와 일치하는 id 항목을 포함하면, set silentlyDiscoveredCredentials[credentialMetadata]을 authenticator로 설정합니다.

          참고: 해당 인증기로 요청이 발행되는 것은 특정 UI 컨텍스트를 통해 사용자가 자격 증명을 선택했을 때입니다(세부사항은 여기 참조).

    2. 그렇지 않으면:

      1. issuing a credential request to an authenticator 알고리즘을 authenticator, savedCredentialIds, pkOptions, rpId, clientDataHash, 및 authenticatorExtensions를 인수로 실행합니다.

        만약 이것이 false를 반환하면 계속합니다.

        참고: 이 분기는 options.mediationconditional 이고 해당 authenticatorsilentCredentialDiscovery 연산을 지원하지 않아도 conditional user mediation 요청 동안 그런 인증기를 사용하려는 경우에 취해집니다.

      2. Append authenticatorissuedRequests에 추가합니다.

    만약 authenticator가 이 client device에서 더 이상 사용 가능하지 않게 되면,

    Remove authenticatorissuedRequests에서 제거합니다.

    만약 어떤 authenticator가 사용자 취소 상태를 반환하면,
    1. Remove 해당 authenticatorissuedRequests에서 제거합니다.

    2. 남아 있는authenticator에 대해 authenticatorCancel을 호출하고 제거합니다.

      참고: Authenticators는 "사용자가 전체 작업을 취소했다"는 표시를 반환할 수 있습니다. 사용자 에이전트가 이를 사용자에게 어떻게 나타내는지는 명시되지 않습니다.

    만약 어떤 authenticator가 오류 상태를 반환하면,

    Remove 해당 authenticatorissuedRequests에서 제거합니다.

    만약 어떤 authenticator가 성공을 나타내면,
    1. Remove 해당 authenticatorissuedRequests에서 제거합니다.

    2. assertionCreationData를 다음 항목을 가진 struct으로 둡니다:

      credentialIdResult

      만약 savedCredentialIds[authenticator]가 존재하면, credentialIdResult의 값을 해당 바이트로 설정합니다. 그렇지 않으면, 성공한 authenticatorGetAssertion 연산에서 반환된 credential ID의 바이트로 설정합니다.

      clientDataJSONResult

      그 값은 clientDataJSON의 바이트입니다.

      authenticatorDataResult

      그 값은 authenticator data의 바이트로, 해당 authenticator가 반환한 값입니다.

      signatureResult

      그 값은 authenticator가 반환한 서명 값의 바이트입니다.

      userHandleResult

      만약 authenticatoruser handle을 반환했다면, userHandleResult의 값을 반환된 user handle의 바이트로 설정합니다. 그렇지 않으면 해당 값을 null로 설정합니다.

      clientExtensionResults

      그 값은 AuthenticationExtensionsClientOutputs 객체로, 각 확장의 extension identifierclient extension output 항목들을 포함합니다. 이러한 항목들은 pkOptions.extensions에 있는 각 클라이언트 확장에 대해 그 확장의 client extension processing 알고리즘을 실행하여 생성됩니다.

    3. 만약 credentialIdFilter가 비어 있지 않고(is not empty) credentialIdFiltercredentialIdResult의 값과 일치하는 id 항목을 포함하지 않으면 계속합니다.

    4. 만약 credentialIdFilter가 비어 있고(is empty) userHandleResult가 null이면 계속합니다.

    5. settingscurrent settings object로 둡니다. globalsettingsglobal object로 둡니다.

    6. pubKeyCredglobal과 연관된 새 PublicKeyCredential 객체로 만들고 그 필드는 다음과 같습니다:

      [[identifier]]

      global%ArrayBuffer%를 사용하여 생성된 새 ArrayBufferassertionCreationData.credentialIdResult의 바이트를 포함합니다.

      authenticatorAttachment

      해당 authenticator의 현재 authenticator attachment modality에 일치하는 AuthenticatorAttachment 값입니다.

      response

      global과 연관된 새 AuthenticatorAssertionResponse 객체로 그 필드는 다음과 같습니다:

      clientDataJSON

      global%ArrayBuffer%를 사용하여 생성된 새 ArrayBufferassertionCreationData.clientDataJSONResult의 바이트를 포함합니다.

      authenticatorData

      global%ArrayBuffer%를 사용하여 생성된 새 ArrayBufferassertionCreationData.authenticatorDataResult의 바이트를 포함합니다.

      signature

      global%ArrayBuffer%를 사용하여 생성된 새 ArrayBufferassertionCreationData.signatureResult의 바이트를 포함합니다.

      userHandle

      만약 assertionCreationData.userHandleResult 가 null이면 이 필드를 null로 설정합니다. 그렇지 않으면, global%ArrayBuffer%를 사용하여 생성된 새 ArrayBufferassertionCreationData.userHandleResult의 바이트를 포함합니다.

      [[clientExtensionsResults]]

      global%ArrayBuffer%를 사용하여 생성된 새 ArrayBufferassertionCreationData.clientExtensionResults의 바이트를 포함합니다.

    7. 남아 있는authenticator에 대해 authenticatorCancel을 호출하고 issuedRequests에서 제거합니다.

    8. pubKeyCred를 반환하고 이 알고리즘을 종료합니다.

  21. "NotAllowedError" DOMException을 던집니다.

5.1.4.2. 인증기에게 자격 증명 요청 발행

[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)의 하위 알고리즘은 주어진 credential을 주어진 authenticator에 요청하기 위해 필요한, UI 문맥에 독립적인 구체적인 단계를 포괄합니다. 이 알고리즘은 [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)에서 현재의 user mediation 유형(예: conditional mediation 등)에 따라 여러 지점에서 호출됩니다.

이 알고리즘은 다음 인수들을 받습니다:

authenticator

이 값은 이 client platform에 현재 연결된 authenticator를 식별하는 플랫폼별 핸들입니다.

savedCredentialIds

이 인수는 map이며, authenticatorcredential ID를 포함합니다. 이 알고리즘에서 이 인수는 수정됩니다.

pkOptions

이 인수는 PublicKeyCredentialRequestOptions 객체로, 검색할 public key credential의 원하는 속성을 지정합니다.

rpId

요청의 RP ID입니다.

clientDataHash

clientDataJSON로 표현된 직렬화된 클라이언트 데이터의 해시입니다.

authenticatorExtensions

이 인수는 map이며, extension identifiers를 키로 하고 base64url 인코딩client extension processing 결과(인증기 확장용)를 값으로 가집니다.

이 알고리즘은 authenticator가 요청을 처리할 수 없다고 client가 판단하면 false를 반환하고, 요청이 성공적으로 발행되면 true를 반환합니다.

인증기에게 자격 증명 요청을 발행하는 단계는 다음과 같습니다:

  1. 만약 pkOptions.userVerificationrequired 로 설정되어 있고 authenticatoruser verification을 수행할 수 없다면, false를 반환합니다.

  2. userVerification어설션에 대한 유효한 user verification 요구사항인 불리언 값으로 둡니다. 만약 pkOptions.userVerification

    required로 설정된 경우

    userVerificationtrue로 둡니다.

    preferred로 설정된 경우

    만약 해당 authenticator

    user verification을 수행할 수 있다면

    userVerificationtrue로 둡니다.

    user verification을 수행할 수 없다면

    userVerificationfalse로 둡니다.

    discouraged로 설정된 경우

    userVerificationfalse로 둡니다.

  3. 만약 pkOptions.allowCredentials

    비어있지 않다면
    1. allowCredentialDescriptorList를 새 list로 둡니다.

    2. client platform별 절차를 실행하여, pkOptions.allowCredentials에 기술된 어떤 public key credentials이 이 authenticatorbound되어 있는지를 rpId와 각 항목의 id, type과 대조하여 판단합니다. 그 필터링된 리스트를 allowCredentialDescriptorList로 설정합니다.

    3. 만약 allowCredentialDescriptorList비어있다면, false를 반환합니다.

    4. distinctTransports를 새 ordered set으로 둡니다.

    5. 만약 allowCredentialDescriptorList에 정확히 하나의 값이 있으면, savedCredentialIds[authenticator]allowCredentialDescriptorList[0].id의 값으로 설정합니다(자세한 내용은 여기§ 6.3.3 The authenticatorGetAssertion Operation를 참조하세요).

    6. 각각의 자격 증명 디스크립터 C에 대해 각 항목의 C.transports 값을 distinctTransports에 추가합니다(있는 경우).

      참고: 이는 ordered set의 성질에 따라 distinctTransports에 중복 없이 전송 값들만 집계하게 됩니다.

    7. 만약 distinctTransports

      비어있지 않다면

      클라이언트는 distinctTransports에서 하나의 transport 값을 선택합니다. 이 선택은 해당 authenticator에 적합한 전송 수단에 대한 로컬 구성 지식을 반영할 수 있습니다.

      그런 다음, 선택된 transport를 사용하여 authenticator에 대해 authenticatorGetAssertion 연산을 rpId, clientDataHash, allowCredentialDescriptorList, userVerification, 및 authenticatorExtensions를 인수로 호출합니다.

      비어있다면

      해당 authenticator에 적합한 전송 수단에 대한 로컬 구성 지식을 사용하여, authenticatorGetAssertion 연산을 authenticator에 대해 rpId, clientDataHash, allowCredentialDescriptorList, userVerification, 및 authenticatorExtensions를 인수로 호출합니다.

    비어 있음

    해당 authenticator에 적합한 전송 수단에 대한 로컬 구성 지식을 사용하여, authenticatorGetAssertion 연산을 authenticator에 대해 rpId, clientDataHash, userVerification, 및 authenticatorExtensions를 인수로 호출합니다.

    참고: 이 경우에는 Relying Party가 허용 가능한 자격 증명 디스크립터 목록을 제공하지 않았으므로, 인증기는 rpId로 식별되는 범위(scope)에 해당하는 어떤 자격 증명이든 사용하도록 요청받는 것입니다.

  4. true를 반환합니다.

5.1.4.3. 요청 예외 처리

이 섹션은 규범적이지 않습니다.

WebAuthn 신뢰 당사자navigator.credentials.get() 호출에서 여러 예외를 만날 수 있습니다. 몇몇 예외는 여러 가지 이유로 인해 발생할 수 있으므로, WebAuthn 신뢰 당사자가 실제 원인을 WebAuthn의 사용에 따라 유추해야 합니다.

참고: 이 사양 외부에서 정의된 것을 포함하여, 모든 WebAuthn 확장 처리 중 발생할 수 있는 예외는 여기에 나열되어 있지 않습니다.

다음 DOMException 예외가 발생할 수 있습니다:

AbortError

ceremony가 AbortController에 의해 취소되었습니다. § 5.6 AbortSignal로 작업 취소하기§ 1.3.4 인증 작업 중단하기를 참고하세요.

SecurityError

유효 도메인올바른 도메인이 아니거나, rp.id유효 도메인과 같지 않거나 그(의) 등록 가능한 도메인 접미사가 아니었습니다. 후자의 경우, 클라이언트관련 origin 요청을 지원하지 않거나, 관련 origin 검증 절차가 실패한 것입니다.

NotAllowedError

다양한 원인을 포함한 catch-all 오류로, ceremony에서 사용자가 취소하는 등 일반적인 사유도 포함됩니다. 일부 원인은 명세 전반에 문서화되어 있으며 다른 원인은 클라이언트별로 다를 수 있습니다.

다음 간단한 예외가 발생할 수 있습니다:

TypeError

options 인자가 유효한 CredentialRequestOptions 값이 아니었습니다.

5.1.5. 기존 자격 증명 저장 - PublicKeyCredential의 [[Store]](credential, sameOriginWithAncestors) 내부 메서드

[[Store]](credential, sameOriginWithAncestors) 메서드는 Web Authentication의 PublicKeyCredential 타입에 대해 지원되지 않으므로, [[Store]](credential, sameOriginWithAncestors) 내부 메서드는 항상 오류를 던집니다.

Note: 이 알고리즘은 동기적이며; Promise 의 해결/거절 처리는 navigator.credentials.store()에서 이루어집니다.

이 내부 메서드는 두 개의 인수를 받습니다:

credential

이 인수는 PublicKeyCredential 객체입니다.

sameOriginWithAncestors

이 인수는 Boolean 값으로, 호출자의 environment settings object조상들과 same-origin인지에 따라 true가 됩니다.

이 메서드가 호출되면 사용자 에이전트는 다음 알고리즘을 반드시 실행해야 합니다:

  1. "NotSupportedError" DOMException을 던집니다.

5.1.6. User-Verifying Platform Authenticator의 가용성 - PublicKeyCredential의 isUserVerifyingPlatformAuthenticatorAvailable() 메서드

WebAuthn Relying Parties는 이 메서드를 사용하여 user-verifying platform authenticator를 사용해 새 자격 증명을 생성할 수 있는지 판단합니다. 호출 시 clientclient platform별 절차를 사용해 사용 가능한 user-verifying platform authenticators을 검색합니다. 하나라도 발견되면 프라미스는 true로 해결되고, 그렇지 않으면 false로 해결됩니다. 결과에 따라 Relying Party는 사용자에게 자격 증명 생성 유도 등 추가 동작을 취할 수 있습니다.

이 메서드는 인수가 없으며 불리언 값을 반환합니다.

partial interface PublicKeyCredential {
    static Promise<boolean> isUserVerifyingPlatformAuthenticatorAvailable();
};

5.1.7. 클라이언트 기능의 가용성 - PublicKeyCredential의 getClientCapabilities() 메서드

WebAuthn Relying Parties는 이 메서드를 사용하여 일부 워크플로우나 사용자 경험을 제공하기 위한 제한된 클라이언트 기능들의 가용성을 판단할 수 있습니다. 예를 들어, RP는 클라이언트에서 오직 hybrid 전송만 이용 가능하거나 conditional mediation이 불가능한 경우에만 표시되는 로그인 버튼을 제공할 수 있습니다(대신 사용자명 필드를 표시하는 대신).

호출 시 clientclient platform별 절차를 사용하여 이러한 기능들의 가용성을 검색합니다.

이 메서드는 인수가 없고, 기능 키를 불리언 값으로 매핑한 레코드를 반환합니다.

partial interface PublicKeyCredential {
    static Promise<PublicKeyCredentialClientCapabilities> getClientCapabilities();
};

typedef record<DOMString, boolean> PublicKeyCredentialClientCapabilities;

KeysPublicKeyCredentialClientCapabilities에서 사전식(오름차순)으로 정렬되어야 합니다. 키 집합은 ClientCapability의 열거값 집합을 포함하는 것이 좋지만, 클라이언트는 필요에 따라 키를 생략할 수 있습니다; 자세한 내용은 § 14.5.4 Disclosing Client Capabilities를 참조하세요.

특정 기능의 값이 true이면 그 기능이 현재 클라이언트에서 지원되는 것으로 알려진 것입니다. 값이 false이면 현재 지원되지 않는 것으로 알려진 것입니다. 어떤 키가 존재하지 않으면 해당 클라이언트 기능의 가용성은 알려지지 않은 것입니다.

키 집합은 또한 클라이언트가 구현한 각 확장에 대해 접두사로 문자열 extension:를 붙인 키를 포함하는 것이 권장됩니다. 해당 구현된 확장에 대한 값은 true여야 합니다. 만약 getClientCapabilities()가 클라이언트에서 지원되지만 어떤 확장이 true로 매핑되지 않았다면, Relying Party는 그 확장에 대한 클라이언트 처리 단계가 수행되지 않을 것이며, 확장이 인증기로 전달되지 않을 수 있다고 가정할 수 있습니다.

확장이 true로 매핑되어 있더라도, 특정 연산에 사용되는 인증기가 그 확장을 지원하지 않을 수 있으므로, Relying Parties는 인증기에서 그 확장의 처리가 수행될 것이라고 가정해서는 안 됩니다.

5.1.8. 등록 절차 옵션 역직렬화 - PublicKeyCredential의 parseCreationOptionsFromJSON() 메서드

WebAuthn Relying Parties는 이 메서드를 사용하여 JSON type 표현으로 된 navigator.credentials.create() 옵션을 PublicKeyCredentialCreationOptions로 변환합니다.

호출 시, 클라이언트options 인자를 새롭고 동일 구조의 PublicKeyCredentialCreationOptions 객체로 변환해야 하며, base64url 인코딩을 사용하여 DOMString 속성을 PublicKeyCredentialCreationOptionsJSON 에서 buffer source type 속성에 해당하는 PublicKeyCredentialCreationOptions 속성으로 디코딩해야 합니다. 이 변환은 클라이언트 확장 입력에도 적용되어야 하며 클라이언트에서 처리합니다.

AuthenticationExtensionsClientInputsJSON 은 IANA "WebAuthn Extension Identifiers" 레지스트리 [IANA-WebAuthn-Registries]에 등록된 확장을 포함할 수 있으나, § 9 WebAuthn Extensions에는 정의되지 않을 수 있습니다.

클라이언트JSON type 표현 구문을 파싱하는 과정에서 문제가 발생하면, "EncodingError" DOMException을 발생시키며, 호환되지 않는 값 설명과 함께 작업을 종료해야 합니다.

partial interface PublicKeyCredential {
    static PublicKeyCredentialCreationOptions parseCreationOptionsFromJSON(PublicKeyCredentialCreationOptionsJSON options);
};

dictionary PublicKeyCredentialCreationOptionsJSON {
    required PublicKeyCredentialRpEntity                    rp;
    required PublicKeyCredentialUserEntityJSON              user;
    required Base64URLString                                challenge;
    required sequence<PublicKeyCredentialParameters>        pubKeyCredParams;
    unsigned long                                           timeout;
    sequence<PublicKeyCredentialDescriptorJSON>             excludeCredentials = [];
    AuthenticatorSelectionCriteria                          authenticatorSelection;
    sequence<DOMString>                                     hints = [];
    DOMString                                               attestation = "none";
    sequence<DOMString>                                     attestationFormats = [];
    AuthenticationExtensionsClientInputsJSON                extensions;
};

dictionary PublicKeyCredentialUserEntityJSON {
    required Base64URLString        id;
    required DOMString              name;
    required DOMString              displayName;
};

dictionary PublicKeyCredentialDescriptorJSON {
    required DOMString              type;
    required Base64URLString        id;
    sequence<DOMString>             transports;
};

dictionary AuthenticationExtensionsClientInputsJSON {
};

5.1.9. 인증 절차 옵션 역직렬화 - PublicKeyCredential의 parseRequestOptionsFromJSON() 메서드들

WebAuthn Relying Parties는 이 메서드를 사용하여 JSON 타입으로 표현된 navigator.credentials.get()의 옵션들을 PublicKeyCredentialRequestOptions로 변환합니다.

호출 시 clientoptions 인수를 새롭고 동일한 구조의 PublicKeyCredentialRequestOptions 객체로 변환해야 하며, base64url 인코딩을 사용해 DOMString 속성들을 디코딩해야 합니다. 이 변환은 client extension inputs에도 적용되어야 합니다.

AuthenticationExtensionsClientInputsJSON 은 IANA "WebAuthn Extension Identifiers" 레지스트리에 등록된 확장들을 포함할 수 있으나, § 9 WebAuthn Extensions에 정의되지 않은 확장들도 허용될 수 있습니다.

만약 client가 JSON 타입 표현을 파싱하는 중 문제를 만나면, 호환되지 않는 값에 대한 설명을 포함한 "EncodingError" DOMException을 던지고 연산을 종료해야 합니다.

partial interface PublicKeyCredential {
    static PublicKeyCredentialRequestOptions parseRequestOptionsFromJSON(PublicKeyCredentialRequestOptionsJSON options);
};

dictionary PublicKeyCredentialRequestOptionsJSON {
    required Base64URLString                                challenge;
    unsigned long                                           timeout;
    DOMString                                               rpId;
    sequence<PublicKeyCredentialDescriptorJSON>             allowCredentials = [];
    DOMString                                               userVerification = "preferred";
    sequence<DOMString>                                     hints = [];
    AuthenticationExtensionsClientInputsJSON                extensions;
};

5.1.10. 인증기에게 자격 증명 변경 신호 전송 - PublicKeyCredential의 signal methods

partial interface PublicKeyCredential {
    static Promise<undefined> signalUnknownCredential(UnknownCredentialOptions options);
    static Promise<undefined> signalAllAcceptedCredentials(AllAcceptedCredentialsOptions options);
    static Promise<undefined> signalCurrentUserDetails(CurrentUserDetailsOptions options);
};

dictionary UnknownCredentialOptions {
    required DOMString                     rpId;
    required Base64URLString               credentialId;
};

dictionary AllAcceptedCredentialsOptions {
    required DOMString                     rpId;
    required Base64URLString               userId;
    required sequence<Base64URLString>     allAcceptedCredentialIds;
};

dictionary CurrentUserDetailsOptions {
    required DOMString                     rpId;
    required Base64URLString               userId;
    required DOMString                     name;
    required DOMString                     displayName;
};

WebAuthn Relying Parties는 이러한 signal methods를 사용하여 authenticators에게 public key credentials의 상태를 알릴 수 있으며, 이를 통해 잘못되었거나 폐기된 자격 증명을 업데이트, 제거 또는 숨기도록 할 수 있습니다. Clients는 인증기가 자신의 credentials map을 업데이트할 수 없거나 요청 시점에 연결되어 있지 않을 수 있으므로 이 기능을 기회에 따라 제공할 수 있습니다. 또한 사용자의 동의 없이 사용자의 자격 증명에 관한 정보를 노출하는 것을 피하기 위해, signal methods는 연산의 성공 여부를 나타내지 않습니다. 성공적으로 해결된 프라미스는 단지 options 객체가 올바르게 구성되었음을 의미할 뿐입니다.

signal methodauthenticator actions를 포함합니다. Authenticators는 권고된 대로 하지 않고 자체적으로 authenticator actions에서 벗어날 수 있습니다(예: 사용자의 의사에 반한다고 합리적으로 판단되는 변경을 무시하거나, 일부 변경에 대해 사용자에게 확인을 요청하는 등). 따라서 Authenticator actions는 signal methods를 처리하는 권장 방식으로 제공됩니다.

만약 어떤 authenticator가 특정 authenticator action을 처리할 능력이 없다면, clients는 동등한 효과를 달성하기 위해 [FIDO-CTAP]authenticatorCredentialManagement 명령과 같은 기존 인프라를 사용할 수 있습니다.

Note: Signal methods는 의도적으로 authenticatorsauthenticator actions를 완료할 때까지 기다리지 않습니다. 이 조치는 요청 시간에 따른 응답 타이밍으로 사용자의 자격 증명 가용성에 관한 정보를 사용자 동의 없이 WebAuthn Relying Parties가 얻는 것을 방지합니다.

5.1.10.1. 비동기 RP ID 검증 알고리즘

비동기 RP ID 검증 알고리즘signal methodsRP IDs를 병렬로 검증할 수 있게 합니다. 이 알고리즘은 DOMString rpId를 입력으로 받고, 검증이 실패하면 거절되는 프라미스를 반환합니다. 단계는 다음과 같습니다:

  1. effectiveDomain적합한 설정 객체origin실효 도메인으로 설정합니다. effectiveDomain유효 도메인이 아니라면, 거부된 promise "SecurityError" DOMException을 반환합니다.

  2. rpId등록 가능한 도메인 접미사이거나 동일한 경우 effectiveDomain, undefined로 resolve된 promise를 반환합니다.

  3. 클라이언트가 관련 origin 요청을 지원하지 않는 경우, 거부된 promise "SecurityError" DOMException을 반환합니다.

  4. p새 promise로 설정합니다.

  5. 다음 단계를 병렬로 실행합니다:

    1. 관련 origin 검증 절차callerOriginrpId를 인수로 실행한 결과가 true라면, p를 resolve합니다.

    2. 그 외의 경우, p "SecurityError" DOMException으로 reject합니다.

  6. p를 반환합니다.

5.1.10.2. signalUnknownCredential(options)

signalUnknownCredential 메서드는 특정 credential id가 WebAuthn Relying Party에 의해 인식되지 않았음을(예: 사용자가 삭제했음) 알리는 용도입니다. signalAllAcceptedCredentials(options)와 달리, 이 메서드는 전체 수락된 credential IDs 목록 및 userHandle를 전달할 필요가 없으므로, 인증되지 않은 호출자에게 프라이버시 유출을 피합니다(자세한 내용은 § 14.6.3 Privacy leak via credential IDs 참조).

signalUnknownCredential(options) 호출 시 client는 다음 단계를 실행합니다:

  1. 만약 base64url 디코딩 결과 options.credentialId가 오류이면, "TypeError"로 거절된 프라미스를 반환합니다.

  2. p비동기 RP ID 검증 알고리즘options.rpId로 실행한 결과로 둡니다.

  3. 프라미스 p가 이행되면, 다음 단계들을 병렬로 실행합니다:

    1. 현재 이 client platform에서 사용 가능한 모든 authenticator에 대해, unknownCredentialId authenticator actionoptions를 입력으로 하여 호출합니다.

  4. p를 반환합니다.

unknownCredentialId authenticator actionUnknownCredentialOptions options를 받아 다음과 같이 동작합니다:

  1. 각각의 해당 public key credential source credential에 대해, 그 authenticatorcredential map을 순회합니다:

    1. 만약 credentialrpIdoptions.rpId와 같고, credentialidbase64url 디코딩options.credentialId와 같다면, credentialcredentials map에서 제거하거나, 인증기별 절차를 사용해 이후의 authentication ceremonies에서 숨기도록 합니다.

사용자가 WebAuthn Relying Party가 제공하는 UI에서 credential을 삭제합니다. 이후 WebAuthn Relying Party에 로그인하려 시도할 때, 빈 allowCredentials가 제공되면, authenticator UI는 사용자가 이전에 삭제한 자격 증명을 제안할 수 있습니다. 사용자가 그 자격 증명을 선택하고 로그인 시도가 거부된 후, WebAuthn Relying Party는 다음을 실행합니다:

PublicKeyCredential.signalUnknownCredential({
    rpId: "example.com",
    credentialId: "aabbcc"  // 사용자가 방금 시도한 credential id, base64url
});

그 후 authenticator는 해당 credential을 삭제하거나 이후 인증 절차에서 숨깁니다.

5.1.10.3. signalAllAcceptedCredentials(options)

특정 사용자의 전체 credential ids 목록을 신호합니다. WebAuthn Relying Parties는 사용자가 인증된 상태이므로 프라이버시 유출 위험이 없는 경우(자세한 내용은 § 14.6.3 Privacy leak via credential IDs 참조) 이 메서드를 signalUnknownCredential()보다 선호해야 합니다. 전체 목록은 사용자의 public key credentials의 전체 스냅샷을 제공하며, 현재 연결된 인증기에 아직 보고되지 않은 변경 사항을 반영할 수 있습니다.

signalAllAcceptedCredentials(options) 호출 시 client는 다음 단계를 실행합니다:

  1. 만약 base64url 디코딩 결과 options.userId가 오류이면, "TypeError"로 거절된 프라미스를 반환합니다.

  2. 각각의 credentialId에 대해 options.allAcceptedCredentialIds:

    1. 만약 base64url 디코딩 결과 credentialId가 오류이면, "TypeError"로 거절된 프라미스를 반환합니다.

  3. p비동기 RP ID 검증 알고리즘options.rpId로 실행한 결과로 둡니다.

  4. 프라미스 p가 이행되면, 다음 단계들을 병렬로 실행합니다:

    1. 현재 이 client platform에서 사용 가능한 모든 authenticator에 대해, allAcceptedCredentialIds authenticator actionoptions를 입력으로 하여 호출합니다.

  5. p를 반환합니다.

allAcceptedCredentialIds authenticator actionsAllAcceptedCredentialsOptions options를 입력으로 받아 다음과 같이 동작합니다:

  1. userIdbase64url 디코딩의 결과로 두어라 options.userId.

  2. 단언: userId는 오류가 아니다.

  3. credentialcredentials map[options.rpId, userId]로 두어라.

  4. 만약 credential가 존재하지 않으면, 이 단계들을 중단한다.

  5. 만약 options.allAcceptedCredentialIds포함하지 않는다 base64url 인코딩credentialid의 결과를, 그러면 제거한다 credentialcredentials map에서 또는 향후 authentication ceremonies에서 숨기기 위한 authenticator-특정 절차를 사용한다.

  6. 그렇지 않으면, 만약 credentialauthenticator-특정 절차에 의해 숨겨졌다면, 해당 동작을 되돌려 credential이 향후 authentication ceremonies에 포함되도록 한다.

사용자는 두 개의 credential ids(credential ids)를 가지고 있으며, 이들이 base64url로 인코딩되면 aabb가 됩니다. 사용자가 credential aa를 WebAuthn Relying Party 제공 UI에서 삭제하면, Relying Party는 다음을 실행합니다:

PublicKeyCredential.signalAllAcceptedCredentials({
    rpId: "example.com",
    userId: "aabbcc",  // user handle, base64url.
    allAcceptedCredentialIds: [
        "bb",
    ]
});

실행 시 인증기(authenticator)가 연결되어 있으면, 해당 인증기는 aa에 해당하는 public key credential을 이후 인증 절차에서 삭제하거나 숨깁니다.

Note: 인증기들은 signalAllAcceptedCredentials(options)가 실행될 때 연결되어 있지 않을 수 있습니다. 따라서 WebAuthn Relying Parties는 예를 들어 매번 로그인 시마다 주기적으로 signalAllAcceptedCredentials(options)를 실행하는 것을 선택할 수 있습니다.

Note: allAcceptedCredentialIds에 포함되지 않은 자격 증명은 제거되거나 숨겨져 복구 불가능할 수 있습니다. Relying parties는 유효한 credential IDs가 목록에서 누락되지 않도록 주의해야 합니다. 만약 실수로 유효한 credential ID가 누락되었다면, 가능한 한 빨리 signalAllAcceptedCredentials(options)에 포함시켜(인증기가 지원하면) 다시 표시되게 해야 합니다.

Authenticators는 가능하면 자격 증명을 영구적으로 삭제하기보다는 일정 기간 숨기는 것을 권장합니다. 이는 Relying Party가 실수로 유효한 credential IDs를 목록에서 누락했을 때 복구에 도움이 됩니다.

5.1.10.4. signalCurrentUserDetails(options)

signalCurrentUserDetails 메서드는 사용자의 현재 namedisplayName을 신호합니다.

signalCurrentUserDetails(options) 호출 시 client는 다음 단계를 실행합니다:

  1. 만약 base64url 디코딩 결과 options.userId가 오류이면, "TypeError"로 거절된 프라미스를 반환합니다.

  2. p비동기 RP ID 검증 알고리즘options.rpId로 실행한 결과로 둡니다.

  3. 프라미스 p가 이행되면, 다음 단계들을 병렬로 실행합니다:

    1. 현재 이 client platform에서 사용 가능한 모든 authenticator에 대해, currentUserDetails authenticator actionoptions를 입력으로 하여 호출합니다.

  4. p를 반환합니다.

currentUserDetails authenticator actionCurrentUserDetailsOptions options를 입력으로 받아 다음과 같이 동작합니다:

  1. userIdbase64url 디코딩options.userId의 결과로 둡니다.

  2. 단언: userId가 오류가 아님을 보장합니다.

  3. credentialcredentials map[options.rpId, userId]로 둡니다.

  4. 만약 credential가 존재하지 않으면 이 단계를 중단합니다.

  5. credentialotherUIoptions.nameoptions.displayName에 맞게 업데이트합니다.

사용자가 WebAuthn Relying Party 제공 UI에서 자신의 이름을 업데이트합니다. Relying Party는 다음을 실행합니다:

PublicKeyCredential.signalCurrentUserDetails({
    rpId: "example.com",
    userId: "aabbcc",  // user handle, base64url.
    name: "New user name",
    displayName: "New display name",
});

그 후 authenticator는 일치하는 자격 증명의 otherUI를 업데이트합니다.

Note: 인증기들은 signalCurrentUserDetails(options)가 실행될 때 연결되어 있지 않을 수 있습니다. 따라서 WebAuthn Relying Parties는 예를 들어 매번 로그인 시마다 주기적으로 signalCurrentUserDetails(options)를 실행하는 것을 선택할 수 있습니다.

5.2. Authenticator Responses (interface AuthenticatorResponse)

AuthenticatorsRelying Party의 요청에 응답할 때 AuthenticatorResponse 인터페이스에서 파생된 객체를 반환합니다:

[SecureContext, Exposed=Window]
interface AuthenticatorResponse {
    [SameObject] readonly attribute ArrayBuffer      clientDataJSON;
};
clientDataJSON, of type ArrayBuffer, readonly

이 속성은 JSON-호환 직렬화client data를 포함하며, 그 해시가 클라이언트에 의해 create() 또는 get() 호출에서 인증기로 전달된다는 점에 유의해야 합니다(즉, client data 자체는 인증기로 전송되지 않습니다).

5.2.1. Information About Public Key Credential (interface AuthenticatorAttestationResponse)

The AuthenticatorAttestationResponse 인터페이스는 새 public key credential 생성을 위한 클라이언트의 요청에 대한 authenticator의 응답을 나타냅니다. 이 응답은 이후에 자격 증명을 식별하는 데 사용할 수 있는 새 자격 증명에 관한 정보와, 등록 시 WebAuthn Relying Party가 자격 증명의 특성을 평가하는 데 사용할 수 있는 메타데이터를 포함합니다.

[SecureContext, Exposed=Window]
interface AuthenticatorAttestationResponse : AuthenticatorResponse {
    [SameObject] readonly attribute ArrayBuffer      attestationObject;
    sequence<DOMString>                              getTransports();
    ArrayBuffer                                      getAuthenticatorData();
    ArrayBuffer?                                     getPublicKey();
    COSEAlgorithmIdentifier                          getPublicKeyAlgorithm();
};
clientDataJSON

이 속성은 AuthenticatorResponse로부터 상속되며, 인증기를 생성된 자격 증명에 대해 호출하도록 만든 클라이언트에서 전달한 JSON-호환 직렬화된 client data를 포함합니다(자세한 내용은 § 6.5 Attestation 참조). 정확한 JSON 직렬화는 보존되어야 하며, 이는 직렬화된 클라이언트 데이터의 해시가 해당 직렬화에 대해 계산되었기 때문입니다.

attestationObject, of type ArrayBuffer, readonly

이 속성은 attestation object를 포함합니다. 이 객체는 클라이언트에게는 불투명하며, 클라이언트로부터 변조되지 않도록 암호학적으로 보호됩니다. attestation objectauthenticator dataattestation statement를 모두 포함합니다. 전자는 AAGUID, 고유한 credential IDcredential public key를 포함합니다. attestation statement의 내용은 인증기가 사용하는 attestation statement format에 의해 결정됩니다. 또한 Relying Party의 서버가 attestation statement를 검증하고 authenticator dataJSON-호환 직렬화된 client data를 디코드하여 검증하는 데 필요한 추가 정보를 포함할 수 있습니다. 자세한 내용은 § 6.5 Attestation, § 6.5.4 Generating an Attestation Object, 및 Figure 6를 참조하세요.

getTransports()

이 연산은 [[transports]]의 값을 반환합니다.

getAuthenticatorData()

이 연산은 attestationObject에 포함된 authenticator data를 반환합니다. 자세한 내용은 § 5.2.1.1 Easily accessing credential data를 참조하세요.

getPublicKey()

이 연산은 새 자격 증명의 DER 형식 SubjectPublicKeyInfo를 반환하거나, 제공할 수 없는 경우 null을 반환합니다. 자세한 내용은 § 5.2.1.1 Easily accessing credential data를 참조하세요.

getPublicKeyAlgorithm()

이 연산은 새 자격 증명의 COSEAlgorithmIdentifier를 반환합니다. 자세한 내용은 § 5.2.1.1 Easily accessing credential data를 참조하세요.

[[transports]]

internal slot은 사전식 순서로 정렬된 0개 이상의 고유한 DOMString의 시퀀스를 포함합니다. 이 값들은 해당 authenticator가 지원하는 것으로 알려진 전송 수단이며, 정보가 없으면 빈 시퀀스가 됩니다. 값은 AuthenticatorTransport의 멤버여야 하지만, Relying Parties는 알 수 없는 값도 수락하고 저장해야 합니다.

5.2.1.1. Easily accessing credential data

모든 [[Create]](origin, options, sameOriginWithAncestors) 메서드 사용자는 반환된 credential public key를 구문 분석하여 저장해야 하며, 이는 향후 authentication assertions을 검증하는 데 필요합니다. 그러나 credential public key는 COSE 형식으로 되어 있어 attestedCredentialDatacredentialPublicKey 멤버 안의 CBOR 구조입니다. 이것은 authenticator data 안에 있고, attestation object에 포함되어 있고, 이 attestation object는 AuthenticatorAttestationResponseattestationObject입니다. Relying Parties는 attestation을 사용하려면 attestationObject를 구문 분석하고 credential public key를 얻어야 합니다. 이는 인증기가 서명한 공개키 복사본이기 때문입니다. 그러나 많은 유효한 WebAuthn 사용 사례에서는 attestation을 필요로 하지 않습니다. 그런 경우 사용자 에이전트가 구문 분석 작업을 수행하고 authenticator data를 직접 노출하며 credential public key를 더 편리한 형식으로 변환할 수 있습니다.

따라서 getPublicKey() 연산은 credential public keySubjectPublicKeyInfo로 반환합니다. 이 ArrayBuffer는 예를 들어 Java의 java.security.spec.X509EncodedKeySpec, .NET의 System.Security.Cryptography.ECDsa.ImportSubjectPublicKeyInfo, 또는 Go의 crypto/x509.ParsePKIXPublicKey에 전달할 수 있습니다.

getPublicKey() 사용에는 몇 가지 제한이 있습니다: pubKeyCredParams를 사용하여 Relying Party는 인증기와 협상하여 사용자 에이전트가 이해하지 못할 수 있는 공개키 알고리즘을 사용할 수 있습니다. 그러나 그렇게 하는 경우 사용자 에이전트는 결과 COSE 공개키를 SubjectPublicKeyInfo 형식으로 변환할 수 없으며 getPublicKey()의 반환값은 null이 됩니다.

사용자 에이전트는 getPublicKey()에 대해 null이 아닌 값을 반환할 수 있어야 하며, 그 조건은 credential public keyCOSEAlgorithmIdentifier 값이 다음 중 하나일 때입니다:

SubjectPublicKeyInfo는 COSE 공개키에 포함된 서명 알고리즘(예: 어떤 해시 함수를 사용할지)에 관한 정보를 포함하지 않습니다. 이를 제공하기 위해 getPublicKeyAlgorithm() 은 해당 credential public keyCOSEAlgorithmIdentifier를 반환합니다.

많은 경우 CBOR을 전혀 파싱할 필요를 제거하기 위해, getAuthenticatorData()attestationObject에서 authenticator data를 반환합니다. authenticator data는 다른 필드들을 바이너리 형식으로 인코딩하여 포함하지만, 해당 필드들에 접근하기 위한 헬퍼 함수는 제공되지 않습니다. 왜냐하면 Relying Parties는 어설션을 얻을 때 이미 그런 필드를 추출해야 하기 때문입니다. credential creation과 달리 어설션에서의 서명 검증은 항상 수행되어야 하므로, Relying Parties는 서명된 authenticator data에서 필드를 추출해야 하며, 동일한 함수들이 자격 증명 생성 시에도 사용됩니다.

Relying Parties는 이러한 함수들을 사용하기 전에 기능 감지를 수행하여 'getPublicKey' in AuthenticatorAttestationResponse.prototype의 값을 확인해야 합니다.

Note: getPublicKey()getAuthenticatorData() 는 본 명세의 Level 2에서만 추가되었습니다. 이러한 함수들이 존재해야 하는 Relying Parties는 오래된 사용자 에이전트와 상호운용되지 않을 수 있습니다.

5.2.2. Web Authentication Assertion (interface AuthenticatorAssertionResponse)

The AuthenticatorAssertionResponse 인터페이스는 authenticator가 Relying Party의 challenge 및 선택적 자격 증명 목록을 받고 생성한 새로운 authentication assertion에 대한 응답을 나타냅니다. 이 응답은 credential private key의 보유를 증명하는 암호화 서명과, 선택적으로 특정 거래에 대한 사용자 동의에 대한 증거를 포함합니다.

[SecureContext, Exposed=Window]
interface AuthenticatorAssertionResponse : AuthenticatorResponse {
    [SameObject] readonly attribute ArrayBuffer      authenticatorData;
    [SameObject] readonly attribute ArrayBuffer      signature;
    [SameObject] readonly attribute ArrayBuffer?     userHandle;
};
clientDataJSON

이 속성은 AuthenticatorResponse로부터 상속되며, 인증기를 어설션 생성에 사용하도록 만든 클라이언트에서 전달한 JSON-호환 직렬화된 client data를 포함합니다 (자세한 내용은 § 5.8.1 Client Data Used in WebAuthn Signatures (dictionary CollectedClientData) 참조). 정확한 JSON 직렬화는 보존되어야 하며, 직렬화된 클라이언트 데이터의 해시가 해당 직렬화에 대해 계산되었기 때문입니다.

authenticatorData, of type ArrayBuffer, readonly

이 속성은 인증기가 반환한 authenticator data를 포함합니다. 자세한 내용은 § 6.1 Authenticator Data를 참조하세요.

signature, of type ArrayBuffer, readonly

이 속성은 인증기에서 반환한 원시 서명을 포함합니다. 자세한 내용은 § 6.3.3 The authenticatorGetAssertion Operation을 참조하세요.

userHandle, of type ArrayBuffer, readonly, nullable

이 속성은 인증기가 반환한 user handle를 포함하거나, 인증기가 user handle을 반환하지 않으면 null을 가집니다. 자세한 내용은 § 6.3.3 The authenticatorGetAssertion Operation을 참조하세요. 만약 authentication ceremony에서 사용된 allowCredentials 옵션이 비어있다면, 인증기는 반드시 user handle을 반환해야 하며, 그 외의 경우에는 반환해도 됩니다.

5.3. Parameters for Credential Generation (dictionary PublicKeyCredentialParameters)

dictionary PublicKeyCredentialParameters {
    required DOMString                    type;
    required COSEAlgorithmIdentifier      alg;
};
이 dictionary는 새 자격 증명을 생성할 때 추가 매개변수를 제공하는 데 사용됩니다.
type, of type DOMString

이 멤버는 생성하려는 자격 증명의 유형을 지정합니다. 값은 PublicKeyCredentialType의 멤버여야 하는 것이 권장되지만, client platforms는 알 수 없는 값을 반드시 무시해야 하며, 알 수 없는 PublicKeyCredentialParameters 항목은 무시되어야 합니다.

alg, of type COSEAlgorithmIdentifier

이 멤버는 새로 생성될 자격 증명에 사용할 암호화 서명 알고리즘을 지정하며, 따라서 생성될 비대칭 키 쌍의 유형(예: RSA 또는 타원곡선)을 결정합니다.

Note: 우리는 여기서 멤버 이름으로 "algorithm"을 풀어 쓰지 않고 "alg"를 사용하는데, 이는 인증기로 전송될 메시지에 직렬화될 때 저대역폭 링크를 통해 전송될 수 있기 때문입니다.

5.4. Options for Credential Creation (dictionary PublicKeyCredentialCreationOptions)

dictionary PublicKeyCredentialCreationOptions {
    required PublicKeyCredentialRpEntity         rp;
    required PublicKeyCredentialUserEntity       user;

    required BufferSource                             challenge;
    required sequence<PublicKeyCredentialParameters>  pubKeyCredParams;

    unsigned long                                timeout;
    sequence<PublicKeyCredentialDescriptor>      excludeCredentials = [];
    AuthenticatorSelectionCriteria               authenticatorSelection;
    sequence<DOMString>                          hints = [];
    DOMString                                    attestation = "none";
    sequence<DOMString>                          attestationFormats = [];
    AuthenticationExtensionsClientInputs         extensions;
};
rp, of type PublicKeyCredentialRpEntity

이 멤버는 요청에 대해 책임이 있는 Relying Party의 이름과 식별자를 포함합니다.

그 값의 name 멤버는 필수입니다. 자세한 내용은 § 5.4.1 Public Key Entity Description (dictionary PublicKeyCredentialEntity)를 참조하십시오.

그 값의 id 멤버는 자격 증명이 범위(scope)되어야 하는 RP ID를 지정합니다. 생략된 경우, 그 값은 CredentialsContainer 객체의 관련 설정 객체origineffective domain이 됩니다. 자세한 내용은 § 5.4.2 Relying Party Parameters for Credential Generation (dictionary PublicKeyCredentialRpEntity)를 참조하십시오.

user, of type PublicKeyCredentialUserEntity

이 멤버는 등록을 수행하는 사용자 계정에 대한 이름들과 식별자를 포함합니다.

그 값의 name, displayNameid 멤버는 필수입니다. id 는 향후 일부 인증 절차에서 userHandle 로 반환될 수 있으며, 동일한 rp.iduser.id 를 가진 발견 가능한(discoverable) 자격 증명을 덮어쓰는 데 사용됩니다. namedisplayName 는 향후 인증 절차에서 자격 증명 선택을 돕기 위해 authenticatorclient에 의해 사용될 수 있으나, 향후 인증 절차의 결과로 Relying Party에 반환되지는 않습니다.

자세한 내용은 § 5.4.1 Public Key Entity Description (dictionary PublicKeyCredentialEntity)§ 5.4.3 User Account Parameters for Credential Generation (dictionary PublicKeyCredentialUserEntity)를 참조하십시오.

challenge, of type BufferSource

이 멤버는 새로 생성된 자격 증명에 대한 attestation object를 생성할 때 authenticator가 다른 데이터와 함께 서명하는 챌린지를 지정합니다. 보안 고려사항은 § 13.4.3 Cryptographic Challenges를 참조하십시오.

pubKeyCredParams, of type sequence<PublicKeyCredentialParameters>

이 멤버는 Relying Party가 지원하는 키 유형과 서명 알고리즘을 선호도 순서(가장 선호하는 것부터 덜 선호하는 것 순)로 나열합니다. 중복은 허용되지만 사실상 무시됩니다. 클라이언트authenticator 는 가능한 한 가장 선호되는 유형의 자격 증명을 생성하려 최선을 다합니다. 나열된 유형 중 어느 것도 생성할 수 없으면 create() 작업은 실패합니다.

광범위한 authenticator를 지원하려는 Relying Parties는 적어도 다음의 COSEAlgorithmIdentifier 값을 포함하는 것이 권장됩니다:

  • -8 (EdDSA)

  • -7 (ES256)

  • -257 (RS256)

추가적인 서명 알고리즘은 필요에 따라 포함할 수 있습니다.

다음은 [RFC9864]에서 도입된 완전 명세된 COSEAlgorithmIdentifier 값들로, pubKeyCredParams에 포함하는 것은 권장되지 않습니다:

  • -9 (ESP256); 대신 -7 (ES256)를 사용하거나 병행 사용하십시오.

  • -51 (ESP384); 대신 -35 (ES384)를 사용하거나 병행 사용하십시오.

  • -52 (ESP512); 대신 -36 (ES512)를 사용하거나 병행 사용하십시오.

  • -19 (Ed25519); 대신 -8 (EdDSA)를 사용하거나 병행 사용하십시오.

Note: WebAuthn 내에서 값 -9 (ESP256), -51 (ESP384), -52 (ESP512) 및 -19 (Ed25519)는 각각 추가 제약으로 인해 -7 (ES256), -35 (ES384), -36 (ES512) 및 -8 (EdDSA)와 동일한 것을 나타냅니다. 그러나 많은 구현체가 후자의 식별자를 지원하지만 전자를 지원하지 않는 경우가 있어 실무에서는 교환 가능하지 않습니다. 따라서 호환성을 위해 pubKeyCredParams 에는 후자의 식별자가 선호됩니다.

timeout, of type unsigned long

이 선택적 멤버는 Relying Party가 호출이 완료되기를 대기할 의사가 있는 시간(밀리초)을 지정합니다. 이는 힌트로 취급되며 client에 의해 재정의될 수 있습니다.

excludeCredentials, of type sequence<PublicKeyCredentialDescriptor>, defaulting to []

Relying Party 는 이 선택적 멤버를 사용하여 이 자격 증명이 매핑된 기존의 사용자 계정에 대응하는 자격 증명들을 나열해야 합니다 (식별은 user.id로 합니다). 이는 새 자격 증명이 이미 해당 authenticator에 존재하는 해당 사용자 계정에 매핑된 자격 증명 위에 생성되는 것을 방지합니다. 만약 그렇게 된다면, client는 사용자가 다른 authenticator를 사용하도록 안내하거나, 실패 시 오류를 반환해야 합니다.

authenticatorSelection, of type AuthenticatorSelectionCriteria

Relying Party 는 이 선택적 멤버를 사용하여 authenticator가 create() 작업에 참여하기 위해 반드시 또는 권장되게 만족해야 하는 기능 및 설정을 지정할 수 있습니다. 자세한 내용은 § 5.4.4 Authenticator Selection Criteria (dictionary AuthenticatorSelectionCriteria)를 참조하십시오.

hints, of type sequence<DOMString>, defaulting to []

이 OPTIONAL 멤버는 PublicKeyCredentialHint에서 하나 이상의 요소를 포함할 수 있으며, 사용자 에이전트가 사용자와 상호작용할 때 가이드로 사용됩니다. 요소들은 해당 열거형에서 가져왔지만 DOMString 타입임을 주의하세요. 자세한 내용은 § 2.1.1 Enumerations as DOMString types를 참조하세요.

attestation, of type DOMString, defaulting to "none"

Relying Party 는 이 선택적 멤버를 사용하여 attestation conveyance에 관한 선호도를 지정할 수 있습니다. 그 값은 AttestationConveyancePreference 의 멤버여야 합니다. 클라이언트 플랫폼은 알 수 없는 값을 무시해야 하며, 알 수 없는 값을 멤버가 존재하지 않는 것처럼 처리해야 합니다.

기본값은 none입니다.

attestationFormats, of type sequence<DOMString>, defaulting to []

Relying Party 는 이 선택적 멤버를 사용하여 attestation 진술 형식에 관한 선호도를 지정할 수 있습니다. 값들은 IANA "WebAuthn Attestation Statement Format Identifiers" 레지스트리에서 가져오는 것이 권장됩니다. 값들은 가장 선호되는 것부터 덜 선호되는 것 순으로 정렬됩니다. 중복은 허용되지만 사실상 무시됩니다. 이 매개변수는 권고적이며 authenticator는 이 매개변수에 열거되지 않은 attestation statement를 사용할 수 있습니다.

기본값은 빈 리스트로, 선호가 없음을 나타냅니다.

extensions, of type AuthenticationExtensionsClientInputs

Relying Party 는 이 선택적 멤버를 사용하여 클라이언트 확장 입력을 제공할 수 있으며, 이는 clientauthenticator에 의해 추가 처리를 요청합니다. 예를 들어, Relying Party는 생성된 credential에 대한 추가 정보를 클라이언트가 반환하도록 요청할 수 있습니다.

확장 프레임워크는 § 9 WebAuthn Extensions에 정의되어 있습니다. 일부 확장은 § 10 Defined Extensions에 정의되어 있습니다; 최신 등록된 WebAuthn Extensions 목록은 IANA "WebAuthn Extension Identifiers" 레지스트리([IANA-WebAuthn-Registries])를 참조하십시오.

5.4.1. 공개 키 엔터티 설명 (dictionary PublicKeyCredentialEntity)

PublicKeyCredentialEntity 딕셔너리는 사용자 계정 또는 WebAuthn Relying Party를 설명하며, 공개 키 자격 증명이 각각 연결되거나 범위 지정된 대상을 의미합니다.

dictionary PublicKeyCredentialEntity {
    required DOMString    name;
};
name, of type DOMString

엔터티를 위한 사람이 이해하기 쉬운(human-palatable) 이름입니다. 그 기능은 PublicKeyCredentialEntity 가 무엇을 나타내는지에 따라 달라집니다:

  • [DEPRECATED] PublicKeyCredentialRpEntity에서 상속될 경우, 이는 표시용으로만 의도된 사람이 이해하기 쉬운 Relying Party 식별자입니다. 예: "ACME Corporation", "Wonderful Widgets, Inc." 또는 "ОАО Примертех".

    많은 clients가 이를 표시하지 않기 때문에 이 멤버는 더 이상 권장되지 않지만, 하위 호환성을 위해 여전히 필수 딕셔너리 멤버로 남아 있습니다. Relying Parties는 안전한 기본값으로 이 값을 RP ID와 같게 설정해도 됩니다 (MAY).

    • Relying Parties[RFC8266]의 Section 2.3에 명시된 바와 같이 Nickname Profile of the PRECIS FreeformClass에 대한 적용 규칙을, name의 값을 설정하거나 사용자에게 값을 표시할 때 수행해야 합니다 (SHOULD).

    • Clients는 사용자에게 값을 표시하기 전에 또는 authenticatorMakeCredential 연산의 파라미터로 값을 포함하기 전에, 동일한 RFC 규정(Section 2.3)을 적용해야 합니다 (SHOULD).

  • PublicKeyCredentialUserEntity에서 상속될 경우, 이는 사용자 계정(user account)을 위한 사람이 이해하기 쉬운 식별자입니다. 이 식별자는 Clients가 자격 증명이 어떤 사용자 계정과 연결되는지를 사용자에게 이해시키기 위해 주로 표시하는 값입니다.

    이 식별자에 적합한 값의 예로는 "alexm", "+14255551234", "alex.mueller@example.com", "alex.mueller@example.com (prod-env)" 또는 "alex.mueller@example.com (ОАО Примертех)" 등이 있습니다.

    • Relying Party는 사용자가 이 값을 선택하도록 허용할 수 있습니다 (MAY). Relying Party는 값을 설정하거나 사용자에게 표시할 때, [RFC8265]의 Section 3.4.3에 명시된 UsernameCasePreserved Profile of the PRECIS IdentifierClass에 따른 적용 규칙을 수행해야 합니다 (SHOULD).

    • Clients는 사용자에게 값을 표시하기 전에 또는 authenticatorMakeCredential 연산의 파라미터로 값을 포함하기 전에, 동일한 RFC 규정(Section 3.4.3)에 따른 적용 규칙을 수행해야 합니다 (SHOULD).

clients, client platforms, 또는 authenticatorsname의 값을 표시할 때에는, 표시된 값 주위에 명확한 경계를 제공하는 UI 요소를 항상 사용하고 다른 요소로 넘치지 않도록 해야 합니다 [css-overflow-3].

name 멤버의 값을 저장할 때에는, 그 값을 § 6.4.1 String Truncation에 설명된 대로, 64바이트 이상인 크기 제한을 사용하여 잘라낼 수 있습니다 (MAY).

5.4.2. 자격 증명 생성을 위한 Relying Party 파라미터 (dictionary PublicKeyCredentialRpEntity)

PublicKeyCredentialRpEntity 딕셔너리는 새 자격 증명을 생성할 때 추가적인 Relying Party 속성을 제공하는 데 사용됩니다.

dictionary PublicKeyCredentialRpEntity : PublicKeyCredentialEntity {
    DOMString      id;
};
id, of type DOMString

Relying Party 엔터티에 대한 고유 식별자이며, RP ID를 설정합니다.

5.4.3. 자격 증명 생성을 위한 사용자 계정 파라미터 (dictionary PublicKeyCredentialUserEntity)

PublicKeyCredentialUserEntity 딕셔너리는 새로운 자격 증명 생성시 추가 사용자 계정 속성을 제공하는 데 사용됩니다.

dictionary PublicKeyCredentialUserEntity : PublicKeyCredentialEntity {
    required BufferSource   id;
    required DOMString      displayName;
};
id, of type BufferSource

사용자 핸들사용자 계정의 것입니다. 사용자 핸들은 최대 크기가 64바이트인 불투명한 바이트 시퀀스이며 사용자에게 표시될 목적으로 만들어진 것이 아닙니다.

안전한 작동을 보장하기 위해 인증 및 권한 부여 결정은 이 id 멤버를 기준으로 내려져야 하며, displayName 또는 name 멤버를 기준으로 내려져서는 안 됩니다. 자세한 내용은 [RFC8266]의 섹션 6.1을 참조하십시오.

사용자 핸들에는 사용자 이름이나 이메일 주소와 같은 개인을 식별할 수 있는 정보가 포함되어서는 안 됩니다; 자세한 내용은 § 14.6.1 User Handle Contents를 참조하십시오. 사용자 핸들은 비어 있어서는 안 됩니다.

사용자 핸들은 일부 인증기가 항상 발견 가능한 자격 증명을 생성하기 때문에, 서로 다른 사용자 계정 간에 상수 값이어서는 안 됩니다(비발견형 자격 증명인 경우에도 마찬가지). 따라서 상수 사용자 핸들은 사용자가 해당 인증기를 동일한 Relying Party에서 둘 이상의 사용자 계정으로 사용하는 것을 방해할 수 있습니다.

displayName, of type DOMString

사람이 읽기 쉬운 이름으로, 표시용으로만 의도된 사용자 계정의 이름입니다. Relying Party는 사용자가 이를 선택하도록 허용해야 하며, 필요 이상으로 선택을 제한해서는 안 됩니다. 적절한 또는 사람이 읽기 쉬운 이름이 제공되지 않는 경우, Relying Party는 이 값을 빈 문자열로 설정해야 합니다.

이 식별자에 적합한 값의 예로는 "Alex Müller", "Alex Müller (ACME Co.)" 또는 "田中倫" 등이 있습니다.

  • Relying Parties[RFC8266]의 Section 2.3에 규정된 대로 Nickname Profile of the PRECIS FreeformClass에 대한 적용 규칙을 displayName을 비어 있지 않은 문자열로 설정하거나 비어 있지 않은 값을 사용자에게 표시할 때 적용해야 합니다 (SHOULD).

  • 클라이언트[RFC8266] Section 2.3에서 규정한 PRECIS FreeformClass의 Nickname Profile에 따라 [RFC8264] 를 준수해야 하며, displayName의 값을 사용자에게 비어있지 않은 값으로 표시하거나 authenticatorMakeCredential 작업의 파라미터로 비어있지 않은 값을 포함시키기 전에 적용해야 합니다.

clients, client platforms, 또는 authenticatorsdisplayName의 값을 표시할 때에는, 표시된 값 주위에 명확한 경계를 제공하는 UI 요소를 항상 사용하고 다른 요소로 넘치지 않도록 해야 합니다 [css-overflow-3].

displayName 멤버의 값을 저장할 때에는 § 6.4.1 String Truncation에 설명된 대로, 64바이트 이상인 크기 제한을 사용하여 값을 잘라낼 수 있습니다.

5.4.4. 인증기 선택 기준 (dictionary AuthenticatorSelectionCriteria)

WebAuthn Relying PartiesAuthenticatorSelectionCriteria 딕셔너리를 사용하여 인증기 속성에 대한 요구사항을 지정할 수 있습니다.

dictionary AuthenticatorSelectionCriteria {
    DOMString                    authenticatorAttachment;
    DOMString                    residentKey;
    boolean                      requireResidentKey = false;
    DOMString                    userVerification = "preferred";
};
authenticatorAttachment, of type DOMString

이 멤버가 존재하는 경우, 해당 authenticator는 지정된 authenticator attachment modality(§ 6.2.1 Authenticator Attachment Modality 참고)에 연결된 것만 필터링됩니다. 멤버가 없는 경우 모든 attachment modality가 허용됩니다. 값은 AuthenticatorAttachment의 멤버여야 하지만, 클라이언트 플랫폼은 알려지지 않은 값을 반드시 무시해야 하며, 알려지지 않은 값을 멤버가 존재하지 않는 것으로 간주합니다.

또한 authenticatorAttachment 멤버를 가진 PublicKeyCredential도 참고하십시오. 이는 성공적인 create() 또는 get() 연산에서 사용된 authenticator attachment modality가 무엇인지 알려줄 수 있습니다.

residentKey, of type DOMString

이 값은 Relying Party가 얼마나 client-side discoverable credential을 생성하기를 원하는지를 지정합니다. 역사적 이유로 명칭에는 더 이상 권장되지 않는 "resident" 용어가 남아 있습니다. 값은 ResidentKeyRequirement 의 멤버인 것이 바람직하지만, client platforms는 알 수 없는 값을 반드시 무시해야 하며, 알 수 없는 값은 해당 멤버가 존재하지 않는 것으로 처리합니다. 값이 주어지지 않으면 requiredrequireResidentKeytrue일 때의 실효값이며, discouraged 는 그것이 false이거나 없을 때의 실효값입니다.

ResidentKeyRequirement 에는 residentKey의 값과 의미에 대한 설명이 있습니다.

requireResidentKey, of type boolean, defaulting to false

이 멤버는 WebAuthn Level 1과의 하위 호환성을 위해 유지되며, 역사적 이유로 discoverable credentials에 대해 "resident" 용어를 유지합니다. Relying PartiesresidentKeyrequired 로 설정된 경우에만 이를 true로 설정해야 합니다.

userVerification, of type DOMString, defaulting to "preferred"

이 멤버는 Relying Partycreate() 연산에 대해 요구하는 user verification 관련 요구사항을 지정합니다. 값은 UserVerificationRequirement 의 멤버인 것이 바람직하지만, client platforms는 알 수 없는 값을 반드시 무시해야 하며, 알 수 없는 값은 해당 멤버가 존재하지 않는 것으로 처리합니다.

UserVerificationRequirement 에는 userVerification의 값과 의미에 대한 설명이 있습니다.

5.4.5. 인증기 연결 방식 열거형 (enum AuthenticatorAttachment)

이 열거형의 값은 인증기부착 방식을 설명합니다. 의존 당사자는 자격 증명을 생성하기 위해 navigator.credentials.create() 를 호출할 때 선호하는 인증기 부착 방식을 표현하기 위해 이를 사용하며, 클라이언트등록 또는 인증 절차를 완료하는 데 사용된 인증기 부착 방식을 보고하는 데 이를 사용합니다.

enum AuthenticatorAttachment {
    "platform",
    "cross-platform"
};

Note: The AuthenticatorAttachment enumeration is deliberately not referenced, see § 2.1.1 Enumerations as DOMString types.

platform

이 값은 플랫폼 부착을 나타냅니다.

cross-platform

이 값은 플랫폼 간 부착을 나타냅니다.

참고: 인증기 부착 방식 선택 옵션은 [[Create]](origin, options, sameOriginWithAncestors) 동작에서만 사용할 수 있습니다. Relying Party는 예를 들어 사용자가 다른 클라이언트 기기에서 인증할 수 있도록 로밍 인증 정보를 갖도록 하거나, 특정 클라이언트 기기에서 더 쉽게 재인증할 수 있도록 플랫폼 인증 정보를 등록하도록 사용할 수 있습니다. [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 동작에는 인증기 부착 방식 선택 옵션이 없습니다. 클라이언트와 사용자는 해당 시점에 사용 가능한 편리한 인증 정보를 사용하며, allowCredentials 옵션이 적용됩니다.

5.4.6. 리던트 키 요구사항 열거형 (enum ResidentKeyRequirement)

enum ResidentKeyRequirement {
    "discouraged",
    "preferred",
    "required"
};

참고: ResidentKeyRequirement 열거형은 의도적으로 참조되지 않습니다. 자세한 내용은 § 2.1.1 Enumerations as DOMString types를 참조하십시오.

이 열거형의 값들은 Relying Party클라이언트 측 검색 가능 자격 증명(이전 명칭: resident credentials 또는 resident keys)에 대해 갖는 요구사항을 설명합니다:

discouraged

Relying Party서버 측 자격 증명 생성을 선호하지만, 클라이언트 측 검색 가능 자격 증명도 허용합니다. 클라이언트authenticator 는 가능하다면 서버 측 자격 증명을 생성해야 합니다.

참고: Relying Party는 생성된 자격 증명이 반드시 서버 측 자격 증명이어야 한다고 요구할 수 없으며, Credential Properties Extensionrk 속성에 대한 값을 반환하지 않을 수 있습니다. 이 때문에 어떤 자격 증명이 서버 측 자격 증명인지 여부를 알지 못할 수 있으며, 따라서 동일한 user handle로 두 번째 자격 증명을 생성하면 첫 번째 자격 증명이 대체될지 알지 못할 수 있습니다.

preferred

Relying Party클라이언트 측 검색 가능 자격 증명의 생성을 강력히 선호하지만, 서버 측 자격 증명도 허용합니다. 클라이언트authenticator 는 가능하다면 검색 가능한 자격 증명을 생성해야 합니다. 예를 들어, 클라이언트사용자 검증이 필요하여 검색 가능한 자격 증명을 생성해야 하는 경우, 사용자가 이를 설정하도록 안내해야 합니다. 이는 userVerification 설정보다 우선합니다.

required

Relying Party클라이언트 측 검색 가능 자격 증명을 요구합니다. 클라이언트클라이언트 측 검색 가능 자격 증명을 생성할 수 없으면 오류를 반환해야 합니다.

참고: Relying Party클라이언트 측 검색 가능 자격 증명이 생성되었는지 여부에 대한 정보를 resident key credential property 를 통해 Credential Properties Extension에서 조회할 수 있습니다. 이는 discouraged 또는 preferredoptions.authenticatorSelection.residentKey 에 사용된 경우에 유용합니다. 이러한 경우에는 authenticator클라이언트 측 검색 가능 자격 증명이나 서버 측 자격 증명 중 어느 쪽이든 생성할 수 있기 때문입니다.

5.4.7. Attestation Conveyance 선호 열거형 (enum AttestationConveyancePreference)

WebAuthn 의존 당사자AttestationConveyancePreference 를 사용하여 자격 증명 생성 중의 attestation 전달 에 대한 선호도를 지정할 수 있습니다.

enum AttestationConveyancePreference {
    "none",
    "indirect",
    "direct",
    "enterprise"
};

참고: AttestationConveyancePreference 열거형은 의도적으로 참조되지 않습니다. 자세한 내용은 § 2.1.1 Enumerations as DOMString types를 참조하십시오.

none

신뢰 당사자인증자 입증에 관심이 없습니다. 예를 들어 사용자 동의를 얻거나 신뢰 당사자에 식별 정보를 전달하는 것을 피하거나, 입증 CA익명화 CA에 왕복 통신을 절약하기 위해 선택할 수 있습니다. 인증자입증문을 생성하는데, 그것이 자체 입증이 아닐 경우, 클라이언트가 이를 None 입증문으로 대체합니다.

이 값이 기본값이며, 알 수 없는 값은 이 동작으로 대체됩니다.

indirect

신뢰 당사자는 검증 가능한 입증문을 받고 싶어 하며, 클라이언트입증문을 어떻게 받을지 결정하게 허용합니다. 클라이언트는 인증자가 생성한 입증문익명화 CA가 생성한 것으로 대체할 수 있고, 이를 통해 사용자의 프라이버시를 보호하거나, 신뢰 당사자가 다양한 환경에서 입증 검증을 쉽게 할 수 있도록 도울 수도 있습니다.

참고: 이 경우 신뢰 당사자가 실제로 검증 가능한 입증문을 얻을 수 있다는 보장은 없습니다. 예를 들어 인증자가 자체 입증을 사용하고 클라이언트입증문을 수정 없이 전달하는 경우가 대표적입니다.

direct

신뢰 당사자인증자가 생성한 입증문을 그대로 받고 싶어 합니다.

enterprise

신뢰 당사자는 고유하게 인증자를 식별할 수 있는 정보를 포함할 수 있는 엔터프라이즈 입증(즉, 입증문)을 받고 싶어 합니다. 이는 조직이 특정 인증기에 등록을 연동하려는 기업 내부 배포 환경을 위한 것입니다. 사용자 에이전트는 요청된 RP ID에 대해 사용자 에이전트 또는 인증기 설정이 이를 허용하지 않는 한, 이러한 입증을 제공해서는 안 됩니다.

허용된 경우, 사용자 에이전트는 인증기(즉, 호출 시점)에 엔터프라이즈 입증이 요청됨을 신호하고, 생성된 AAGUID입증문을 수정 없이 신뢰 당사자에 전달해야 합니다.

5.5. 인증 생성 옵션 (dictionary PublicKeyCredentialRequestOptions)

PublicKeyCredentialRequestOptions 딕셔너리는 get() 이 인증을 생성하는 데 필요한 데이터를 제공합니다. challenge 멤버는 반드시 포함되어야 하며, 나머지 멤버는 선택적입니다.

dictionary PublicKeyCredentialRequestOptions {
    required BufferSource                challenge;
    unsigned long                        timeout;
    DOMString                            rpId;
    sequence<PublicKeyCredentialDescriptor> allowCredentials = [];
    DOMString                            userVerification = "preferred";
    sequence<DOMString>                  hints = [];
    AuthenticationExtensionsClientInputs extensions;
};
challenge, of type BufferSource

이 멤버는 authenticator가 다른 데이터와 함께 서명하여 authentication assertion을 생성할 때 사용되는 챌린지를 지정합니다. 자세한 보안 고려사항은 § 13.4.3 Cryptographic Challenges를 참조하십시오.

timeout, of type unsigned long

이 선택적 멤버는 Relying Party가 호출이 완료되기를 기다릴 의사가 있는 시간(밀리초)을 지정합니다. 이 값은 힌트로 취급되며 client에 의해 재정의될 수 있습니다.

rpId, of type DOMString

이 선택적 멤버는 RP ID를 지정하며, 이는 Relying Party가 주장하는 ID입니다. clientRelying Partyorigin이 이 RP IDscope와 일치하는지 확인해야 합니다. authenticator는 이 RP ID가 인증에 사용될 credentialrpId와 정확히 일치하는지 검증해야 합니다.

명시되지 않은 경우, 그 값은 CredentialsContainer 객체의 relevant settings objectorigineffective domain이 됩니다.

allowCredentials, of type sequence<PublicKeyCredentialDescriptor>, defaulting to []

이 선택적 멤버는 client가 이 authenticators 중 인증 절차에 적합한 것을 찾는 데 사용됩니다. 이 멤버는 두 가지 방식으로 사용될 수 있습니다:

만약 empty가 아닌 경우, 나열된 자격 증명 중 어느 것도 사용될 수 없다면 클라이언트는 오류를 반환해야 합니다.

userVerification, of type DOMString, defaulting to "preferred"

이 선택적 멤버는 Relying Partyget() 연산에 대해 요구하는 user verification 요건을 지정합니다. 값은 UserVerificationRequirement 의 멤버인 것이 바람직하지만, client platforms는 알 수 없는 값을 무시해야 하며, 알 수 없는 값은 해당 멤버가 존재하지 않는 것으로 처리해야 합니다. 적합한 authenticators는 이 요구를 만족할 수 있는 것들로 필터링됩니다.

UserVerificationRequirement 에는 userVerification의 값과 의미에 대한 설명이 있습니다.

hints, of type sequence<DOMString>, defaulting to []

이 선택적 멤버는 PublicKeyCredentialHint 에서 가져온 하나 이상의 요소를 포함하여 사용자 에이전트가 사용자와 상호작용하는 방법을 안내하도록 합니다. 요소들은 해당 열거형에서 가져온 값이지만 타입은 DOMString임에 유의하십시오. 자세한 내용은 § 2.1.1 Enumerations as DOMString types를 참조하십시오.

extensions, of type AuthenticationExtensionsClientInputs

Relying Party는 이 선택적 멤버를 사용하여 client extension inputs을 제공하여 clientauthenticator가 추가 처리를 수행하도록 요청할 수 있습니다.

확장 프레임워크는 § 9 WebAuthn Extensions에 정의되어 있습니다. 일부 확장은 § 10 Defined Extensions에 정의되어 있습니다; 최신 등록된 WebAuthn Extensions 목록은 IANA "WebAuthn Extension Identifiers" 레지스트리([IANA-WebAuthn-Registries]) 및 [RFC8809]를 참조하십시오.

5.6. AbortSignal을 사용한 연산 중단

개발자는 AbortController 를 활용하여 [[Create]](origin, options, sameOriginWithAncestors)[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 작업을 제어할 것을 권장합니다. 상세한 사용법은 DOM § 3.3 AbortController와 AbortSignal 객체의 API 통합 부분을 참고하세요.

참고: DOM § 3.3 AbortController와 AbortSignal 객체의 API 통합에 따르면, 웹 플랫폼 API가 AbortController와 연동될 경우, AbortSignalaborted 될 때 Promise를 즉시 reject 해야 합니다. [[Create]](origin, options, sameOriginWithAncestors)[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 메서드는 복잡한 상속과 병렬 구조로 인해, 두 API의 알고리즘은 해당 aborted 속성을 세 곳에서 점검함으로써 이 요건을 충족시킵니다. [[Create]](origin, options, sameOriginWithAncestors)의 경우, Credential Management 1 § 2.5.4 자격 증명 생성에서 [[Create]](origin, options, sameOriginWithAncestors) 호출 직전, § 5.1.3 새 자격 증명 생성 - PublicKeyCredential의 [[Create]](origin, options, sameOriginWithAncestors) 내부 메서드에서 인증기 세션 시작 직전, 그리고 마지막으로 authenticator 세션 내에서 속성을 확인합니다. [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)도 동일합니다.

5.7. WebAuthn 확장 입력과 출력

아래 세부 절에서는 WebAuthn 확장 입력과 출력을 전달하는 데 사용되는 데이터 타입을 정의합니다.

참고: 인증기 확장 출력인증기 데이터의 일부로 전달됩니다(표 1 참고).

참고: 아래에 정의된 타입인 AuthenticationExtensionsClientInputsAuthenticationExtensionsClientOutputs등록 확장인증 확장 모두에 적용됩니다. 이름의 "Authentication..." 부분은 "WebAuthentication..." 의미로 간주해야 합니다.

5.7.1. 인증 확장 클라이언트 입력 (dictionary AuthenticationExtensionsClientInputs)

dictionary AuthenticationExtensionsClientInputs {
};

이 사전은 0개 이상의 WebAuthn 확장에 대한 클라이언트 확장 입력 값을 담고 있습니다.

5.7.2. 인증 확장 클라이언트 출력 (dictionary AuthenticationExtensionsClientOutputs)

dictionary AuthenticationExtensionsClientOutputs {
};

이 사전은 0개 이상의 WebAuthn 확장에 대한 클라이언트 확장 출력 값을 담고 있습니다.

5.7.3. 인증 확장 인증기 입력 (CDDL type AuthenticationExtensionsAuthenticatorInputs)

AuthenticationExtensionsAuthenticatorInputs = {
  * $$extensionInput
} .within { * tstr => any }

CDDL 타입 AuthenticationExtensionsAuthenticatorInputs는 0개 이상의 WebAuthn 확장에 대한 인증기 확장 입력 값을 담고 있는 CBOR 맵을 정의합니다. 확장은 § 9.3 요청 파라미터 확장에 설명된 대로 멤버를 추가할 수 있습니다.

이 타입은 Relying Party에게 노출되지 않지만, 클라이언트인증기에서 사용됩니다.

5.7.4. 인증 확장 인증기 출력 (CDDL type AuthenticationExtensionsAuthenticatorOutputs)

AuthenticationExtensionsAuthenticatorOutputs = {
  * $$extensionOutput
} .within { * tstr => any }

CDDL 타입 AuthenticationExtensionsAuthenticatorOutputs는 0개 이상의 WebAuthn 확장에 대한 인증기 확장 출력 값을 담고 있는 CBOR 맵을 정의합니다. 확장은 § 9.3 요청 파라미터 확장에 설명된 대로 멤버를 추가할 수 있습니다.

5.8. 지원 데이터 구조

공개 키 자격 증명 타입은 지원 명세서에서 정의된 특정 데이터 구조를 사용합니다. 다음과 같습니다.

5.8.1. WebAuthn 서명에 사용되는 클라이언트 데이터 (dictionary CollectedClientData)

클라이언트 데이터WebAuthn Relying Party클라이언트 양쪽의 맥락적 바인딩을 나타냅니다. 이는 키가 문자열이고, 값은 JSON에서 유효하게 인코딩될 수 있는 어떤 타입이라도 될 수 있는 키-값 매핑입니다. 구조는 아래 Web IDL로 정의됩니다.

참고: CollectedClientData 는 향후 확장될 수 있습니다. 따라서 파싱 시 미지의 키와 키 순서 변경에 대해 유연하게 동작해야 합니다. § 5.8.1.2 제한된 검증 알고리즘도 참고하세요.

dictionary CollectedClientData {
    required DOMString           type;
    required DOMString           challenge;
    required DOMString           origin;
    boolean                      crossOrigin;
    DOMString                    topOrigin;
};

dictionary TokenBinding {
    required DOMString status;
    DOMString id;
};

enum TokenBindingStatus { "present", "supported" };
type, 유형 DOMString

이 멤버는 새로운 자격 증명을 생성할 때 "webauthn.create", 기존 자격 증명에서 인증 정보를 가져올 때는 "webauthn.get" 문자열을 포함합니다. 이 멤버의 목적은 공격자가 한 서명을 다른 서명으로 대체하는 특정 타입의 서명 혼동 공격을 방지하기 위함입니다.

challenge, 유형 DOMString

이 멤버는 Relying Party 가 제공한 챌린지의 base64url 인코딩 값을 포함합니다. § 13.4.3 암호화 챌린지의 보안 참고도 참고하세요.

origin, 유형 DOMString

이 멤버는 요청자의 완전히 한정된 origin 문자열을 포함합니다(클라이언트가 인증기에 제공), [RFC6454] 구문에 따라 지정됩니다.

crossOrigin, 유형 boolean

이 선택적 멤버는 내부 메서드로 전달된 sameOriginWithAncestors 인자의 반값을 담고 있습니다.

topOrigin, 유형 DOMString

이 선택적 멤버는 요청자의 완전히 한정된 최상위 origin 값을 포함하며, [RFC6454] 구문으로 지정됩니다. 이 값은 same-origin with its ancestors가 아닌 컨텍스트에서만 설정되며, 즉 crossOrigintrue일 경우에만 값이 있습니다.

[예약됨] tokenBinding

이 선택적 멤버는 Token Binding 프로토콜 [TokenBinding]의 상태에 관한 정보를 포함하며, Relying Party와 통신할 때 사용됩니다. 해당 멤버가 없으면 클라이언트가 토큰 바인딩을 지원하지 않음을 나타냅니다

참고: Token Binding은 WebAuthn Level 1, 2에는 있었지만 Level 3에서는 사용되지 않을 예정입니다. tokenBinding 필드는 다른 용도로 재사용되지 않도록 예약되어 있습니다.

status, 유형 DOMString

이 멤버는 TokenBindingStatus 의 멤버여야 하지만, 클라이언트 플랫폼은 알 수 없는 값을 무시하고, 해당 tokenBinding 멤버가 없는 것처럼 처리해야 합니다. 알고 있는 값은 다음 두 가지 중 하나입니다.

supported

클라이언트가 토큰 바인딩을 지원하지만 Relying Party와 통신 시 협상되지 않았음을 나타냅니다.

present

토큰 바인딩이 Relying Party와의 통신 시 사용되었음을 의미합니다. 이 경우 id 멤버가 반드시 존재해야 합니다.

참고: TokenBindingStatus 열거형은 의도적으로 참조되지 않았으며, § 2.1.1 DOMString 타입의 열거형 참고.

id, 유형 DOMString

이 멤버는 statuspresent인 경우 반드시 존재해야 하며, base64url 인코딩Token Binding ID로서 Relying Party와 통신할 때 사용된 값이어야 합니다.

참고: Token Binding ID클라이언트 플랫폼에 따라 획득 방식이 다릅니다.

CollectedClientData 구조는 클라이언트가 다음 값을 계산할 때 사용합니다:

클라이언트 데이터의 JSON 호환 직렬화

이는 CollectedClientData 사전에 JSON 호환 직렬화 알고리즘을 실행한 결과입니다.

직렬화된 클라이언트 데이터의 해시

이는 클라이언트가 구성한 클라이언트 데이터의 JSON 호환 직렬화에 대해 SHA-256을 이용해 계산한 해시입니다.

5.8.1.1. 직렬화

CollectedClientData 의 직렬화는 JSON 값을 바이트로 직렬화 알고리즘의 부분집합입니다. 즉, CollectedClientData 에 대한 유효한 JSON 인코딩을 산출하며, 또한 전체 JSON 파서를 통합하지 않고 검증자가 구조적으로 사용 가능한 추가 구조도 제공합니다. 검증자에게는 표준 JSON 구문 분석을 권장하지만, 전체 파서가 부담일 때는 아래 보다 제한적인 알고리즘을 사용할 수 있습니다. 이 검증 알고리즘은 base64url 인코딩, 바이트열 덧붙이기(고정 템플릿에 작성하는 식), 조건 분기(입력이 escape 필요 없음이 전제)만 있으면 됩니다.

직렬화 알고리즘은, 최초에는 빈 바이트열에 연속적으로 바이트열을 덧붙여 전체 결과를 완성합니다.

  1. result에 빈 바이트열을 할당합니다.

  2. 0x7b2274797065223a({"type":)를 result에 덧붙입니다.

  3. CCDToString(type) 을 result에 덧붙입니다.

  4. 0x2c226368616c6c656e6765223a(,"challenge":)를 result에 덧붙입니다.

  5. CCDToString(challenge) 을 result에 덧붙입니다.

  6. 0x2c226f726967696e223a(,"origin":)를 result에 덧붙입니다.

  7. CCDToString(origin) 을 result에 덧붙입니다.

  8. 0x2c2263726f73734f726967696e223a(,"crossOrigin":)를 result에 덧붙입니다.

  9. crossOrigin 이 없거나 false일 경우:

    1. 0x66616c7365(false)를 result에 덧붙입니다.

  10. 그 외의 경우:

    1. 0x74727565(true)를 result에 덧붙입니다.

  11. topOrigin 이 존재할 경우:

    1. 0x2c22746f704f726967696e223a(,"topOrigin":)를 result에 덧붙입니다.

    2. CCDToString(topOrigin) 을 result에 덧붙입니다.

  12. CollectedClientData 의 임시 복사본을 만들고, type, challenge, origin, crossOrigin (존재 시), topOrigin (존재 시)를 삭제합니다.

  13. 임시 복사본에 남은 필드가 없는 경우:

    1. 0x7d(})를 result에 덧붙입니다.

  14. 그 외의 경우:

    1. 임시 복사본에 serialize JSON to bytes를 적용해 바이트열 remainder를 만듭니다.

    2. 0x2c(,)를 result에 덧붙입니다.

    3. remainder에서 선두 바이트를 제거합니다.

    4. remainderresult에 덧붙입니다.

  15. 이 직렬화의 결과는 result의 값입니다.

위 알고리즘에서 사용하는 함수 CCDToString은 다음과 같이 정의됩니다:

  1. encoded에 빈 바이트열을 할당합니다.

  2. 0x22(")를 encoded에 덧붙입니다.

  3. 주어진 객체에 ToString을 적용해 문자열로 변환합니다.

  4. 문자열 내 각 코드포인트에 대해, 만약:

    {U+0020, U+0021, U+0023–U+005B, U+005D–U+10FFFF} 범위일 때

    해당 코드포인트의 UTF-8 바이너리를 encoded에 덧붙입니다.

    U+0022인 경우

    0x5c22(\")를 encoded에 덧붙입니다.

    U+005C인 경우

    0x5c5c(\\)를 encoded에 덧붙입니다.

    기타

    0x5c75(\u)와 해당 코드포인트 값을 16진법 4자리 소문자로 인코딩한 것을 encoded에 덧붙입니다.

  5. 0x22(")를 encoded에 덧붙입니다.

  6. 이 함수의 결과는 encoded의 값입니다.

5.8.1.2. 제한된 검증 알고리즘

전체 JSON 파서를 도입하기 어렵다면, 인코딩된 CollectedClientData 를 검증하기 위한 아래 알고리즘을 활용할 수 있습니다:

  1. 알고리즘의 입력값:

    1. clientDataJSON: clientDataJSON (직렬화된 CollectedClientData) 바이트열

    2. type: type에 들어갈 기대 문자열

    3. challenge: PublicKeyCredentialRequestOptions 혹은 PublicKeyCredentialCreationOptions 에 사용된 챌린지 바이트열

    4. origin: 사용자 에이전트에게 요청을 전달한 origin.

    5. 옵션 topOrigin: (있다면) topOrigin 기대값

    6. requireTopOrigin: topOrigin이 정의되어 있고 topOrigin 속성이 clientDataJSON에 없으면 검증 실패로 처리할지 여부(boolean).

      이 항목 덕분에, 이 알고리즘은 requireTopOriginfalse인 경우 WebAuthn LV2 JSON-compatible 직렬화 알고리즘 과 하위 호환됩니다.

  2. expected에 빈 바이트열 할당.

  3. 0x7b2274797065223a({"type":)를 expected에 덧붙임.

  4. CCDToString(type) 를 expected에 덧붙임.

  5. 0x2c226368616c6c656e6765223a(,"challenge":)를 expected에 덧붙임.

  6. challengebase64url 인코딩을 적용해 challengeBase64로 저장.

  7. CCDToString(challengeBase64) 를 expected에 덧붙임.

  8. 0x2c226f726967696e223a(,"origin":)를 expected에 덧붙임.

  9. CCDToString(origin) 을 expected에 덧붙임.

  10. 0x2c2263726f73734f726967696e223a(,"crossOrigin":)를 expected에 덧붙임.

  11. topOrigin이 정의되어 있다면:

    1. 0x74727565(true)를 expected에 덧붙임.

    2. requireTopOrigin이 true이거나 0x2c22746f704f726967696e223a(,"topOrigin":)이 clientDataJSONexpected 길이 위치에서 시작하는 접두사라면…

      1. 0x2c22746f704f726967696e223a(,"topOrigin":)를 expected에 덧붙임.

      2. CCDToString(topOrigin)을 expected에 덧붙임.

  12. 그 외의 경우 (topOrigin 미정의):

    1. 0x66616c7365(false)를 expected에 덧붙임.

  13. expectedclientDataJSON의 접두사가 아니라면 검증은 실패.

  14. clientDataJSONexpected보다 길지 않으면 검증 실패.

  15. clientDataJSON에서 expected 길이에 해당하는 위치의 바이트 값이:

    0x7d일 때

    검증 성공.

    0x2c일 때

    검증 성공.

    그 외

    검증 실패.

5.8.1.3. 향후 확장

제한된 검증 알고리즘과의 호환성을 유지하기 위하여, 향후 명세 버전에서는 type, challenge, origin, crossOrigin, 또는 topOriginCollectedClientData 에서 제거해서는 안 됩니다. 또한 직렬화 알고리즘의 해당 필드 직렬화 순서를 바꾸거나, 중간에 새 필드를 끼워넣어도 안 됩니다.

CollectedClientData 에 필드를 추가하는 경우, 제한된 검증 알고리즘이 업데이트되어 위 두 알고리즘에 포함되기 전에는 검증자들이 이 필드를 고려하지 못합니다. 이후 업데이트가 이뤄지면 추가된 필드 역시 앞 문단의 제한사항을 적용받게 되며, 과거 버전의 직렬화에 대해 호환 가능해야 합니다. 즉, 추가된 여섯 번째 키-값 쌍은 이전 버전 에이전트에서는 여섯 번째에 오지 않거나 아예 없을 수도 있음을 검증 알고리즘이 처리해야 합니다.

5.8.2. 자격 증명 유형 열거형(enum PublicKeyCredentialType)

enum PublicKeyCredentialType {
    "public-key"
};

참고: PublicKeyCredentialType 열거형은 의도적으로 참조되지 않았으니, § 2.1.1 DOMString 타입의 열거형을 참고하세요.

이 열거형은 유효한 자격 증명 유형을 정의합니다. 확장 포인트로, 미래에 더 많은 자격 증명 유형이 정의되면 값이 추가될 수 있습니다. 이 열거형의 값은 인증 어설션과 attestation 구조를 인증기 종류에 따라 버전 관리하는 데 사용됩니다.

현재 하나의 자격 증명 유형만 정의되어 있으며, 바로 "public-key"입니다.

5.8.3. 자격 증명 설명자 (dictionary PublicKeyCredentialDescriptor)

dictionary PublicKeyCredentialDescriptor {
    required DOMString                    type;
    required BufferSource                 id;
    sequence<DOMString>                   transports;
};

이 사전은 특정 공개 키 자격 증명을 식별합니다. 이는 create() 에서 동일한 인증기에 중복 자격 증명 생성을 방지하고, get() 에서 클라이언트가 현재 해당 자격 증명에 접근할 수 있는지 확인하는 데 사용됩니다.

자격 증명 기록의 설명자는 해당 자격 증명 기록의 일부 속성의 부분집합이며, PublicKeyCredential 객체의 일부 필드를 반영합니다. 이 객체는 create()get() 이 반환하는 객체와도 상응합니다.

type, of type DOMString

이 멤버는 호출자가 참조하는 public key credential의 유형을 담고 있습니다. 값은 PublicKeyCredentialType 의 멤버여야 하는 것이 좋지만, client platforms은 알려지지 않은 PublicKeyCredentialDescriptortype 을 반드시 무시해야 합니다. 그러나 모든 요소가 알려지지 않은 type 때문에 무시된다면, 비어 있는 allowCredentials 와 의미론적으로 구별되므로 오류가 발생해야 합니다.

이 값은 식별된 public key credential source를 나타내는 credential recordtype 항목의 값으로 설정하는 것이 바람직합니다. 이는 type 필드가 PublicKeyCredential에서 하는 역할을 반영합니다.

id, of type BufferSource

이 멤버는 호출자가 참조하는 public key credentialcredential ID를 포함합니다.

이 값은 식별된 public key credential source를 나타내는 credential recordid 항목의 값으로 설정하는 것이 바람직합니다. 이는 rawId 필드가 PublicKeyCredential에서 하는 역할을 반영합니다.

transports, of type sequence<DOMString>

이 선택적 멤버는 호출자가 참조하는 public key credentialmanaging authenticatorclient가 어떻게 통신할지에 대한 힌트를 포함합니다. 값은 AuthenticatorTransport 의 멤버인 것이 바람직하지만, client platforms은 알 수 없는 값을 무시해야 합니다.

이 값은 식별된 public key credential source를 나타내는 credential recordtransports 항목의 값으로 설정하는 것이 바람직합니다. 이는 response.getTransports() 메서드가 PublicKeyCredential 구조체에서 create() 연산으로 생성될 때 수행하는 동작을 반영합니다.

5.8.4. 인증기 전송 방식 열거형(enum AuthenticatorTransport)

enum AuthenticatorTransport {
    "usb",
    "nfc",
    "ble",
    "smart-card",
    "hybrid",
    "internal"
};

참고: The AuthenticatorTransport enumeration is deliberately not referenced, see § 2.1.1 DOMString 타입으로서의 열거형.

인증자는 다양한 전송 수단을 구현하여 클라이언트와 통신할 수 있습니다. 이 열거형은 클라이언트가 특정 인증자에게 특정 자격 증명에 대한 증명을 얻기 위해 어떻게 통신할 수 있는지에 대한 힌트를 정의합니다. 이러한 힌트는 WebAuthn Relying Party가 인증자에 어떻게 접근할 수 있는지에 대해 가진 최선의 추정임을 주의하십시오. Relying Party는 일반적으로 공개 키 자격 증명에 대해 지원되는 전송 수단을 getTransports()를 통해 알게 됩니다.
usb

해당 인증자에 분리형 USB를 통해 접근할 수 있음을 나타냅니다.

nfc

해당 인증자에 근거리 무선 통신(near field communication, NFC)을 통해 접근할 수 있음을 나타냅니다.

ble

해당 인증자에 Bluetooth Smart(블루투스 저전력 / BLE)를 통해 접근할 수 있음을 나타냅니다.

smart-card

해당 인증자에 접촉식 ISO/IEC 7816 스마트 카드를 통해 접근할 수 있음을 나타냅니다.

hybrid

해당 인증자가 (종종 분리된) 데이터 전송 및 근접 메커니즘의 조합을 사용하여 접근될 수 있음을 나타냅니다. 예를 들어 스마트폰을 사용하여 데스크톱 컴퓨터에서 인증하는 것을 지원합니다.

internal

해당 인증자가 클라이언트 장치 특정 전송 수단을 사용하여 접근됨을 나타내며, 즉 클라이언트 장치에 내장된 플랫폼 인증자입니다. 이러한 인증자는 클라이언트 장치에서 분리할 수 없습니다.

5.8.5. 암호화 알고리즘 식별자 (typedef COSEAlgorithmIdentifier)

typedef long COSEAlgorithmIdentifier;
A COSEAlgorithmIdentifier’s value is a number identifying a cryptographic algorithm. The algorithm identifiers SHOULD be values registered in the IANA COSE Algorithms registry [IANA-COSE-ALGS-REG], for instance, -7 for "ES256" and -257 for "RS256".

COSE 알고리즘 레지스트리는 COSE 키의 다른 매개변수로 지정할 수 있는 자유도를 남겨둡니다. 상호운용성을 촉진하기 위해, 이 명세는 다음과 같이 자격 증명 공개 키에 대해 추가적인 보장을 제공합니다:

  1. 알고리즘이 -7 (ES256)인 키는 crv 매개변수로 1 (P-256)을 지정해야 하며, 압축된 점 형식을 사용해서는 안 됩니다.

  2. 알고리즘이 -9 (ESP256)인 키는 압축된 점 형식을 사용해서는 안 됩니다.

  3. 알고리즘이 -35 (ES384)인 키는 crv 매개변수로 2 (P-384)를 지정해야 하며, 압축된 점 형식을 사용해서는 안 됩니다.

  4. 알고리즘이 -51 (ESP384)인 키는 압축된 점 형식을 사용해서는 안 됩니다.

  5. 알고리즘이 -36 (ES512)인 키는 crv 매개변수로 3 (P-521)을 지정해야 하며, 압축된 점 형식을 사용해서는 안 됩니다.

  6. 알고리즘이 -52 (ESP512)인 키는 압축된 점 형식을 사용해서는 안 됩니다.

  7. 알고리즘이 -8 (EdDSA)인 키는 crv 매개변수로 6 (Ed25519)를 지정해야 합니다. (이들은 COSE에서 항상 압축 형식을 사용합니다.)

이러한 제한은 Section 2.1의 권고와 일치합니다 [RFC9053].

참고: 이러한 알고리즘을 사용하여 서명 검증을 올바르게 구현하려면 여러 가지 검사가 필요합니다. 그중 하나는 압축되지 않은 타원 곡선 점을 처리할 때 해당 점이 실제로 곡선 위에 있는지 확인하는 것입니다. 이 검사는 암호화 라이브러리와 다른 코드 사이의 간극으로 인해 누락될 위험이 특히 크다고 판단되어 강조되어 있습니다.

5.8.6. 사용자 검증 요구 열거형(enum UserVerificationRequirement)

enum UserVerificationRequirement {
    "required",
    "preferred",
    "discouraged"
};

WebAuthn Relying Party는 일부 작업에 대해 사용자 검증을 요구할 수 있으며, 이 타입으로 요구 사항을 표현할 수 있습니다.

참고: UserVerificationRequirement 열거형은 의도적으로 참조되지 않았으며, § 2.1.1 DOMString 타입의 열거형을 참고하세요.

required

Relying Party는 이 작업에 대해 사용자 인증을 요구하며, 응답에 UV 플래그가 설정되어 있지 않으면 전체 ceremony가 실패합니다. 클라이언트사용자 인증을 수행할 수 없는 경우 반드시 오류를 반환해야 합니다.

preferred

Relying Party는 가능한 경우 작업에 대해 사용자 인증을 선호하지만, 응답에 UV 플래그가 설정되어 있지 않더라도 작업이 실패하지 않습니다.

discouraged

Relying Party는 작업 중에 사용자 인증이 사용되는 것을 원하지 않습니다(예: 사용자 인터랙션 흐름의 방해를 최소화하기 위해).

5.8.7. 클라이언트 기능 열거형(enum ClientCapability)

enum ClientCapability {
    "conditionalCreate",
    "conditionalGet",
    "hybridTransport",
    "passkeyPlatformAuthenticator",
    "userVerifyingPlatformAuthenticator",
    "relatedOrigins",
    "signalAllAcceptedCredentials",
    "signalCurrentUserDetails",
    "signalUnknownCredential"
};

이 열거형은 WebAuthn Relying Party가 특정 워크플로우 및 경험을 사용자에게 제공하기 위해 평가할 수 있는 제한적 클라이언트 기능 집합을 정의합니다.

Relying PartygetClientCapabilities() 메서드를 통해 사용할 수 있는 기능 설명을 얻을 수 있습니다.

참고: ClientCapability 열거형은 의도적으로 참조되지 않았으며, § 2.1.1 DOMString 타입의 열거형을 참고하세요.

conditionalCreate

WebAuthn 클라이언트등록 과정에서 conditional 중재를 지원함을 의미합니다.

자세한 내용은 § 5.1.3 새 자격 증명 생성 - PublicKeyCredential의 [[Create]](origin, options, sameOriginWithAncestors) 내부 메서드를 참고하세요.

conditionalGet

WebAuthn 클라이언트인증 과정에서 conditional 중재를 지원함을 의미합니다.

이 기능은 isConditionalMediationAvailable() 메서드가 true로 평가되는 것과 같습니다.

자세한 내용은 § 5.1.4 기존 자격 증명을 사용한 어설션 생성을 참고하세요.

hybridTransport

WebAuthn 클라이언트hybrid 전송 방식을 지원함을 의미합니다.

passkeyPlatformAuthenticator

WebAuthn 클라이언트패스키 플랫폼 인증기를 로컬 및/또는 hybrid 전송을 통해 지원함을 의미합니다.

userVerifyingPlatformAuthenticator

WebAuthn 클라이언트사용자 검증 플랫폼 인증기를 지원함을 의미합니다.

relatedOrigins

WebAuthn 클라이언트연관 Origin 요청을 지원함을 의미합니다.

signalAllAcceptedCredentials

WebAuthn 클라이언트signalAllAcceptedCredentials()을 지원함을 의미합니다.

signalCurrentUserDetails,

WebAuthn 클라이언트signalCurrentUserDetails()을 지원함을 의미합니다.

signalUnknownCredential

WebAuthn 클라이언트signalUnknownCredential()을 지원함을 의미합니다.

5.8.8. User-agent 힌트 열거(enum PublicKeyCredentialHint)

enum PublicKeyCredentialHint {
    "security-key",
    "client-device",
    "hybrid",
};

Note: PublicKeyCredentialHint 열거형은 의도적으로 참조되지 않음. 자세한 내용은 § 2.1.1 DOMString 타입으로서의 열거형을 참고하십시오.

WebAuthn Relying Parties는 이 열거형을 사용하여 요청을 어떻게 완료하는 것이 가장 좋은지에 대한 힌트를 사용자 에이전트에게 전달할 수 있습니다. 이러한 힌트는 필수가 아니며, 사용자 에이전트를 구속하지 않지만 Relying Party가 요청에 대해 가지고 있는 상황별 정보를 활용하여 최상의 경험을 제공하는 데 도움을 줄 수 있습니다. 힌트는 선호도가 높은 순서대로 제공되므로, 두 힌트가 모순될 경우 첫 번째 것이 우선 적용됩니다. 힌트는 중첩될 수도 있습니다: 더 구체적인 힌트가 정의되어 있더라도 Relying Party는 이를 인식하지 못하는 사용자 에이전트를 위해 덜 구체적인 힌트도 보낼 수 있습니다. 이 경우 가장 구체적인 힌트를 덜 구체적인 힌트보다 먼저 보내야 합니다. 동일한 힌트가 여러 번 나타나면, 두 번째 이후는 무시됩니다.

힌트는 자격 증명의 transportsauthenticatorAttachment에 포함된 정보와 모순될 수 있습니다. 이럴 경우 힌트가 우선합니다. (transports 값은 discovered credential을 사용할 때 제공되지 않으므로, 이런 요청의 일부 측면을 표현하는 유일한 수단이 됩니다.)

security-key

Relying Party가 사용자가 이 요청을 물리적인 보안 키로 충족시킬 것으로 판단함을 나타냅니다. 예를 들어, 엔터프라이즈 Relying Party가 직원들에게 보안 키를 배포했고 해당 authenticator등록인증에 허용하고 싶을 때 이 힌트를 설정할 수 있습니다.

이전 사용자 에이전트와의 호환성을 위해 이 힌트가 PublicKeyCredentialCreationOptions에 사용될 때, authenticatorAttachmentcross-platform으로 설정해야 합니다.

client-device

Relying Party가 사용자가 플랫폼 인증장치클라이언트 디바이스에 연결하여 이 요청을 충족시킬 것으로 판단함을 나타냅니다.

이전 사용자 에이전트와의 호환성을 위해 이 힌트가 PublicKeyCredentialCreationOptions에 사용될 때, authenticatorAttachmentplatform으로 설정해야 합니다.

hybrid

Relying Party가 사용자가 스마트폰과 같은 범용 authenticator로 이 요청을 충족시킬 것으로 판단함을 나타냅니다. 예를 들어, 소비자 Relying Party는 고객 중 소수만이 전용 보안 키를 가지고 있다고 생각할 수 있습니다. 이 옵션은 로컬 플랫폼 인증장치가 UI에서 강조 표시되지 않음을 의미하기도 합니다.

이전 사용자 에이전트와의 호환성을 위해 이 힌트가 PublicKeyCredentialCreationOptions에 사용될 때, authenticatorAttachmentcross-platform으로 설정해야 합니다.

5.9. Permissions Policy 통합

이 명세는 기능 식별자 토큰 "publickey-credentials-create" 및 "publickey-credentials-get"로 식별되는 두 개의 정책 제어 기능을 정의합니다. 이들의 기본 허용 목록은 모두 'self'입니다. [Permissions-Policy]

Document권한 정책은 그 document 내의 어떤 콘텐츠도 성공적으로 호출할 수 있는지 여부를 결정합니다. Web Authentication API를 예로 들어보면, navigator.credentials.create({publicKey:..., ...}) 또는 navigator.credentials.get({publicKey:..., ...}) 등을 통해 호출하는 경우가 해당됩니다. 어떤 document에서 비활성화된 경우, 그 문서 내의 어떤 콘텐츠도 위에 명시된 메서드들을 사용할 수 없습니다. 시도할 경우 오류가 반환됩니다.

Note: [CREDENTIAL-MANAGEMENT-1]에 명시된 알고리즘이 실제 권한 정책 평가를 수행합니다. 이러한 정책 평가는 현재 설정 객체에 접근할 수 있을 때 발생해야 하기 때문입니다. [[Create]](origin, options, sameOriginWithAncestors)[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 내부 메서드는 이러한 접근 권한이 없으며, 이는 병렬로 CredentialsContainerCreate a CredentialRequest a Credential 추상 연산에 의해 호출되기 때문입니다. [CREDENTIAL-MANAGEMENT-1].

5.10. iframe 요소 내에서 Web Authentication 사용하기

Web Authentication API는 교차 출처 iframe에서 기본적으로 비활성화되어 있습니다. 이 기본 정책을 재정의하고 교차 출처 iframe 에서 Web Authentication API[[Create]](origin, options, sameOriginWithAncestors)[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 메서드를 허용하려면, allow 속성을 iframe 엘리먼트에 지정하고, publickey-credentials-create 또는 publickey-credentials-get 기능 식별자 토큰을 각각 allow 속성 값에 포함시켜야 합니다.

Relying Parties가 내장된 환경에서 WebAuthn API를 활용하는 경우, § 13.4.2 내장 사용에 대한 가시성 고려사항에서 UI 재조정과 그 잠재적 완화방안에 대해 검토해야 합니다.

기본적으로 Web Authentication은 RP IDorigin유효 도메인과 같거나, 등록 가능한 도메인 접미사이어야 합니다. (즉, origin유효 도메인의 접미사)

이는 여러 국가별 도메인이 사용되는 대규모 환경(예: example.com vs example.co.uk vs example.sg), 또는 브랜드별 대체 도메인이 필요한 경우(예: myexampletravel.com vs examplecruises.com), 혹은 서비스형 플랫폼으로 모바일 앱을 지원하는 환경에서 배포를 어렵게 만들 수 있습니다.

WebAuthn Relying PartiesWebAuthn Clients가 제한된 관련 origin 집합에서 자격증명을 생성하고 사용할 수 있도록 허용하도록 선택할 수 있습니다. 이러한 Relying Parties는 반드시 모든 관련 origin의 ceremony에서 사용할 공통 RP ID를 선택해야 합니다.

JSON 문서는 webauthn well-known URL [RFC8615]에서 RP ID에 대해 제공되어야 하며, HTTPS를 통해 제공되어야 합니다. 해당 JSON 문서는 다음과 같이 반환되어야 합니다:

예시: RP ID가 example.com일 경우:

{
    "origins": [
        "https://example.co.uk",
        "https://example.de",
        "https://example.sg",
        "https://example.net",
        "https://exampledelivery.com",
        "https://exampledelivery.co.uk",
        "https://exampledelivery.de",
        "https://exampledelivery.sg",
        "https://myexamplerewards.com",
        "https://examplecars.com"
    ]
}

이 기능을 지원하는 WebAuthn Clients는 최소 다섯 개의 등록 가능한 origin 라벨을 지원해야 하며, 클라이언트 정책에는 남용 방지를 위한 상한이 정의되어야 합니다.

WebAuthn Clients의 해당 well-known 엔드포인트 요청은 자격증명 없이, referrer 없이, 그리고 https: 스킴을 사용하여 이루어져야 합니다. 리다이렉션을 따를 때, WebAuthn Clients는 반드시 모든 리다이렉션이 https: 스킴을 사용하는지 명시적으로 요구해야 합니다.

이 기능을 지원하는 WebAuthn ClientsrelatedOriginsgetClientCapabilities() 응답에 포함해야 합니다.

5.11.1. 관련 origin 검증

관련 origin 검증 절차callerOriginrpIdRequested를 인자로 아래와 같이 동작합니다:

  1. maxLabels를 클라이언트 정책에서 허용하는 등록 가능한 origin 라벨의 최대 개수로 둔다.

  2. RP ID rpIdRequested에 대해 webauthn well-known URL [RFC8615] (https://rpIdRequested/.well-known/webauthn)을 자격 증명 없이, referrer 없이, https: 스킴을 사용하여 fetch한다.

    1. fetch에 실패하거나, 응답 content type이 application/json이 아니거나, 리다이렉트 후 status code가 200이 아니라면 "SecurityError" DOMException을 throw한다.

    2. 리소스 body가 올바른 JSON 오브젝트가 아니면, "SecurityError" DOMException을 throw한다.

    3. JSON 오브젝트의 origins 프로퍼티 값이 없거나, 문자열 배열이 아니면 "SecurityError" DOMException을 throw한다.

  3. labelsSeen을 새로운 빈 set으로 둔다.

  4. origins의 각 originItem에 대해:

    1. urlURL 파서originItem을 입력값으로 하여 실행한 결과로 둔다. 실패하면 continue한다.

    2. domain유효 도메인url로 둔다. null이면 continue한다.

    3. labeldomain의 등록 가능한 origin 라벨로 둔다.

    4. label이 비어있거나 null이면 continue한다.

    5. labelsSeensizemaxLabels보다 크거나 같고 labelsSeenlabel을 포함하지 않으면, continue한다.

    6. callerOriginurlsame origin이면 true를 반환한다.

    7. labelsSeensizemaxLabels보다 작으면 label을 labelsSeen에 append한다.

  5. false 반환.

6. WebAuthn 인증기 모델

웹 인증 APIWebAuthn 인증자에 대한 추상적인 기능 모델을 내포합니다. 이 섹션에서는 인증자 모델을 설명합니다.

클라이언트 플랫폼은 이 추상 모델을 원하는 방식으로 구현하거나 노출할 수 있습니다. 그러나, 클라이언트의 웹 인증 API 구현이 해당 클라이언트 플랫폼이 지원하는 인증자에서 동작할 때의 동작은 § 5 Web Authentication API에 정의된 동작과 구별이 되지 않아야 합니다.

참고: [FIDO-CTAP]는 이 모델의 구체적인 인스턴스 예시이지만, 반환되는 데이터와 WebAuthn API 알고리즘과 기대하는 데이터 간의 차이점이 존재합니다. CTAP2 응답 메시지는 이 명세에서 동일한 오브젝트에 대해 정의된 문자열 키 대신 정수 키를 사용하여 CBOR 맵을 구성합니다. 클라이언트는 그러한 데이터에 필요한 변환을 수행해야만 합니다. [FIDO-CTAP] 명세는 Section §6. Authenticator API에서 CTAP2 정수 키와 WebAuthn 문자열 키 간의 매핑을 자세히 기술합니다.

인증자에 대해 이 모델은 반드시 지원해야 하는 논리적 연산과 클라이언트 및 WebAuthn Relying Party에 노출되는 데이터 형식을 정의합니다. 하지만, 인증자가 클라이언트 디바이스와 어떻게 통신하는지에 대한 세부사항은(상호 운용성에 필수인 경우를 제외하고) 정의하지 않습니다. 예를 들어, 이 추상 모델은 USB 또는 NFC와 같은 전송 방식으로 인증자를 클라이언트와 연결하는 프로토콜을 정의하지 않습니다. 또한, 이 추상 모델은 특정 에러 코드나 반환 방법은 정의하지 않지만, 클라이언트의 요구에 맞게 에러 동작을 정의합니다. 따라서, 특정 에러 코드가 어떤 에러 조건이 반드시 구분 가능해야(또는 불필요한지) 하는지 설명하는 수단으로 언급됩니다. 이를 통해 준수 및 안전한 클라이언트 구현을 할 수 있습니다.

Relying Parties는 필요하다면 인증자 선택에 영향을 줄 수 있는데, 자격 증명 생성 혹은 어설션 생성 시 각각 자격 증명 생성 옵션 또는 어설션 생성 옵션을 이용해 여러 인증자 속성을 지정할 수 있습니다. WebAuthn API의 기반 알고리즘은 이 옵션들을 모아서 아래에 정의된 해당 인증자 연산에 전달합니다.

이 추상 모델에서 인증자는 키 관리 및 암호화 서명을 담당합니다. 인증자는 WebAuthn 클라이언트에 내장되어 있을 수도 있고 별도의 디바이스에 존재할 수도 있습니다. 인증자는 자체적으로 나머지 인증자보다 높은 보안 수준을 가진 암호화 모듈을 포함할 수 있습니다. 이는 인증자가 WebAuthn 클라이언트 내에 내장된 경우에 특히 중요하며, 이 경우 암호화 모듈(예를 들어 TPM)은 인증자의 다른 부분보다 더 신뢰할 수 있는 요소로 간주될 수 있습니다.

각 인증자는 (rpId, userHandle)에서 공개키 자격 증명 소스로의 credentials map을 저장합니다. (map)

또한, 각 인증자는 Authenticator Attestation Globally Unique Identifier 또는 AAGUID를 갖습니다. 이는 인증자의 종류(예: 제조사 및 모델)를 나타내는 128비트 식별자입니다. AAGUID는 반드시 제조사가 본질적으로 동일한 인증자에 대해 동일하게 선택해야 하며, 다른 종류의 모든 인증자와는 (매우 높은 확률로) 달라야 합니다. 특정 종류의 인증자에 대한 AAGUID는 이를 보장하기 위해 임의로 생성하는 것이 바람직합니다. Relying Party는 AAGUID를 이용하여 인증자의 인증 수준이나 키 보호 강도 등 속성을 다른 정보를 통해 추론할 수 있습니다. Relying Party는 AAGUID를 토대로 attestation을 요청하거나 검증하지 않고도 인증자 제조사를 파악하려 시도할 수 있지만, attestation 없이 AAGUID는 확실하게 진짜임을 증명할 수 없습니다.

인증자의 주요 역할은 다양한 상황별 데이터에 묶인 WebAuthn 서명을 제공하는 것입니다. 이러한 데이터는 서명 요청이 서버에서 인증자에 도달할 때 스택의 다양한 레벨에서 관찰되어 추가됩니다. 서버가 서명을 검증할 때 이 바인딩을 기대값과 비교합니다. 이러한 상황적 바인딩은 두 가지로 나뉩니다: Relying Party 또는 클라이언트가 추가한 클라이언트 데이터, 그리고 인증자가 추가한 인증자 데이터입니다. 인증자는 클라이언트 데이터에 서명하지만, 그 내용에는 관심이 없습니다. 인증자의 대역폭 및 처리 부담을 줄이기 위해, 클라이언트는 클라이언트 데이터를 해시하여 그 결과만 인증자에게 전송합니다. 인증자는 직렬화된 클라이언트 데이터의 해시와 자신의 인증자 데이터 조합에 서명합니다.

이 디자인의 목표는 다음과 같이 요약할 수 있습니다.

인증자는 두 가지 목적의 암호화 서명을 생성합니다:

  1. 새로운 공개키 자격 증명authenticatorMakeCredential 연산을 통해 생성될 때 attestation signature가 생성됩니다. Attestation signature인증자 및 자격 증명에 대한 특정 속성을 암호학적으로 증명합니다. 예를 들어, attestation signature는 인증자 종류(AAGUID로 표시)와 자격 증명 공개키를 명시합니다. Attestation signatureattestation private key로 서명되며, 원하는 Attestation 유형에 따라 선택됩니다. Attestation에 대한 자세한 내용은 § 6.5 Attestation를 참조하세요.

  2. authenticatorGetAssertion 메서드가 호출될 때 assertion signature가 생성됩니다. 이는 인증자가 사용자가 로그인이나 구매 완료와 같은 특정 트랜잭션에 동의했음을 어설션하는 것입니다. Assertion signature는 특정 자격 증명 비공개키를 가진 인증자가 요청한 트랜잭션의 사용자가 해당 공개키 자격 증명을 생성할 때 동의한 동일한 사용자임을 최대한 확인했음을 나타냅니다. 또한 클라이언트 데이터 등 추가 정보도 어설션하는데, 예를 들어 사용자 동의가 제공된 방식이나 인증자가 사용자에게 보여준 프롬프트 등이 해당됩니다. Assertion signature 형식은 아래 그림 4에 설명돼 있습니다.

WebAuthn signatureattestation signatureassertion signature 모두를 의미합니다. 이들 서명의 형식과 생성 과정은 아래에 명시되어 있습니다.

6.1. 인증기 데이터

authenticator data 구조는 인증자가 만든 상황적 바인딩을 인코딩합니다. 이러한 바인딩은 인증자 자체에 의해 제어되며, 인증자의 보안 특성에 대한 WebAuthn Relying Party의 평가에서 신뢰를 얻습니다. 한 쪽 극단의 경우, 인증자가 클라이언트에 내장되어 있고 그 바인딩이 클라이언트 데이터만큼만 신뢰할 수 있습니다. 반대편 극단의 경우, 인증자가 높은 보안의 하드웨어와 소프트웨어를 가진 별도의 개체이고 보안 채널을 통해 클라이언트에 연결될 수 있습니다. 두 경우 모두 Relying Party는 동일한 형식의 authenticator data를 받고, 인증자에 대한 지식을 바탕으로 신뢰 결정을 내립니다.

authenticator data는 컴팩트하지만 확장 가능한 인코딩을 가집니다. 인증자는 클라이언트 플랫폼보다 훨씬 단순한 소프트웨어 스택과 제한된 기능, 저전력 요구를 갖는 장치일 수 있기 때문에 이는 바람직합니다.

authenticator data 구조는 최소 37바이트 이상의 바이트 배열로, 아래 표와 같이 구성되어 있습니다.

Name Length (in bytes) Description
rpIdHash 32 자격 증명범위가 지정된 RP ID의 SHA-256 해시
flags 1 플래그(bit 0이 가장 오른쪽 비트):
signCount 4 서명 카운터, 32비트 부호 없는 빅엔디안 정수
attestedCredentialData variable (if present) attested credential data(존재할 경우). § 6.5.1 Attested Credential Data에서 자세한 내용을 확인. 길이는 credential IDcredential public key의 길이에 따라 달라집니다.
extensions variable (if present) 확장 정의된 authenticator data. 이는 확장 식별자가 키이고, 확장 출력이 값인 CBOR [RFC8949] 맵입니다. 자세한 내용은 § 9 WebAuthn Extensions 참조.
Authenticator data 레이아웃. Name 열의 명칭은 문서 내부 참조용이며, authenticator data의 실제 표현에는 포함되지 않습니다.

RP ID는 자격 증명이 생성될 때 클라이언트로부터 처음 받아오고, 어설션이 생성될 때도 다시 받아옵니다. 하지만, 클라이언트 데이터와 일부 중요한 면에서 다릅니다. 우선, 클라이언트 데이터와 달리 자격 증명의 RP ID는 작업 사이에 변경되지 않고 자격 증명 수명 동안 동일하게 유지됩니다. 또한, authenticatorGetAssertion 연산 중 인증자에 의해, 요청된 자격 증명범위가 지정된 RP ID가 클라이언트가 제공한 RP ID와 정확히 일치하는지 검증함으로써, 검증됩니다.

인증자다음 단계를 수행하여 authenticator data 구조를 생성합니다:

아래 그림authenticator data 구조의 시각적 표현을 보여줍니다.

Authenticator data 레이아웃.
Note: authenticator data는 자신의 길이를 정의합니다: ATED 플래그가 설정되어 있지 않으면 항상 37바이트입니다. attested credential data(AT 플래그가 설정된 경우만 존재)는 자신의 길이를 정의합니다. ED 플래그가 설정된 경우, 전체 길이는 37바이트 + attested credential data(AT 플래그가 설정된 경우) + 뒤따르는 확장 출력(CBOR 맵) 길이입니다.

길이가 가변인 attested credential data의 길이를 결정하려면, 앞의 credentialId길이를 고려하여, credentialPublicKey의 시작 위치를 정하고, credentialPublicKey의 길이를 결정해야 합니다. (RFC9052 섹션 7도 참고)

6.1.1. 서명 카운터 관련 사항

인증자들은 서명 카운터 기능을 구현하는 것이 좋습니다. 이러한 카운터들은 개념적으로 인증자가 각 자격 증명마다, 혹은 인증자 전체에 대해 전역적으로 저장할 수 있습니다. 자격 증명의 초기 서명 카운터 값은 signCountauthenticator data에서 authenticatorMakeCredential 호출 결과로 지정됩니다. 서명 카운터는 인증자가 authenticatorGetAssertion 작업을 성공적으로 수행할 때마다 양의 값만큼 증가되어, 이후 값도 WebAuthn Relying Party에게 다시 authenticator data를 통해 반환됩니다. 서명 카운터의 목적은 Relying Parties가 복제된 인증자를 탐지하는 데 도움을 주는 것입니다. 복제 감지는 보호 수단이 제한적인 인증자에서 더 중요합니다.

서명 카운터를 구현하지 않는 인증자들은 signCountauthenticator data에서 항상 0으로 고정합니다.

Relying Party는 최근 authenticatorGetAssertion 작업의 signature counter를 저장합니다. (credential에서 authenticatorGetAssertion이 한 번도 수행된 적이 없으면 authenticatorMakeCredential 작업의 카운터 값을 저장합니다.) 이후 authenticatorGetAssertion 작업에서 Relying Party는 저장된 signature counter 값과 assertion의 authenticator data에 반환된 새로운 signCount 값을 비교합니다. 둘 중 하나라도 0이 아니고, 새로운 signCount가 저장된 값보다 작거나 같으면, 복제된 인증기(authenticator)가 존재하거나, 인증기가 오동작하고 있거나, 또는 Relying Party가 assertion을 인증기에서 생성된 순서와 다른 순서로 받아 처리하는 경쟁 상태(race condition)가 있을 수 있습니다.

서명 카운터 불일치를 감지한다고 해서 현재 작업이 복제 인증자로 수행된 것인지 혹은 원래 인증자인지 알 수 있는 것은 아닙니다. Relying Parties는 각자의 상황에 맞게(예: 각자의 위험 허용도, 운영상 증가하지 않는 값에 대한 허용 사유 등) 이 경우를 적절히 처리해야 합니다.

인증자들은 다음과 같아야 합니다:

6.1.2. FIDO U2F 서명 형식 호환성

Assertion signature인증기 데이터 구조와 클라이언트 데이터 해시를 연결해 서명하는데, 이 형식은 FIDO U2F 인증 서명 형식과 호환됩니다 (자세한 내용은 Section 5.4, [FIDO-U2F-Message-Formats] 참고).

이는 FIDO U2F 인증 응답 메시지에서 서명된 데이터의 처음 37바이트가 유효한 인증기 데이터 구조이고, 나머지 32바이트가 클라이언트 데이터 해시이기 때문입니다. 이 인증기 데이터 구조에서 rpIdHash는 FIDO U2F의 application 파라미터에 해당하며, 모든 flagsUP을 제외하고 항상 0입니다. attestedCredentialDataextensions는 나타나지 않습니다. 따라서 FIDO U2F 인증 서명도 authenticatorGetAssertion 동작이 생성한 일반 assertion signature와 동일한 검증 절차로 검증할 수 있습니다.

6.1.3. 자격 증명 백업 상태

자격 증명의 백업 가능성과 현재 백업 상태BE, BS 플래그인증기 데이터에 전달되며, 에 명시되어 있습니다.

BE 플래그 값은 authenticatorMakeCredential 동작 중 설정되며, 이후 변경될 수 없습니다.

BS 플래그 값은 공개 키 자격 증명 소스의 상태에 따라 시간이 지남에 따라 변할 수 있습니다. 아래 에 유효 조합 및 의미가 정의되어 있습니다.

BE BS 설명
0 0 해당 자격 증명은 단일 기기 자격 증명입니다.
0 1 이 조합은 허용되지 않습니다.
1 0 이 자격 증명은 다중 기기 자격 증명이며, 현재 백업되지 않음 상태입니다.
1 1 이 자격 증명은 다중 기기 자격 증명이며, 현재 백업됨 상태입니다.
BEBS 플래그 조합

Relying Parties는 이러한 플래그의 최신 값을 사용자 계정과 함께 저장하여 향후 평가를 할 것을 권장합니다.

아래는 Relying Parties가 이러한 플래그를 활용하는 방법의 비포괄적 목록입니다:

6.2. 인증기 분류

많은 사용 사례는 사용된 authenticator의 기능에 따라 달라집니다. 이 절에서는 그러한 기능들, 그중 중요한 조합들, 그리고 그 조합들이 어떤 사용 사례를 가능하게 하는지를 정의합니다.

예를 들면:

위 예시는 주요 authenticator type 특성을 설명합니다:

이 특성들은 서로 독립적이며 이론적으로는 어떤 방식으로든 조합될 수 있지만, 는 특별히 주목할 만한 몇몇 authenticator types의 이름과 조합을 나열합니다.

Authenticator Type Authenticator Attachment Modality Credential Storage Modality Authentication Factor Capability
Second-factor platform authenticator platform Either Single-factor capable
User-verifying platform authenticator platform Either Multi-factor capable
Second-factor roaming authenticator cross-platform Server-side storage Single-factor capable
Passkey roaming authenticator cross-platform Client-side storage Multi-factor capable
Passkey platform authenticator platform (transport = internal) or cross-platform (transport = hybrid) Client-side storage Multi-factor capable
일부 authenticator types 명칭에 대한 정의.

두 번째 요소 플랫폼 인증자는 동일한 클라이언트 디바이스에서 재인증할 때 편리하며, 새로운 세션 시작이나 기존 세션을 다시 시작할 때 모두 추가적인 보안을 제공합니다. 두 번째 요소 이동식 인증자는 특정 클라이언트 디바이스를 처음 인증하거나 여러 사용자가 함께 사용하는 클라이언트 디바이스 인증에 더 자주 사용됩니다.

패스키 플랫폼 인증자패스키 이동식 인증자는 패스워드 없는 다중요소 인증을 가능하게 합니다. 자격증명 비공개키 소유 증명에 더해, 이러한 인증자는 두 번째 인증 요소사용자 인증(보통 PIN 또는 생체 인증)을 지원합니다. 인증자는 따라서 두 가지 인증 요소 역할을 할 수 있어, 패스워드를 Relying Party와 공유할 필요 없이 다중요소 인증을 할 수 있습니다. 이 인증자들은 탐색 가능한 자격증명(패스키라고도 부름, 패스키)도 지원하며, 이는 사용자 이름 입력이 필요없는 인증 플로도 가능하게 합니다.

사용자 인증 플랫폼 인증자 클래스는 거의 패스키 플랫폼 인증자 클래스에 의해 대체되었지만, 정의 자체는 isUserVerifyingPlatformAuthenticatorAvailable 메서드에서 아직 사용됩니다.

에 명명되지 않은 조합들은 더 특징적이지 않은 사용 사례를 가집니다:

다음 하위 섹션에서는 인증자 연결 방식, 자격증명 저장 방식, 인증요소 능력을 더 깊이 정의합니다.

6.2.1. Authenticator Attachment Modality

Clients는 다양한 방식으로 authenticators와 통신할 수 있습니다. 예를 들어, clientclient device 고유의 API를 사용하여 해당 authenticator와 통신할 수 있습니다. 반면에, client는 Bluetooth와 같은 표준화된 크로스 플랫폼 전송 프로토콜(참조: § 5.8.4 Authenticator Transport Enumeration (enum AuthenticatorTransport))을 사용하여 cross-platform attached authenticators를 검색하고 통신할 수 있습니다. 우리는 authenticatorsclient device의 일부인 경우 이를 platform authenticators라고 부르며, 크로스 플랫폼 전송 프로토콜로 접근 가능한 인증기는 roaming authenticators라고 부릅니다.

일부 플랫폼 인증자는 상황에 따라 이동식 인증자로도 사용할 수 있습니다. 예를 들어, 모바일 디바이스에 내장된 플랫폼 인증자가 Bluetooth를 통해 이동식 인증자 역할을 할 수 있습니다. 이런 경우, 모바일 디바이스에서 실행 중인 클라이언트는 인증자를 플랫폼 인증자로 인식하고, Bluetooth를 통해 동일 인증자와 통신하는 다른 클라이언트 디바이스에서 실행 중인 클라이언트는 해당 인증자를 이동식 인증자로 인식하게 됩니다.

플랫폼 인증자의 주요 사용 사례는 특정 클라이언트 디바이스를 "신뢰할 수 있는 디바이스"로 등록하는 것입니다. 즉, 클라이언트 디바이스 자체가 이후 소유 증거 인증 요소로 작동해 미래 인증에 사용됩니다. 이 덕분에 사용자는 이후 인증 시나리오이동식 인증자가 필요하지 않으므로, (예: 열쇠고리나 휴대폰을 주머니에서 꺼낼 필요가 없습니다.)

이동식 인증자의 사용 사례는 처음으로 새로운 클라이언트 디바이스에서 인증할 때, 잘 사용하지 않는 클라이언트 디바이스, 여러 사용자가 공유하는 클라이언트 디바이스, 플랫폼 인증자가 포함되지 않은 클라이언트 디바이스에서 사용하는 경우입니다. 또한 정책이나 사용자의 선호에 따라 인증자를 사용하는 클라이언트 디바이스와 분리해야 할 때도 있습니다. 이동식 인증자는 또한 다른 인증기를 분실했을 때 백업 자격증명을 보관하는 데 사용할 수 있습니다.

6.2.2. Credential Storage Modality

  1. 인증자, 클라이언트 또는 클라이언트 디바이스에 내장된 영속적 저장소(예: 보안 요소)에 저장. 이는 클라이언트 측 검색 가능한 공개키 자격 증명 소스에 대한 기술적 요구사항입니다.

  2. 공개키 자격 증명 소스를 암호화(즉, 래핑)하여 오직 해당 인증자만 복호화(즉, 언래핑)하도록 하고, 그 결과 암호문을 자격 증명 ID로 사용합니다. 자격 증명 ID신뢰당사자에 의해 저장되고, allowCredentials 옵션을 통해 get()으로 인증자에 반환되어, 공개키 자격 증명 소스를 복호화해 사용할 수 있습니다.

    이 방식은 인증자가 무제한 자격 증명 저장 용량을 가지게 하지만, 암호화된 공개키 자격 증명 소스신뢰당사자에 저장되고, 인증자가 아닌 곳에 저장된 자격 증명(credential)은 신뢰당사자를 통해 먼저 가져온 뒤에야 인증자가 사용할 수 있게 됩니다.

인증자가 지원하는 저장 전략에 따라 아래와 같이 인증자자격 증명 저장 방식이 정의됩니다:

검색 가능한 자격 증명 지원 인증자는 두 가지 저장 전략 모두 지원할 수 있다는 점에 유의하세요. 이 경우, 인증자자격 증명별로 서로 다른 저장 전략을 선택할 수 있지만, residentKeyrequireResidentKey 옵션(create() 호출 시)을 따라야 합니다.

6.2.3. Authentication Factor Capability

인증 의식(authentication factors) 동안 신원을 증명하는 데 사용할 수 있는 세 가지 넓은 범주의 인증 요소가 있습니다: 소지한 것(something you have), 알고 있는 것(something you know)자신의 일부인 것(something you are). 예로 각각 물리적 키, 비밀번호 및 지문이 있습니다.

모든 WebAuthn Authenticator소지한 것(something you have) 분류에 속하지만, authenticator사용자 검증(user verification)을 지원하면 추가로 한 가지 또는 두 가지 유형의 인증 요소로 동작할 수 있습니다. 예를 들어, authenticator가 PIN을 검증할 수 있다면, 그 PIN은 알고 있는 것(something you know)이 되고, 생체 인증기자신의 일부인 것(something you are)을 검증할 수 있습니다. 따라서 사용자 검증을 지원하는 authenticator다요소 지원(multi-factor capable)입니다. 반대로, authenticator다요소 지원이 아니면 단일 요소 지원(single-factor capable)입니다. 단일한 다요소 지원 authenticator는 여러 모드의 사용자 검증을 지원할 수 있으므로, 세 가지 종류의 인증 요소 모두로 동작할 수 있습니다.

비록 사용자 검증authenticator에서 로컬로 수행되고 Relying Party가 직접 수행하는 것은 아니지만, authenticator는 서명된 응답에 UV 플래그를 설정하여 사용자 검증이 수행되었는지를 표시합니다. Relying Party는 따라서 UV 플래그를 사용해 등록 또는 인증 의식 중에 추가적인 인증 요소가 사용되었는지 검증할 수 있습니다. UV 플래그의 진위는 차례로 authenticatorattestation statement를 검사하여 평가할 수 있습니다.

6.3. Authenticator Operations

WebAuthn Client는 해당 인증자의 어떤 연산도 호출하기 위해 인증자에 연결해야 합니다. 이 연결은 authenticator session을 정의합니다. 인증자는 세션 간의 격리를 유지해야 합니다. 이는 특정 시점에 하나의 세션만 허용하거나 더 복잡한 세션 관리를 제공함으로써 달성할 수 있습니다.

다음 연산들은 클라이언트가 인증자 세션에서 호출할 수 있습니다.

6.3.1. Lookup Credential Source by Credential ID Algorithm

credential id를 조회한 결과는 다음 알고리즘의 결과입니다. 이는 credential id credentialIdauthenticator authenticator에서 조회한 결과입니다:

  1. 만약 authenticatorcredentialIdpublic key credential source credSource로 복호화할 수 있다면:

    1. credSource.idcredentialId로 설정합니다.

    2. credSource를 반환합니다.

  2. For each public key credential source credSource를 이 인증자의 credentials map에서 반복하는 동안:

    1. 만약 credSource.idcredentialId이면, credSource를 반환합니다.

  3. null을 반환합니다.

6.3.2. The authenticatorMakeCredential Operation

이 작업을 호출하기 전에, 클라이언트는 authenticatorCancel 작업을 먼저 호출하여 인증자 세션에서 진행 중인 모든 다른 작업을 중단해야 합니다.

이 작업은 다음 입력 파라미터를 받습니다:

hash

클라이언트가 제공한 직렬화된 클라이언트 데이터의 해시.

rpEntity

Relying PartyPublicKeyCredentialRpEntity.

userEntity

사용자 계정PublicKeyCredentialUserEntity, 여기에는 사용자 핸들이 포함됩니다.

requireResidentKey

자격 증명 생성에 대한 유효한 resident key 요구사항, 클라이언트가 결정한 Boolean 값.

requireUserPresence

상수 Boolean 값 true, 또는 FALSE일 수 있으며 이는 options.mediationconditional로 설정되고 사용자 에이전트가 이전에 사용자로부터 동의를 수집했을 경우입니다.

requireUserVerification

자격 증명 생성에 대한 유효한 사용자 검증 요구사항, 클라이언트가 결정한 Boolean 값.

credTypesAndPubKeyAlgs

PublicKeyCredentialType와 공개키 알고리즘(COSEAlgorithmIdentifier)의 쌍으로 이루어진 시퀀스이며, 이는 Relying Party가 요청합니다. 이 시퀀스는 가장 선호하는 것에서 덜 선호하는 순으로 정렬됩니다. authenticator는 가능한 한 가장 선호되는 credential을 생성하기 위해 최선을 다합니다.

excludeCredentialDescriptorList

선택적으로 제공되는 PublicKeyCredentialDescriptor 객체 목록으로, Relying Party가 제공하며, 만약 이들 중 어떤 것이 인증자에게 알려져 있다면 인증자는 새로운 자격증명을 생성해서는 안 됩니다. excludeCredentialDescriptorList은 알려진 자격증명들의 목록을 포함합니다.

enterpriseAttestationPossible

개별 식별 가능한 attestation이 인증자에 의해 반환될 수 있음을 나타내는 Boolean 값.

attestationFormats

Relying Party의 attestation statement 형식에 대한 선호도를 문자열 시퀀스로 표현한 것(가장 선호되는 것에서 덜 선호되는 것 순). 인증자가 attestation을 반환하는 경우, 지원하는 가장 선호되는 형식을 사용하려고 최선의 노력을 합니다.

extensions

클라이언트가 Relying Party가 요청한 확장에 따라 생성한 CBOR map으로, 확장 식별자에서 해당 authenticator extension input으로 매핑합니다.

이 연산이 호출되면, authenticator는 다음 절차를 반드시 수행해야 합니다:

  1. 제공된 모든 매개변수가 구문적으로 올바르고 올바른 길이인지 확인합니다. 그렇지 않다면, "UnknownError"에 상응하는 오류 코드를 반환하고 연산을 종료합니다.

  2. PublicKeyCredentialTypecredTypesAndPubKeyAlgs에 있는 암호 매개변수 조합 중 적어도 하나를 지원하는지 확인합니다. 지원하지 않으면 "NotSupportedError"에 상응하는 오류 코드를 반환하고 연산을 종료합니다.

  3. descriptor에 대하여 excludeCredentialDescriptorList를 반복합니다:

    1. 만약 조회가 이 인증자에서 descriptor.id를 찾았고 반환값이 null이 아니며, 반환된 항목의 RP IDtyperpEntity.idexcludeCredentialDescriptorList.type과 각각 일치한다면, 새로운 자격증명 생성을 확인하는 authorization gesture를 수집합니다. 이 authorization gesture사용자 존재 검사를 반드시 포함해야 합니다. 만약 사용자가

      새 자격증명 생성을 위한 동의를 확인하면

      "InvalidStateError"에 상응하는 오류 코드를 반환하고 연산을 종료합니다.

      새 자격증명 생성을 위한 동의를 안 하면

      "NotAllowedError"에 상응하는 오류 코드를 반환하고 연산을 종료합니다.

      Note:authorization gesture의 목적은 자격증명을 생성하는 것이 아니라, 프라이버시 이유로 descriptor.id가 이 인증자에 바인딩되어 있음을 공개하는 것을 허가하는 데 있습니다. 사용자가 동의하면 clientRelying Party는 이를 감지하고 사용자가 다른 authenticator를 사용하도록 안내할 수 있습니다. 사용자가 동의하지 않으면, authenticatordescriptor.id가 바인딩되어 있음을 드러내지 않고 사용자가 단순히 자격증명 생성을 거부한 것처럼 응답합니다.

  4. 만약 requireResidentKeytrue이고 인증자가 client-side discoverable public key credential source를 저장할 수 없다면, "ConstraintError"에 상응하는 오류 코드를 반환하고 연산을 종료합니다.

  5. 만약 requireUserVerificationtrue이고 인증자가 사용자 검증을 수행할 수 없다면, "ConstraintError"에 상응하는 오류 코드를 반환하고 연산을 종료합니다.

  6. authorization gesture가 완료되고 사용자 동의가 획득되면, 새로운 자격증명 객체를 생성합니다:

    1. (publicKey, privateKey)를 이 인증자가 지원하는 credTypesAndPubKeyAlgs의 첫 번째 항목(가장 선호되는 항목)을 사용하여 새 암호 키 쌍으로 생성합니다.

    2. userHandleuserEntity.id로 합니다.

    3. credentialSource를 다음 필드를 가진 새로운 public key credential source로 합니다:

      type

      public-key.

      privateKey

      privateKey

      rpId

      rpEntity.id

      userHandle

      userHandle

      otherUI

      인증자가 포함하기로 선택한 기타 정보.

    4. 만약 requireResidentKeytrue이거나 인증자가 client-side discoverable public key credential source를 만들기로 선택하면:

      1. credentialId를 새로운 credential id로 합니다.

      2. credentialSource.idcredentialId로 설정합니다.

      3. credentials를 이 인증자의 credentials map으로 합니다.

      4. Set credentials[(rpEntity.id, userHandle)]을 credentialSource로 설정합니다.

    5. 그렇지 않으면:

      1. credentialIdcredentialSource를 직렬화하고 암호화하여 이 인증자만 복호화할 수 있도록 한 결과로 합니다.

  7. 새 자격증명 객체를 생성하는 동안 어떤 오류가 발생하면, "UnknownError"에 상응하는 오류 코드를 반환하고 연산을 종료합니다.

  8. processedExtensionsauthenticator extension processing의 결과로 둡니다. 이는 extensions에 있는 각 지원되는 확장 식별자authenticator extension input에 대해 수행됩니다.

  9. 만약 authenticator가:

    U2F 장치이면

    새 자격증명의 signature counter 값을 0으로 둡니다. (U2F 장치는 signature counter를 지원할 수 있지만 자격증명 생성 시 카운터를 반환하지 않습니다.)

    전역 signature counter를 지원하면

    authenticator data를 생성할 때 전역 signature counter의 실제 값을 사용합니다.

    자격증명별 signature counter를 지원하면

    카운터를 할당하고 이를 새 자격증명에 연관시키며 카운터 값을 0으로 초기화합니다.

    signature counter를 지원하지 않으면

    새 자격증명의 signature counter 값을 0으로 고정합니다.

  10. attestedCredentialDatacredentialIdpublicKey를 포함한 attested credential data 바이트 배열로 둡니다.

  11. attestationFormatattestationFormats에서 첫 번째로 지원되는 attestation statement format identifier로 둡니다(단, enterpriseAttestationPossible를 고려함). 만약 attestationFormats에 지원되는 값이 없다면, attestationFormat를 이 인증자가 가장 선호하는 형식으로 둡니다.

  12. authenticatorData§ 6.1 Authenticator Data에 명시된 바이트 배열로 하고, 여기에 attestedCredentialDataattestedCredentialData로 포함하며, 필요한 경우 processedExtensionsextensions로 포함합니다.

  13. 새 자격증명에 대한 attestation object를 생성합니다. 절차는 § 6.5.4 Generating an Attestation Object에 명시된 절차와 attestationFormat, 그리고 값 authenticatorDatahash를 사용하며, enterpriseAttestationPossible의 값을 고려합니다. attestation에 대한 자세한 내용은 § 6.5 Attestation을 참조하세요.

이 연산이 성공적으로 완료되면, 인증자는 attestation object를 클라이언트에 반환합니다.

6.3.3. The authenticatorGetAssertion Operation

이 연산을 호출하기 전에, 클라이언트는 반드시 authenticatorCancel 연산을 호출하여 authenticator session에서 진행 중인 모든 다른 연산을 중단해야 합니다.

이 연산은 다음 입력 매개변수를 받습니다:

rpId

호출자의 RP ID, 이는 사용자 에이전트와 클라이언트에 의해 결정됩니다.

hash

클라이언트가 제공한 직렬화된 클라이언트 데이터의 해시.

allowCredentialDescriptorList

선택적 목록으로, PublicKeyCredentialDescriptor들을 포함하며 이는 Relying Party가 허용하는 자격증명(클라이언트에 의해 필터링될 수 있음)을 설명합니다.

requireUserPresence

상수 Boolean 값 true. 이는 추상 인증자 모델을 WebAuthn을 구현하려는 구현체에 적용하기 쉽게 하기 위한 의사-매개변수로 포함되어 있으며, 구현체는 사용자 존재 검사(test of user presence)를 선택적으로 만들고자 할 수 있습니다.

requireUserVerification

클라이언트가 제공한 어설션에 대한 유효한 사용자 검증 요구사항 Boolean 값.

extensions

클라이언트가 Relying Party가 요청한 확장에 따라 생성한 CBOR map으로, 확장 식별자에서 해당 authenticator extension input으로 매핑합니다.

이 메서드가 호출되면, authenticator는 다음 절차를 반드시 수행해야 합니다:

  1. 제공된 모든 매개변수가 구문적으로 올바르고 올바른 길이인지 확인합니다. 그렇지 않다면, "UnknownError"에 상응하는 오류 코드를 반환하고 연산을 종료합니다.

  2. credentialOptions를 새로운 빈 set으로 하여 public key credential sources를 담도록 합니다.

  3. 만약 allowCredentialDescriptorList가 제공되었다면, descriptor에 대해:

    1. credSource를 이 인증자에서 조회한 결과로 둡니다(즉, descriptor.id의 조회 결과).

    2. 만약 credSource가 null이 아니면, append하여 credentialOptions에 추가합니다.

  4. 그렇지 않으면(allowCredentialDescriptorList가 제공되지 않았다면), keycredSource에 대해 이 인증자의 credentials map에서 credSourcecredentialOptions에 append합니다.

  5. Remove를 사용하여 credentialOptions에서 rpIdrpId와 같지 않은 항목들을 제거합니다.

  6. 만약 credentialOptions가 비어 있으면, "NotAllowedError"에 상응하는 오류 코드를 반환하고 연산을 종료합니다.

  7. 사용자에게 public key credential sourceselectedCredentialcredentialOptions에서 선택하도록 프롬프트합니다. 그리고 selectedCredential 사용을 위한 authorization gesture를 수집하여 사용자 동의를 확인합니다. authorization gesture에 대한 프롬프트는 인증자가 자체 출력 기능을 가지고 있으면 인증자가, 그렇지 않으면 사용자 에이전트가 표시할 수 있습니다.

    만약 requireUserVerificationtrue이면, authorization gesture는 반드시 사용자 검증을 포함해야 합니다.

    만약 requireUserPresencetrue이면, authorization gesture는 반드시 사용자 존재 검사를 포함해야 합니다.

    만약 사용자가 동의하지 않으면, "NotAllowedError"에 상응하는 오류 코드를 반환하고 연산을 종료합니다.

  8. processedExtensionsauthenticator extension processing의 결과로 둡니다. 이는 extensions에 있는 각 지원되는 확장 식별자authenticator extension input에 대해 수행됩니다.

  9. 선택된 자격증명에 연관된 signature counter 또는 전역 signature counter 값을, 어떤 방식이 인증자에 의해 구현되었는지에 따라 양의 값만큼 증가시킵니다. 만약 인증자가 signature counter를 구현하지 않았다면, signature counter 값은 0으로 유지됩니다.

  10. authenticatorData§ 6.1 Authenticator Data에 명시된 바이트 배열로 하고, 필요한 경우 processedExtensionsextensions로 포함하되 attestedCredentialData는 제외합니다.

  11. signatureassertion signature로 둡니다. 이는 authenticatorData || hash의 연결에 대해 selectedCredentialprivateKey를 사용하여 생성된 서명입니다(아래 그림 참조). 간단한 구분자 없는 연결은 안전하게 사용할 수 있는데, 이는 authenticator data가 스스로의 길이를 설명하기 때문입니다. 직렬화된 클라이언트 데이터의 해시(가변 길이일 수 있음)는 항상 마지막 요소입니다.

    assertion signature 생성.
  12. assertion signature를 생성하는 동안 어떤 오류가 발생하면, "UnknownError"에 상응하는 오류 코드를 반환하고 연산을 종료합니다.

  13. 사용자 에이전트로 반환:
    • selectedCredential.id, 만약 클라이언트가 길이 2 이상의 자격증명 목록(allowCredentialDescriptorList)을 제공했거나, 그런 목록이 제공되지 않았을 경우 반환됩니다.

      Note: 만약 allowCredentialDescriptorList 내에서 클라이언트가 정확히 하나의 자격증명을 제공했고 그것이 성공적으로 사용되었다면, 해당 자격증명의 credential ID는 반환되지 않습니다. 클라이언트는 이미 그것을 알고 있기 때문에, 제약된 연결에서 바이트 전송을 절약할 수 있습니다.

    • authenticatorData

    • signature

    • selectedCredential.userHandle

      Note: 만약 allowCredentialDescriptorList가 제공된 경우 반환된 userHandle 값이 null일 수 있습니다. 자세한 내용은 userHandleResult를 참조하세요.

만약 authenticator가 지정된 기준에 맞는 자격증명을 해당 Relying Party에 대해 찾을 수 없다면, 연산을 종료하고 오류를 반환합니다.

6.3.4. The authenticatorCancel Operation

이 연산은 입력 매개변수를 받지 않으며 결과도 반환하지 않습니다.

클라이언트가 authenticator session에서 이 연산을 호출하면, 해당 인증자 세션에서 현재 진행 중인 어떤 authenticatorMakeCredential 또는 authenticatorGetAssertion 연산도 종료됩니다. 인증자는 취소된 연산을 승인하기 위한 어떠한 사용자 입력도 더 이상 요청하거나 수락하지 않습니다. 클라이언트는 취소된 연산에 대한 인증자의 추가 응답을 무시합니다.

이 연산은 만약 그것이 authenticator session에서 호출되었고 해당 세션에 진행 중인 authenticatorMakeCredential 또는 authenticatorGetAssertion 연산이 없다면 무시됩니다.

6.3.5. The silentCredentialDiscovery operation

이것은 선택적 연산으로, 인증자가 conditional user mediation를 가능하게 하기 위해 인증자가 지원할 수 있는 연산입니다.

이 연산은 다음 입력 매개변수를 받습니다:

rpId

호출자의 RP ID, 이는 determined by the client에 의해 결정됩니다.

이 연산이 호출되면, authenticator는 다음 절차를 반드시 수행해야 합니다:

  1. collectedDiscoverableCredentialMetadata를 새로운 list로 하고 그 항목은 다음을 포함하는 DiscoverableCredentialMetadata 구조체입니다:

    type

    PublicKeyCredentialType.

    id

    Credential ID.

    rpId

    Relying Party Identifier.

    userHandle

    user handle.

    otherUI

    인증자가 UI에 정보를 제공하기 위해 사용하는 기타 정보.

  2. For each public key credential source credSource를 이 인증자의 credentials map에서 반복합니다:

    1. 만약 credSourceclient-side discoverable credential이 아니면, continue.

    2. 만약 credSource.rpIdrpId가 아니면, continue.

    3. discoveredCredentialMetadata를 새로운 DiscoverableCredentialMetadata 구조체로 하고, 그 항목들은 credSourcetype, id, rpId, userHandleotherUI의 복사본으로 합니다.

    4. Append를 사용하여 discoveredCredentialMetadatacollectedDiscoverableCredentialMetadata에 추가합니다.

  3. collectedDiscoverableCredentialMetadata를 반환합니다.

6.4. 문자열 처리

인증자는 Relying Party가 선택한 임의의 문자열을 저장해야 할 수 있습니다. 예를 들어 namedisplayName ( PublicKeyCredentialUserEntity 내 ) 등이 있습니다. 이 절에서는 사람에게 표시될 수 있는 임의 문자열을 처리할 때의 실무적 결과에 대해 논의합니다.

6.4.1. 문자열 잘림(String Truncation)

API의 각 임의 문자열은 authenticator가 가질 수 있는 자원 제약을 어느 정도 수용하도록 마련되어야 합니다. 잘림을 수용 방식으로 선택하는 경우, 문자열 값을 손상시키지 않도록 주의해야 합니다.

예를 들어, 단순히 유니코드 코드 포인트 기준으로 잘라내면 그라픔(cluster)이 잘려나갈 수 있습니다. 이로 인해 그라픔 클러스터가 완전히 제거되는 대신 다른 글리프로 렌더링되어 문자열의 의미가 바뀔 수 있습니다. 예를 들어, 그림은 인코딩 길이가 65바이트인 UTF-8 인코딩 문자열의 끝 부분을 보여줍니다. 64바이트로 잘라야 하면 마지막 0x88 바이트가 먼저 제거되어 크기 제한을 만족시킵니다. 이는 부분적인 UTF-8 코드 포인트를 남기므로 그 코드 포인트의 나머지 바이트도 제거되어야 합니다. 그로 인해 부분적인 그라픔 클러스터가 남게 되면, 해당 클러스터의 나머지 부분도 제거해야 합니다.

다양한 잘림 경계의 위치를 보여주는 UTF-8 인코딩 문자열의 끝 부분.

이러한 문제를 처리할 책임은 주로 클라이언트에게 있으며, 이는 authenticators에게 문자 인코딩과 유니코드 문자 속성을 이해하도록 부담을 주지 않기 위함입니다. 다음 하위절에서는 각각 클라이언트와 인증자가 문자열 잘림을 어떻게 수행할 수 있는지에 대한 요구사항을 정의합니다.

6.4.1.1. 클라이언트에 의한 문자열 잘림

WebAuthn Client가 문자열을 잘라낼 때, Relying Party가 관찰할 수 있는 잘림 동작은 다음 요구사항을 충족해야 합니다:

지정된 최소 지원 길이보다 크거나 같은 크기 제한을 선택합니다. 문자열은 UTF-8 문자 인코딩에서의 바이트 길이가 그 제한을 만족하도록 잘릴 수 있습니다. 이 잘림은 UTF-8 코드 포인트 경계를 반드시 존중해야 하며, 그라픔 클러스터 경계를 준수하는 것이 권장됩니다 [UAX29]. 결과로 얻어진 잘린 값은 선택된 크기 제한보다 짧을 수 있지만, 크기 제한을 만족하고 그라픔 클러스터 경계에서 끝나는 가장 긴 접두사 서브스트링보다 짧아서는 안 됩니다.

클라이언트는 이러한 요구사항을 만족한다면 authenticator에게 잘림을 수행하도록 맡길 수 있습니다; 그렇지 않으면 클라이언트는 문자열 값을 인증자에게 전달하기 전에 반드시 잘림을 수행해야 합니다.

위 사항 외에도 바이트 경계에서만 잘라내는 것은 사용자 에이전트가 알아야 할 알려진 문제를 야기합니다: 만약 인증자가 [FIDO-CTAP]를 사용한다면 이후 인증자 메시지가 해당 값이 CBOR 문자열로 타입되었고 유효한 UTF-8이어야 하므로 유효하지 않은 CBOR를 포함할 수 있습니다. 따라서 authenticators를 다룰 때 사용자 에이전트는 다음을 수행해야 합니다:

  1. 인증자에게 전송되는 모든 문자열이 유효하게 인코딩되어 있는지 확인합니다.

  2. 문자열이 잘려서 잘못된 인코딩이 된 경우를 처리합니다. 예를 들어, 끝의 부분적인 코드 포인트는 제거하거나 U+FFFD로 대체할 수 있습니다.

6.4.1.2. 인증자에 의한 문자열 잘림

WebAuthn Authenticator는 제약된 환경에서 구현될 수 있으므로, 인증자에 대한 요구사항은 클라이언트에 대한 요구사항보다 완화됩니다.

WebAuthn Authenticator가 문자열을 잘라낼 때, 잘림 동작은 다음 요구사항을 반드시 충족해야 합니다:

지정된 최소 지원 길이보다 크거나 같은 크기 제한을 선택합니다. 문자열은 UTF-8 문자 인코딩에서의 바이트 길이가 그 제한을 만족하도록 잘릴 수 있습니다. 이 잘림은 UTF-8 코드 포인트 경계를 준수하는 것이 권장되며, 그라픔 클러스터 경계를 준수할 수도 있습니다 [UAX29]. 결과로 얻어진 잘린 값은 선택된 크기 제한보다 짧을 수 있지만, 크기 제한을 만족하고 그라픔 클러스터 경계에서 끝나는 가장 긴 접두사 서브스트링보다 짧아서는 안 됩니다.

6.4.2. 언어 및 방향 인코딩(Language and Direction Encoding)

문자열이 컨텍스트 내에서 올바르게 표시되기 위해서는 문자열의 언어와 기본 방향이 필요할 수 있습니다. 이 API의 문자열은 고정 기능을 갖는 authenticators에 기록되었다가 나중에 다른 플랫폼에서 읽혀 표시될 수 있습니다.

전용 언어 및 방향 메타데이터 필드를 지원하지 않는 기존의 고정 기능 authenticators와의 호환성을 위해, Web Authentication Level 2는 이러한 메타데이터를 문자열 자체에 포함시켜 원자적으로 전송되도록 하는 규정을 포함했습니다. 이 인코딩은 권장되지 않으며; 클라이언트authenticators는 새 값에서 이러한 인코딩을 무시할 수 있습니다. 클라이언트authenticators는 기존 문자열에 인코딩된 언어 및 방향 메타데이터를 감지하고 처리할 수 있으며, 그 방법은 Web Authentication Level 2 §6.4.2. Language and Direction Encoding에 설명되어 있습니다.

대신, 향후 버전의 Web Authentication API는 전용 언어 및 방향 메타데이터 필드를 제공할 수 있습니다.

6.5. Attestation

인증기는 가능하다면 일부 형태의 어테스테이션도 제공해야 합니다. 인증기가 이를 제공한다면 기본적인 요구사항은 인증기가 각 크리덴셜 공개키에 대해, WebAuthn Relying Party가 검증할 수 있는 어테스테이션 스테이트먼트를 생성할 수 있다는 것입니다. 일반적으로, 어테스테이션 스테이트먼트에는 어테스테이션 프라이빗키로 서명된, 보증된 크리덴셜 공개키와 챌린지, 그리고 어테스테이션 공개키에 대한 출처정보를 제공하는 증명서나 비슷한 데이터가 포함되어 Relying Party가 신뢰 여부를 판단할 수 있게 됩니다. 그러나 어테스테이션 키 쌍이 사용 불가능한 경우, 인증기는 해당 크리덴셜 공개키를 대응하는 크리덴셜 프라이빗키셀프 어테스테이션을 수행하거나, 혹은 어테스테이션 없음으로 처리할 수 있습니다. 이 모든 정보는 인증기가 새로운 크리덴셜 공개키를 생성할 때마다, 전체적으로 어테스테이션 오브젝트 형태로 반환됩니다. 어테스테이션 오브젝트인증기 데이터(보증된 크리덴셜 데이터 포함) 및 어테스테이션 스테이트먼트와 어떻게 연결되는지는 아래 figure 에서 보여줍니다.

만약 authenticatorself attestation을 사용하거나 attestation을 제공하지 않는다면, Relying Party가 신뢰 결정을 내릴 수 있는 출처 정보가 제공되지 않습니다. 이러한 경우 인증자는 자신의 동작에 대해 Relying Party에게 어떠한 보장도 제공하지 않습니다.

Attestation object 레이아웃 — 포함된 authenticator data(attested credential data 포함) 및 attestation statement을 보여줍니다.
Note: 이 그림은 packed attestation statement format만을 보여줍니다. 추가적인 여러 attestation statement formats§ 8 Defined Attestation Statement Formats에 정의되어 있습니다.

attestation object의 중요한 구성 요소 중 하나는 attestation statement입니다. 이는 특정 유형의 서명된 데이터 객체로, public key credential 자체와 이를 생성한 authenticator에 대한 진술을 포함합니다. 또한 attesting authority의 키로 생성된 attestation signature를 포함하며, (self attestation의 경우 credential private key로 생성됩니다). attestation statement를 올바르게 해석하려면 Relying Partyattestation의 두 가지 측면을 이해해야 합니다.

  1. attestation statement format은 signature가 표현되는 방식과 여러 가지 맥락적 바인딩이 authenticator에 의해 attestation statement에 포함되는 방식을 말합니다. 즉, 이 값은 진술문의 구문을 정의합니다. 기존의 다양한 구성 요소와 OS 플랫폼(TPM이나 Android OS 등)은 attestation statement formats를 정의한 바 있습니다. 이 명세는 § 6.5.2 Attestation Statement Formats에서 확장 가능한 방식으로 다양한 포맷을 지원합니다. 각각의 포맷은 § 8.1 Attestation Statement Format Identifiers에서 서술된 문자열로 식별됩니다.

  2. attestation typeattestation statements 및 그 기반 신뢰 모델의 의미론을 정의합니다. 특히 Relying Partyattestation statement를 암호학적으로 유효한지 확인한 후, 신뢰를 어떻게 구축하는지에 대한 내용을 정의합니다. 이 명세는 § 6.5.3 Attestation Types에서 설명된 여러 attestation types를 지원합니다.

일반적으로 attestation statement formatsattestation types 사이에 단순한 매핑은 존재하지 않습니다. 예를 들어, attestation statement format 중 "packed"은 § 8.2 Packed Attestation Statement Format에서 정의된 모든 attestation types와 함께 사용될 수 있으며, 다른 포맷 및 타입들은 더 제한적으로 적용될 수 있습니다.

attestation의 프라이버시, 보안 및 운용 특성은 다음에 따라 달라집니다.

attestation typeattestation statement formatauthenticator가 선택합니다. Relying PartiesattestationattestationFormats 파라미터를 설정하여 선호도를 신호로 전달할 수 있습니다.

대부분의 authenticators는 소수의 attestation typesattestation statement formats만을 지원할 것이며, Relying Parties는 정책에 따라 어떤 attestation types가 허용 가능한지 결정합니다. Relying Parties는 또한 자신들이 신뢰하는 authenticators의 특성을 이해해야 하며, 이들 authenticators에 대한 정보가 필요합니다. 예를 들어, FIDO Metadata Service [FIDOMetadataService]는 이러한 정보를 얻는 방법 중 하나입니다.

6.5.1. Attested Credential Data

Attested credential data는 자격증명에 대한 attestation object를 생성할 때 authenticator data에 추가되는 가변 길이 바이트 배열입니다. 그 형식은 에 나와 있습니다.

Name Length (in bytes) Description
aaguid 16 인증자의 AAGUID.
credentialIdLength 2 L 바이트 길이의 credentialId의 길이, 16비트 부호 없는 빅엔디안 정수. 값은 ≤ 1023이어야 합니다.
credentialId L Credential ID
credentialPublicKey variable COSE_Key 형식으로 인코딩된 credential public key, Section 7의 정의에 따라 [RFC9052]을 참고하여 CTAP2 표준 CBOR 인코딩 형식을 사용합니다. COSE_Key로 인코딩된 credential public key는 "alg" 파라미터를 포함해야 하며 다른 선택적 파라미터는 포함해서는 안 됩니다. "alg" 파라미터는 COSEAlgorithmIdentifier 값을 포함해야 합니다. 인코딩된 credential public key는 또한 관련 키 타입 명세에 따라 요구되는 추가적인 필수 파라미터들을 포함해야 합니다(예: 키 타입 "kty" 및 알고리즘 "alg"에 대해 REQUIRED).
Attested credential data 레이아웃. Name 열의 명칭은 문서 내 참조용이며, attested credential data의 실제 표현에는 포함되지 않습니다.
6.5.1.1. COSE_Key 형식으로 인코딩된 credentialPublicKey 값의 예시

이 절에서는 ES256, PS256, RS256 서명 알고리즘에 대한 COSE_Key로 인코딩된 타원곡선 및 RSA 공개키 예시를 제공합니다. 이 예시는 위에서 credentialPublicKey 값에 대해 정의된 규칙을 준수하며, 명확성을 위해 CDDL [RFC8610]로 제시됩니다.

Section 7 of [RFC9052]는 모든 COSE_Key 인코딩 키에 대한 일반적인 프레임워크를 정의합니다. 특정 알고리즘에 대한 키 타입은 [RFC9053] 및 기타 명세에 정의되어 있습니다.

아래는 ES256 서명 알고리즘(ES256, ECDSA w/ SHA-256)에 사용되는 P-256 곡선의 EC2 형식 COSE_Key-인코딩 타원곡선 공개키 예시입니다:

{
  1:   2,  ; kty: EC2 key type
  3:  -7,  ; alg: ES256 signature algorithm
 -1:   1,  ; crv: P-256 curve
 -2:   x,  ; x-coordinate as byte string 32 bytes in length
           ; e.g., in hex: 65eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d
 -3:   y   ; y-coordinate as byte string 32 bytes in length
           ; e.g., in hex: 1e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c
}

위 타원곡선 공개키를 CTAP2 표준 CBOR 인코딩 형태(CTAP2 canonical CBOR encoding form)으로 인코딩한 예시는 다음과 같습니다(명확성을 위해 공백과 줄바꿈 포함):

A5
   01  02

   03  26

   20  01

   21  58 20   65eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d

   22  58 20   1e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c

다음은 PS256 서명 알고리즘에 사용되는 2048비트 RSA 공개키의 COSE_Key-인코딩 예시입니다 ([RFC8230] 섹션 4 참고):

{
  1:   3,  ; kty: RSA key type
  3: -37,  ; alg: PS256
 -1:   n,  ; n:   RSA modulus n byte string 256 bytes in length
           ;      e.g., in hex (middle bytes elided for brevity): DB5F651550...6DC6548ACC3
 -2:   e   ; e:   RSA public exponent e byte string 3 bytes in length
           ;      e.g., in hex: 010001
}

아래는 동일한 COSE_Key-인코딩 RSA 공개키의 RS256 서명 알고리즘( RSASSA-PKCS1-v1_5 with SHA-256 )용 예시입니다:

{
  1:   3,  ; kty: RSA key type
  3:-257,  ; alg: RS256
 -1:   n,  ; n:   RSA modulus n byte string 256 bytes in length
           ;      e.g., in hex (middle bytes elided for brevity): DB5F651550...6DC6548ACC3
 -2:   e   ; e:   RSA public exponent e byte string 3 bytes in length
           ;      e.g., in hex: 010001
}

6.5.2. Attestation Statement Formats

앞서 설명한 바와 같이, attestation statement format은 인증자가 다양한 상황적 바인딩에 대해 생성하는 암호학적 서명을 표현하는 데이터 형식입니다. 각 attestation statement format은 다음 템플릿을 사용하여 정의되어야 합니다:

초기 지정된 attestation statement formats 목록은 § 8 Defined Attestation Statement Formats에 있습니다.

6.5.3. Attestation Types

WebAuthn은 여러 attestation types을 지원하며, 이는 attestation statements와 그 기반 신뢰 모델의 의미론을 정의합니다:

Note: 이 명세는 authenticators가 사용하는 attestation types을 명시적으로 표현하는 데이터 구조를 정의하지 않습니다. Relying Partiesattestation statement verification에 참여할 때—즉, navigator.credentials.create()를 호출하고 attestation conveyancenone이 아닌 값으로 선택한 후 수신된 attestation statement를 검증할 때—사용된 attestation typeverification의 일부로서 판단하게 됩니다. 자세한 구분 및 검증 절차는 § 8 Defined Attestation Statement Formats의 "Verification procedure" 하위항목에서 볼 수 있습니다. 또한 § 14.4.1 Attestation Privacy도 참고 바랍니다. 본 절에서 정의된 모든 attestation typesSelfNone을 제외하면, Relying Party verification 이후, trust path§ 7.1 Registering a New Credentialstep 23에 따라 루트 인증서와 매칭해야 합니다. 이러한 attestation types을 구분하는 것은 Relying Party 정책 아래 attestation의 허용 여부를 판단하는 데 주로 유용합니다.

Basic Attestation (Basic)

기본 attestation의 경우 [UAFProtocol], 인증기의 attestation key pair는 인증기 ‘모델’별로 지정됩니다. 즉, 같은 또는 유사한 모델의 인증기는 종종 동일한 attestation key pair를 공유합니다. 자세한 내용은 § 14.4.1 Attestation Privacy를 참고하세요.

Basic attestationbatch attestation이라고도 불립니다.

Self Attestation (Self)

self attestation, 즉 surrogate basic attestation [UAFProtocol]의 경우, 인증기는 특정 attestation key pair를 갖지 않습니다. 대신, credential private key를 사용해 attestation signature를 생성합니다. attestation private key에 특별한 보호 기구가 없는 인증기는 이 유형을 주로 사용합니다.

Attestation CA (AttCA)

이 경우 authenticator는 TPM(Trusted Platform Module)을 기반으로 하며, 인증기별로 고유한 "endorsement key"(EK)를 보유합니다. 이 키는 Attestation CA와의 안전한 통신에 사용됩니다. [TCG-CMCProfile-AIKCertEnroll] (이전에는 "Privacy CA"로 불림). 인증기는 여러 개의 attestation identity key pairs(AIK)를 생성할 수 있고, 각 AIK에 대한 인증서를 Attestation CA에 요청할 수 있습니다. EK(글로벌 상관 핸들)의 노출을 Attestation CA로 제한하는 효과가 있습니다. 각 authenticator가 생성한 public key credential마다 개별적으로 AIK를 발급받고, Relying Parties에게 attestation certificates로 전달합니다.

Note: 이 방식은 보통 여러 개의 attestation certificates를 생성하며, 가장 최근에 요청된 attestation certificate을 "active"라 칭합니다.

Anonymization CA (AnonCA)

이 경우 authenticatorAnonymization CA을 사용하여 credential 별로 동적으로 attestation certificates를 생성하므로, attestation statements에서 Relying Parties에 고유 식별 정보를 제공하지 않습니다(즉, 추적 용도에 사용될 수 있는 정보가 없음).

Note: Attestation statements 타입 AttCA 또는 AnonCA를 전달할 때, Basic과 동일한 데이터 구조를 사용하므로, 실질적으로 세 attestation 타입의 구분은 attestation certificates의 외부 정보에 의존해야만 가능합니다.

No attestation statement (None)

이 경우, attestation 정보가 제공되지 않습니다. § 8.7 None Attestation Statement Format도 참고하세요.

6.5.4. Generating an Attestation Object

attestation object(Figure 6 참조) 생성을 위해:

attestationFormat

attestation statement format

authData

authenticator data를 포함한 바이트 배열.

hash

직렬화된 클라이언트 데이터의 hash

authenticator는 MUST:

  1. attStmtattestationFormatsigning procedureauthDatahash를 전달하여 얻은 결과로 할당.

  2. fmtattestationFormatattestation statement format identifier로 할당

  3. 아래 구문에 따라 본 알고리즘에서 초기화한 변수들로 채워진 CBOR 맵 형태의 attestation object를 반환:

    attObj = {
        authData: bytes,
    
        ; Each choice in $$attStmtType defines the fmt value and attStmt structure
        $$attStmtType
    } .within attStmtTemplate
    
    attStmtTemplate = {
        authData: bytes,
        fmt: text,
        attStmt: (
          { * tstr => any } ; Map is filled in by each concrete attStmtType
          //
          [ * any ]         ; attStmt may also be an array
        )
    }
    

6.5.5. Signature Formats for Packed Attestation, FIDO U2F Attestation, and Assertion Signatures

새로 정의되는 attestation format은 ASN.1 인코딩을 사용하지 않고, 대신 내부 구조 없는 고정 길이 바이트 배열로 signature를 표현할 것을 권장합니다. [RFC9053][RFC8230]에서 정의한 COSE signature 표기를 적용합니다.

아래 서명 형식 정의들은 이러한 요구사항을 충족하며, 여기 명시되지 않은 다른 서명 알고리즘에도 참고할 수 있습니다:

7. WebAuthn Relying Party Operations

registration 또는 authentication ceremonyWebAuthn Relying PartyPublicKeyCredentialCreationOptions 또는 PublicKeyCredentialRequestOptions 객체를 각각 생성, ceremony의 파라미터를 인코딩함으로써 시작됩니다. Relying Party는 이 단계에서 민감 정보가 유출되지 않도록 주의해야 하며, 자세한 내용은 § 14.6.2 Username Enumeration를 참고하세요.

create() 또는 get() 실행에 성공하면, Relying Party의 스크립트는 PublicKeyCredential 내의 AuthenticatorAttestationResponse 또는 AuthenticatorAssertionResponse 구조를 각각 수신하게 되고, 이 구조 내용을 Relying Party 서버로 전달해야 하며, 이 명세 범위 바깥의 방법을 사용합니다. 이 섹션에서는 Relying Party가 이 구조를 수신한 후 수행해야 하는 동작을 설명합니다.

7.1. Registering a New Credential

registration ceremony 수행을 위해 Relying Party는 다음과 같이 진행해야 합니다:

  1. optionsRelying Party의 ceremony 필요 사항에 맞춘 새로운 CredentialCreationOptions 구조로 할당. pkOptionsoptions.publicKey로 함.

  2. navigator.credentials.create() 호출, 인자로 options 전달. credential은 promise가 성공적으로 resolve될 때의 결과로 할당. promise가 reject될 경우, ceremony를 사용자 오류로 중단하거나 상황에 따라 사용자의 경험을 안내할 수 있음(예: "InvalidStateError"와 동일한 오류 코드가 반환될 경우, 사용자가 다른 authenticator를 사용하도록 안내). 자세한 오류 상황 및 관련 내용은 § 6.3.2 The authenticatorMakeCredential Operation 참고.

  3. responsecredential.response로 할당. responseAuthenticatorAttestationResponse 인스턴스가 아니면 ceremony 중단.

  4. clientExtensionResultscredential.getClientExtensionResults() 호출 결과.

  5. JSONtextresponse.clientDataJSON 값에 대해 UTF-8 decode를 실행한 결과.

    Note: 어떤 구현체의 UTF-8 decode를 사용해도, UTF-8 decode 알고리즘과 동일한 결과가 나와야 하며, BOM(Byte Order Mark) 선행 바이트는 제거해야 함.

  6. C(credential 생성 중 수집된 client data)는 JSONtext에 구현체 의존적인 JSON 파서를 실행한 결과.

    Note: C는 어떤 형식이어도 되나, 본 알고리즘에서 C의 구성 요소를 참조 가능해야 함.

  7. C.type 값이 webauthn.create임을 검증.

  8. C.challenge 값이 pkOptions.challenge 값을 base64url 인코딩한 것과 동일한지 검증.

  9. C.origin 값이 origin으로서 Relying Party가 기대하는 값인지 검증. 구체적 검증 방법은 § 13.4.9 Validating the origin of a credential 참고.
  10. 만약 C.crossOrigin 멤버가 존재하고 값이 true로 설정되어 있다면, Relying Party가 이 자격 증명이 조상들과 동일 출처가 아닌 iframe 내에서 생성되었을 것으로 예상하는지 확인해야 합니다.

  11. C.topOrigin 값이 있으면:

    1. Relying Party가 해당 credential이 same-origin이 아닌 iframe에서 생성될 것으로 기대했는지 검증.

    2. C.topOrigin 값이 origin과 일치하고, Relying Party가 해당 페이지의 하위 프레임에서 생성될 것으로 기대하는 값인지 검증. § 13.4.9 Validating the origin of a credential 참조.

  12. hashresponse.clientDataJSON 값을 SHA-256으로 해시한 결과.

  13. attestationObject 필드를 CBOR 디코딩하여 attestation statement format fmt, authenticator data authData, attestation statement attStmt을 획득.

  14. authData에 있는 rpIdHash 값이 Relying Party가 기대하는 RP ID의 SHA-256 해시값인지 검증합니다.

  15. options.mediation 값이 conditional가 아니면, UP 비트가 authDataflags에 set되어 있음 검증.

  16. Relying Party가 user verification을 요구 시, UV 비트가 set되어 있는지 검증.

  17. BE 비트가 authDataflags에 set되어 있지 않으면, BS 비트도 set되어 있지 않은지 검증.

  18. Relying Party가 credential의 backup eligibility로 사용자 경험 또는 정책을 결정할 경우, BE 비트 평가.

  19. Relying Partybackup state를 참고해 사용자 경험 또는 정책을 결정할 경우, BS 비트 평가.

  20. credential public key의 "alg" 값이 alg 속성이 pkOptions.pubKeyCredParams 목록의 item 중 하나와 일치하는지 검증.

  21. fmt에 대해 USASCII 대소문자 구분 매칭을 통해 지원하는 WebAuthn Attestation Statement Format Identifier 값인지 확인. 최신 등록 값 목록은 [IANA-WebAuthn-Registries]에서 유지되고, [RFC8809]에 의해 정립됨.

  22. attStmt가 올바른 attestation statement이며, 유효한 attestation signature를 전달하는지, attestation statement format fmtverification procedureattStmt, authData, hash를 인자로 사용해 검증.

    Note:attestation statement format은 고유의 verification procedure를 규정합니다. 초기 정의된 형식은 § 8 Defined Attestation Statement Formats와, 최신 목록은 [IANA-WebAuthn-Registries]를 참고.

  23. 검증이 성공하면, 해당 attestation type과 attestation statement format fmt에 대해 정책 또는 신뢰받는 출처로부터 허용 가능한 루트 인증서(trust anchors) 목록을 획득. 예시: FIDO Metadata Service [FIDOMetadataService]aaguid 값을 활용하여 해당 정보를 획득할 수 있습니다.
  24. verification procedure(step 21 참고) 결과를 바탕으로 신뢰도 평가 아래와 같이 수행:

    attestation statement가 신뢰할 만하지 않다고 판단되면, Relying Partyregistration ceremony를 실패해야 합니다.

    NOTE: 단, 정책에서 허용된다면, Relying Partycredential ID와 credential public key를 저장하고, 해당 credential을 self attestation으로 취급할 수 있습니다(자세한 설명은 § 6.5.3 Attestation Types 참조). 이런 경우, Relying Partypublic key credential이 특정 authenticator 모델에서 생성되었다는 암호학적 증거가 없음을 의미합니다. 자세한 내용은 [FIDOSecRef][UAFProtocol] 참고.

  25. credentialId 길이가 1023 바이트 이하인지 검증. 이를 초과하면 RP는 등록 ceremony 실패해야 함.

  26. credentialId 값이 다른 사용자에게 이미 등록되어 있지 않은지 검증. 이미 등록되어 있다면 Relying Partyregistration ceremony 실패.

    Note: Relying Parties가 중복된 credential IDs를 거부하는 이유는 credential IDs의 엔트로피가 충분해 우연한 중복 가능성이 매우 낮으나, self attestation을 제외한 attestation types에는 credential private key 보유를 자체 증명하지 않으므로, 공격자가 피해자의 credential ID 및 credential public key를 획득해 사이트에 자신의 것으로 등록할 수 있기 때문입니다. 만약 해당 사이트가 이 신규 등록을 허용하고, 기존 피해자 credential을 대체한다면, 피해자는 이후 공격자 계정으로 로그인해야 하며, 이때 저장한 정보가 공격자에게 노출될 수 있습니다.

  27. credentialRecord를 새 credential record로 생성, 아래 내용 포함:
    type

    credential.type.

    id

    credential.id 또는 credential.rawIdRelying Party가 선호하는 형식.

    publicKey

    credential public key (authData에서 추출).

    signCount

    authData.signCount.

    uvInitialized

    UV flag(authData 내 값).

    transports

    response.getTransports() 호출 결과.

    backupEligible

    BE flag(authData 내 값).

    backupState

    BS flag(authData 내 값).

    credential record는 아래와 같은 선택적 값도 포함할 수 있음:

    attestationObject

    response.attestationObject 값.

    attestationClientDataJSON

    response.clientDataJSON 값.

    rpId

    pkOptions.rp.id 값.

    Relying Party는 필요하다면 추가 item을 임의로 포함 가능. 예시로, 사용자 경험을 위해 credential에 "nickname"을 추가해 계정 설정에 인증기와 연결성 식별에 활용할 수도 있음.

  28. clientExtensionResultsclient extension outputsauthDataextensionsauthenticator extension outputs 처리. 각 extension에 따라 처리 단계가 구체적으로 규정될 수도 있고, Relying Party 재량에 맡길 수도 있음. Relying Party는 extension output을 무시할 수 있음.

    Clients는 추가 authenticator extension 또는 client extension을 설정할 수 있어, authenticator extension outputs 또는 client extension outputsRelying PartypkOptions.extensions에서 요청하지 않은 값이 포함될 수 있음. Relying Party는 이러한 상황에 확실히 대응할 준비가 되어 있어야 하며, 원치 않는 extension을 무시하거나 attestation을 거부할 수 있습니다. 이는 로컬 정책 및 사용 extension에 따라 결정할 수 있습니다.

    모든 extension은 clientauthenticator 모두에게 OPTIONAL이므로, Relying Party는 none 또는 일부 요청 extension이 작동하지 않은 상황도 처리할 수 있도록 준비해야 함.

  29. 위 단계 모두 성공 시, credentialRecorduser account에 저장(pkOptions.user으로 지정된 계정), 그리고 registration ceremony를 계속. 실패 시에는 registration ceremony를 중단.

    Relying Party가 이 상황에서 registration ceremony를 중단하지 않으면, public key credential이 특정 authenticator 모델에서 생성됐다는 암호학적 증거가 없음을 인정하는 것입니다. Relying Party는 credential을 no attestation(§ 6.5.3 Attestation Types 참고)과 동등하게 취급할 수도 있습니다. 자세한 논의는 [FIDOSecRef][UAFProtocol] 참조.

    attestation objects 검증을 위해서는 Relying Party가 신뢰할 만한 신뢰 anchor(루트 인증서)를 step 22에서 얻을 수 있어야 합니다. 인증서를 사용하는 경우, Relying Party는 중간 CA 인증서의 상태 정보에도 접근 가능해야 하며, 클라이언트가 attestation 정보에서 인증서 체인을 제공하지 않은 경우 Relying Party는 체인을 직접 구성할 수 있어야 합니다.

7.2. 인증 어서션 검증

인증 절차를 수행하기 위해, Relying Party는 다음과 같이 진행해야 한다:

  1. optionsCredentialRequestOptions 구조로 두고, Relying Party의 절차 필요에 맞게 구성한다. pkOptionsoptions.publicKey로 하라.

  2. navigator.credentials.get() 을 호출하고 options를 인자로 넘긴다. credential은 성공적으로 해결된 promise의 결과로 둔다. 만약 promise가 거부되면, 사용자에게 보이는 오류로 절차를 중단하거나 거부된 promise에서 유추 가능한 컨텍스트에 따라 사용자 경험을 안내한다. 다양한 오류 상황과 그에 따른 사정은 § 6.3.3 The authenticatorGetAssertion Operation을 참조하라.

  3. responsecredential.response로 둔다. responseAuthenticatorAssertionResponse의 인스턴스가 아니면, 사용자에게 보이는 오류로 절차를 중단하라.

  4. clientExtensionResultscredential.getClientExtensionResults()를 호출한 결과로 두라.

  5. 만약 pkOptions.allowCredentials 비어 있지 않다면, 다음을 검증한다: credential.id공개 키 인증 정보 중 하나임을, pkOptions.allowCredentials 에 나열된 것들 중의 하나로 식별되는지 확인한다.

  6. 인증되는 사용자를 식별하고 credentialRecord를 해당 credential record로 둔다:

    인증 절차 시작 전(예: 사용자명 또는 쿠키로) 사용자가 식별되었다면,

    식별된 사용자 계정자격 증명 레코드가 있고, 그 idcredential.rawId와 같은지 확인하라. credentialRecord를 해당 credential record로 둔다. response.userHandle 이 존재하면, 그것이 해당 사용자 핸들과 일치하는지 확인하라.

    인증 절차 시작 전 사용자가 식별되지 않았다면,

    response.userHandle 이 존재하는지 확인한다. response.userHandle 이 식별하는 사용자 계정자격 증명 레코드를 가지며, 그 idcredential.rawId와 같은지 확인하라. credentialRecord를 해당 credential record로 둔다.

  7. cData, authData, sigresponseclientDataJSON, authenticatorData, signature 값으로 각각 둔다.

  8. JSONtextcData 값에 UTF-8 decode를 수행한 결과로 둔다.

    참고: UTF-8 decode의 어떤 구현을 사용해도, UTF-8 decode 알고리즘이 산출하는 것과 동일한 결과만 보장하면 된다. 특히, 선두 바이트 순서 표시(BOM)가 있으면 제거되어야 한다.

  9. C를 서명에 사용되었다고 주장되는 클라이언트 데이터로서, JSONtext에 구현별 JSON 파서를 수행한 결과로 둔다.

    참고: C는 구현별 데이터 구조 표현이어도 된다. 이 알고리즘 요구대로 C의 구성 요소 참조 가능성만 있으면 된다.

  10. C.type 값이 webauthn.get 문자열인지 확인하라.

  11. C.challenge 값이 pkOptions.challenge의 base64url 인코딩과 일치하는지 확인하라.

  12. 값이 C.origin origin인지 확인하고, 해당 값이 Relying Party가 기대하는 값이어야 합니다. 자세한 안내는 § 13.4.9 자격 증명의 origin 검증을 참고하세요.
  13. C.crossOrigin 이 존재하고 true인 경우, Relying Party가 해당 자격 증명을 조상과 same-origin이 아닌 iframe 내에서 사용할 것으로 예상하는지 확인하라.

  14. C.topOrigin 이 존재하면:

    1. Relying Party가 해당 자격 증명을 조상과 same-origin이 아닌 iframe 내에서 사용할 것으로 예상하는지 확인하라.

    2. 값이 C.topOrigin origin과 일치하는지 확인합니다. 이 origin은 Relying Party가 해당 페이지에 대해 기대하는 값이어야 하며, 그 페이지가 서브프레임으로 포함되는 경우를 의미합니다. 자세한 안내는 § 13.4.9 자격 증명의 origin 검증에서 확인하십시오.

  15. rpIdHashauthData에 있으며, Relying Party가 기대하는 RP ID의 SHA-256 해시인지 확인하라.

    참고: appid 확장을 사용하는 경우 추가 로직이 필요하다. 세부 내용은 § 10.1.1 FIDO AppID Extension (appid)를 참조하라.

  16. UP 비트가 authDataflags에 설정되어 있는지 확인하라.

  17. 이 assertion에 사용자 검증이 필요한지 판단한다. pkOptions.userVerificationrequired로 설정된 경우에만, 사용자 검증이 요구되어야 한다.

    사용자 검증이 요구되는 경우, UV 비트가 authDataflags에 설정되어 있는지 확인하라. 그렇지 않으면, UV flag 값은 무시한다.

  18. BE 비트가 authDataflags에 설정되어 있지 않으면, BS 비트가 설정되어 있지 않은지 확인하라.

  19. 자격 증명 백업 상태Relying Party의 비즈니스 로직이나 정책에 사용된다면, currentBe, currentBs는 각각 authDataBE, BS 비트의 값으로 한다. credentialRecord.backupEligiblecredentialRecord.backupState와 비교한다:

    1. credentialRecord.backupEligible 이 설정되어 있으면, currentBe도 설정되어 있는지 확인하라.

    2. credentialRecord.backupEligible 이 설정되어 있지 않으면, currentBe도 설정되어 있지 않은지 확인하라.

    3. Relying Party 정책이 있으면 적용하라.

    참고: § 6.1.3 Credential Backup State를 참고하여 Relying PartyBS 플래그 값을 어떻게 처리할 수 있는지 예시를 보라.

  20. cData에 SHA-256 해시를 계산한 결과를 hash로 둔다.

  21. credentialRecord.publicKey를 사용해, authDatahash의 바이너리 결합에 대해 sig가 유효한 서명인지 검증하라.

    참고: 이 검증 단계는 FIDO U2F 인증기의 서명과 호환된다. 상세 내용은 § 6.1.2 FIDO U2F Signature Format Compatibility를 보라.

  22. authData.signCount 가 0이 아니거나, credentialRecord.signCount 가 0이 아니면, 다음 단계를 수행하라:

    • authData.signCount

      credentialRecord.signCount 보다 크면:
      서명 카운터가 유효하다.
      credentialRecord.signCount 이하이면:
      이는 신호일 뿐, 인증기가 복제되었다는 증거는 아니다. 예를 들어 이런 의미일 수 있다:
      • 두 개 이상의 credential private key 복사본이 존재하고 병렬적으로 사용되고 있을 수 있다.

      • 인증기의 오작동.

      • Relying Party가 인증기에서 생성된 순서와 다르게 assertion 응답을 처리하는 race condition.

      Relying Parties는 자신의 운영 특성을 평가하고 이 정보를 위험 점수에 반영해야 합니다. Relying PartycredentialRecord.signCount 값을 업데이트할지, authentication ceremony를 실패 처리할지 여부는 Relying Party별로 결정됩니다.

      서명 카운터에 대한 고려 사항은 § 6.1.1 Signature Counter Considerations를 참조하라.

  23. clientExtensionResults에 있는 클라이언트 확장 출력authDataextensions에 있는 인증기 확장 출력Relying Party의 요구에 따라 처리합니다. 각 확장마다 처리 절차가 구체적으로 명시될 수도 있고, 확장 출력에 대해 Relying Party가 어떻게 처리할지는 재량에 맡길 수도 있습니다. Relying Party는 일부 또는 모든 확장 출력을 무시할 수 있습니다.

    클라이언트는 추가 인증기 확장이나 클라이언트 확장을 추가로 설정할 수 있고, 이로 인해 인증기 확장 출력이나 클라이언트 확장 출력Relying PartypkOptions.extensions에서 요청하지 않은 값이 나타날 수 있다. Relying Party는 이런 상황을 처리할 준비가 되어 있어야 하며, 무단 확장을 무시하거나 assertion을 거부하는 등 정책에 따라 결정할 수 있다.

    모든 확장은 clientauthenticator 모두에 대해 선택 사항이므로, Relying Party는 요청된 확장이 전혀, 또는 일부만 처리된 경우도 다룰 준비가 되어 있어야 한다.

  24. credentialRecord의 상태 값을 다음과 같이 갱신한다:
    1. credentialRecord.signCountauthData.signCount 값으로 갱신한다.

    2. credentialRecord.backupStatecurrentBs 값으로 갱신한다.

    3. credentialRecord.uvInitializedfalse이면, authDataUV 비트 값으로 갱신한다. 이 변경은 WebAuthn user verification에 상응하는 추가 인증요소의 인증을 요구해야 한다; 인증되지 않았으면 이 단계를 건너뛴다.

    Relying Party가 WebAuthn 인증 절차 단계 외 추가 보안 점검을 수행한다면, 위의 상태 갱신은 추가 점검이 성공적으로 끝난 뒤에 이뤄져야 한다.

  25. 위의 모든 단계가 성공적이라면 적절하게 인증 절차를 계속하라. 그렇지 않으면, 인증 절차를 실패 처리하라.

8. 정의된 어테스테이션 명세 형식

WebAuthn은 플러그인 형태의 어테스테이션 명세 형식을 지원합니다. 이 절에서는 그런 형식들에 대한 초기 목록을 정의합니다.

8.1. 어테스테이션 명세 형식 식별자

어테스테이션 명세 형식은 문자열로 식별되며, 이를 어테스테이션 명세 형식 식별자라고 합니다. 이 식별자는 어테스테이션 명세 형식 작성자가 선택합니다.

어테스테이션 명세 형식 식별자는 [IANA-WebAuthn-Registries]가 관리하는 IANA "WebAuthn Attestation Statement Format Identifiers" 레지스트리에 등록하는 것이 좋으며([RFC8809]), 등록된 모든 어테스테이션 명세 형식 식별자는 서로 고유합니다.

등록되지 않은 어테스테이션 명세 형식 식별자는 고유성을 보장하기 위해, 소문자 역방향 도메인 네이밍(reverse domain-name) 방법을 사용하고 개발자가 등록한 도메인명을 사용해야 합니다. 모든 어테스테이션 명세 형식 식별자는 32 오타이트 이하의 길이어야 하며, 인쇄 가능한 US-ASCII 문자만 사용해야 하고, 역슬래시와 따옴표는 사용할 수 없습니다. 즉, [RFC5234]의 VCHAR이지만 %x22(doublequote) 및 %x5c(backslash)는 제외합니다.

참고: 즉, 도메인명을 기반으로 한 어테스테이션 명세 식별자는 LDH Label만 사용할 수 있습니다. [RFC5890] 참고.

구현에서는 WebAuthn 어테스테이션 명세 형식 식별자 비교 시 대소문자를 구분해야 합니다.

여러 버전이 존재할 수 있는 어테스테이션 명세 형식은 식별자에 버전을 포함하여야 합니다. 실제로, 버전이 다르면 서로 다른 형식으로 취급합니다. 예: packed2§ 8.2 Packed Attestation Statement Format의 새 버전입니다.

다음 절에서 현재 정의되어 등록되어 있는 어테스테이션 명세 형식들과 그 식별자를 소개합니다. 최신 등록 어테스테이션 명세 형식 식별자 목록은 어테스테이션 명세 형식 식별자로서 IANA "WebAuthn Attestation Statement Format Identifiers" 레지스트리 [IANA-WebAuthn-Registries]에서 관리합니다 ([RFC8809]).

8.2. Packed 어테스테이션 명세 형식

이것은 WebAuthn에 최적화된 어테스테이션 명세 포맷입니다. 매우 컴팩트하면서도 확장 가능한 인코딩 방식을 사용합니다. 이 방식은 리소스가 제한된 인증자(예: 보안 요소)에서도 구현이 가능합니다.

어테스테이션 명세 포맷 식별자

packed

지원되는 어테스테이션 유형

Basic, Self, AttCA

구문(Syntax)

Packed 어테스테이션 명세의 구문은 다음 CDDL로 정의됩니다:

$$attStmtType //= (
                      fmt: "packed",
                      attStmt: packedStmtFormat
                  )

packedStmtFormat = {
                       alg: COSEAlgorithmIdentifier,
                       sig: bytes,
                       x5c: [ attestnCert: bytes, * (caCert: bytes) ]
                   } //
                   {
                       alg: COSEAlgorithmIdentifier
                       sig: bytes,
                   }

각 필드의 의미는 다음과 같습니다:

alg

COSEAlgorithmIdentifier로, 어테스테이션 서명을 생성할 때 사용된 알고리즘의 식별자를 포함합니다.

sig

어테스테이션 서명을 담고 있는 바이트 문자열입니다.

x5c

이 배열의 요소들은 attestnCert 및 해당 인증서 체인(있는 경우)을 포함하며, 각각 X.509 형식으로 인코딩됩니다. 어테스테이션 인증서 attestnCert는 반드시 배열의 첫 번째 요소여야 합니다.

attestnCert

X.509 형식으로 인코딩된 어테스테이션 인증서입니다.

서명 절차

이 어테스테이션 명세 포맷의 서명 절차는 assertion 서명 생성 절차와 유사합니다.

  1. authenticatorData어테스테이션용 인증자 데이터를, clientDataHash직렬화된 클라이언트 데이터의 해시를 나타냅니다.

  2. Basic 또는 AttCA 어테스테이션이 사용되는 경우, 인증자는 authenticatorDataclientDataHash를 연결(concatenate)한 뒤, 인증자 별 메커니즘으로 선택한 어테스테이션 개인키로 서명하여 sig를 생성합니다. x5cattestnCert와 관련 인증서 체인(있을 경우)을 넣고, alg는 어테스테이션 개인키의 알고리즘으로 설정합니다.

  3. self attestation이 사용되는 경우, 인증자는 authenticatorDataclientDataHash를 연결하여 자격증명(credential) 개인키로 서명해 sig를 생성하고, alg는 해당 개인키 알고리즘으로 설정하며 나머지 필드는 생략합니다.

검증 절차

검증 절차 입력값 attStmt, authenticatorData, clientDataHash가 주어졌을 때 검증 절차는 다음과 같습니다:

  1. attStmt가 위에 정의된 구문에 부합하는 유효한 CBOR인지 확인하고 CBOR 디코딩하여 필드를 추출합니다.

  2. x5c가 있으면:

    • sigauthenticatorDataclientDataHash의 연결에 대해 alg에 명시된 알고리즘으로 attestnCert의 어테스테이션 공개키를 사용한 유효 서명인지 확인합니다.

    • attestnCert§ 8.2.1 Packed 어테스테이션 명세의 인증서 요구사항을 충족하는지 확인합니다.

    • attestnCert에 OID 1.3.6.1.4.1.45724.1.1.4 (id-fido-gen-ce-aaguid) 확장이 있으면, 그 값이 authenticatorDataaaguid와 일치하는지 확인합니다.

    • 필요하면 x5c를 조사하고 외부 지식을 참고하여 attStmtBasic 또는 AttCA 어테스테이션을 나타내는지 판별합니다.

    • 성공하면, 어테스테이션 유형 Basic, AttCA 또는 불확실성, 그리고 attestation trust path x5c를 나타내는 구현별 값을 반환합니다.

  3. x5c가 없는 경우, self attestation이 사용됩니다.

    • algauthenticatorDatacredentialPublicKey 알고리즘과 일치하는지 확인합니다.

    • sigauthenticatorDataclientDataHash의 연결에 대해 alg로 자격증명(public key)을 사용해 유효하게 서명된 것인지 확인합니다.

    • 성공하면 어테스테이션 유형 Self와 빈 attestation trust path를 나타내는 구현별 값을 반환합니다.

8.2.1. Packed 어테스테이션 명세의 인증서 요구 사항

어테스테이션 인증서에는 다음 필드/확장이 반드시 포함되어야 합니다:

추가적으로, Authority Information Access (AIA) 확장에서 엔트리 id-ad-ocsp와 CRL Distribution Point 확장은 둘 다 선택 사항입니다. 이는 많은 어테스테이션 인증서 상태가 인증자 메타데이터 서비스에서 확인 가능하기 때문입니다. 예를 들어 FIDO Metadata Service를 참조하세요.

특정 인증자 모델의 펌웨어는 확장 OID 1.3.6.1.4.1.45724.1.1.5(id-fido-gen-ce-fw-version)를 사용해 구분할 수 있습니다. 이 특성이 있으면, 새로운 펌웨어 리릴리즈마다 증가하는 0 이상의 INTEGER가 들어갑니다. critical로 표시되어서는 안 됩니다.

예를 들어, 다음은 위 확장 OIDs와 필수가 요구된 필드를 포함한 어테스테이션 인증서입니다:

-----BEGIN CERTIFICATE-----
MIIBzTCCAXOgAwIBAgIUYHS3FJEL/JTfFqafuAHvlAS+hDYwCgYIKoZIzj0EAwIw
QTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC1dlYkF1dGhuIFdHMRwwGgYDVQQDDBNF
eGFtcGxlIEF0dGVzdGF0aW9uMCAXDTI0MDEwMzE3NDUyMVoYDzIwNTAwMTA2MTc0
NTIxWjBBMQswCQYDVQQGEwJVUzEUMBIGA1UECgwLV2ViQXV0aG4gV0cxHDAaBgNV
BAMME0V4YW1wbGUgQXR0ZXN0YXRpb24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC
AATDQN9uaFFH4BKBjthHTM1drpb7gIuPod67qyF6UdL4qah6XUp6tE7Prl+DfQ7P
YH9yMOOcci3nr+Q/jOBaWVERo0cwRTAhBgsrBgEEAYLlHAEBBAQSBBDNjDlcJu3u
3mU7AHl9A8o8MBIGCysGAQQBguUcAQEFBAMCASowDAYDVR0TAQH/BAIwADAKBggq
hkjOPQQDAgNIADBFAiA3k3aAUVtLhDHLXOgY2kRnK2hrbRgf2EKdTDLJ1Ds/RAIh
AOmIblhI3ALCHOaO0IO7YlMpw/lSTvFYv3qwO3m7H8Dc
-----END CERTIFICATE-----

위 속성들은 인증서 내부에서 다음과 같은 구조로 인코딩되어 있습니다:

30 21                                    -- SEQUENCE
  06 0B 2B 06 01 04 01 82 E5 1C 01 01 04 -- OID 1.3.6.1.4.1.45724.1.1.4
  04 12                                  -- OCTET STRING
    04  10                               -- OCTET STRING
      CD 8C 39 5C 26 ED EE DE            -- AAGUID cd8c395c-26ed-eede-653b-00797d03ca3c
      65 3B 00 79 7D 03 CA 3C 

30 12                                    -- SEQUENCE
  06 0B 2B 06 01 04 01 82 E5 1C 01 01 05 -- OID 1.3.6.1.4.1.45724.1.1.5
  04 03                                  -- OCTET STRING
    02 01                                -- INTEGER
      2A                                 -- Firmware version: 42

8.2.2. Enterprise Packed 어테스테이션 명세의 인증서 요구 사항

확장 OID 1.3.6.1.4.1.45724.1.1.2 (id-fido-gen-ce-sernum)은 엔터프라이즈 용도의 packed 어테스테이션에서 추가적으로 사용될 수 있습니다. 존재할 경우, 이 확장은 하나의 AAGUID에 대해 디바이스별로 고유한 옥텟 문자열 값을 지정해야 하며, 이 값은 공장 초기화(factory reset) 이후에도 유지되어야 하지만, 디바이스와 연관된 일련번호나 다른 하드웨어 식별자와는 다를 수 있습니다. 이 확장은 critical로 표시되어선 안 되며, 값은 OCTET STRING으로 인코딩됩니다. 이 확장은 비엔터프라이즈 어테스테이션에서는 존재할 수 없습니다.

8.3. TPM 어테스테이션 명세 포맷

이 어테스테이션 명세 포맷은 일반적으로 신뢰 플랫폼 모듈(Trusted Platform Module, TPM)을 암호 엔진으로 사용하는 인증자에서 사용됩니다.

어테스테이션 명세 포맷 식별자

tpm

지원되는 어테스테이션 유형

AttCA

구문(Syntax)

TPM 어테스테이션 명세의 구문은 다음과 같습니다:

$$attStmtType // = (
                       fmt: "tpm",
                       attStmt: tpmStmtFormat
                   )

tpmStmtFormat = {
                    ver: "2.0",
                    (
                        alg: COSEAlgorithmIdentifier,
                        x5c: [ aikCert: bytes, * (caCert: bytes) ]
                    )
                    sig: bytes,
                    certInfo: bytes,
                    pubArea: bytes
                }

각 필드 의미는 다음과 같습니다:

ver

서명이 준수하는 TPM 사양의 버전입니다.

alg

COSEAlgorithmIdentifier로, 어테스테이션 서명을 위해 사용된 알고리즘 식별자를 담습니다.

x5c

aikCert와 그 인증서 체인을 X.509 인코딩으로 담습니다.

aikCert

어테스테이션에 사용된 AIK 인증서로, X.509 인코딩입니다.

sig

어테스테이션 서명으로, [TPMv2-Part2] 11.3.4절에 명시된 TPMT_SIGNATURE 구조입니다.

certInfo

[TPMv2-Part2] 10.12.8절에 명시된 TPMS_ATTEST 구조로, 위 서명이 계산될 때 사용됩니다.

pubArea

TPM에서 자격 증명 공개키를 나타내는 데 사용하는 TPMT_PUBLIC 구조([TPMv2-Part2] 12.2.4 참조)입니다.

서명 절차

authenticatorData어테스테이션용 인증자 데이터를, clientDataHash직렬화된 클라이언트 데이터의 해시를 나타냅니다.

authenticatorDataclientDataHash를 연결하여 attToBeSigned를 만듭니다.

[TPMv2-Part3] 18.2절의 과정에 따라 어테스테이션 개인키를 사용해 서명을 생성하고, extraData 파라미터는 "alg" 시그니처 알고리즘에서 요구하는 해시 알고리즘(SHA-256 등)으로 attToBeSigned를 해싱한 값으로 지정합니다.

pubArea 필드는 자격 증명 공개키의 공개 영역(TPMT_PUBLIC 구조)으로, certInfo 필드는 TPMS_ATTEST 구조(동일명 출력 파라미터), sig 필드는 위에서 생성한 서명 값으로 각각 설정합니다.

참고: TPM에서 pubArea를 TPM2_ReadPublic 명령으로 읽으면 TPU2B_PUBLIC 구조가 반환되는데, 이는 TPMT_PUBLIC 구조 앞에 길이값 2바이트가 붙습니다. pubArea에 넣기 전 반드시 그 2바이트를 빼야 합니다.

검증 절차

검증 절차 입력값 attStmt, authenticatorData, clientDataHash가 주어졌을 때 검증 절차는 다음과 같습니다:

attStmt가 위 구문에 맞는 유효한 CBOR인지 검증하고, CBOR 디코딩하여 필드를 추출합니다.

pubAreaparametersunique 필드가 authenticatorDatacredentialPublicKey 와 동일한지 확인합니다. (위 attestedCredentialData에 포함된 공개키)

authenticatorDataclientDataHash를 연결하여 attToBeSigned를 만듭니다.

certInfo의 무결성을 검증합니다.

  • x5c가 존재하는지 확인합니다.

  • aikCert§ 8.3.1 TPM 어테스테이션 명세의 인증서 요구 사항을 만족하는지 확인합니다.

  • aikCert에 OID 1.3.6.1.4.1.45724.1.1.4 (id-fido-gen-ce-aaguid) 확장이 있다면, 해당 값이 authenticatorDataaaguid와 일치하는지 확인합니다.

  • sigcertInfo에 대해 aikCert의 어테스테이션 공개키와 alg에 명시된 알고리즘으로 유효한 서명인지 검사합니다.

certInfo가 올바른지 검증합니다: 참고: certInfo는 TPMS_ATTEST 구조체입니다.

  • magicTPM_GENERATED_VALUE로 설정되어 있는지 확인합니다.

  • typeTPM_ST_ATTEST_CERTIFY로 설정되어 있는지 확인합니다.

  • extraDataattToBeSigned에 "alg"에서 사용하는 해시 알고리즘을 적용한 값과 일치하는지 확인합니다.

  • attested[TPMv2-Part2] 10.12.3 절에 명시된 TPMS_CERTIFY_INFO 구조가 포함되어 있는지 확인하며, 그 name 필드가 pubArea에 대해 [TPMv2-Part1] 16절 절차에 따라 계산된 올바른 Name인지 확인합니다.

    참고: TPM은 항상 pubArea에 있는 nameAlg와 동일한 nameAlg를 name에 가진 TPMS_CERTIFY_INFO 구조를 반환합니다.

    참고: "표준 어테스테이션 구조"([TPMv2-Part1] 31.2절)에서의 나머지 필드인 qualifiedSigner, clockInfo, firmwareVersion는 무시합니다. 사용된 aikCert 키의 특성에 따라 이 필드들은 난독화될 수 있습니다. 유효하다면 위험 엔진 input으로 사용할 수도 있습니다.

  • 성공하면, 어테스테이션 유형 AttCAattestation trust path x5c를 나타내는 구현별 값을 반환합니다.

8.3.1. TPM 어테스테이션 명세의 인증서 요구 사항

TPM 어테스테이션 인증서에는 다음 필드/확장이 반드시 포함되어야 합니다:

8.4. Android Key 어테스테이션 명세 형식

문제가 되는 인증자가 Android "N" 이상 플랫폼의 플랫폼 인증자인 경우, 어테스테이션 명세는 Android 키 어테스테이션을 기반으로 한다. 이 경우, 어테스테이션 명세는 보안 운영 환경에서 실행되는 구성 요소에 의해 생성되지만, 어테스테이션용 인증자 데이터는 이 환경 외부에서 생성된다. WebAuthn Relying Party어테스테이션용으로 사용되었다고 주장되는 인증자 데이터가 어테스테이션 인증서 확장 데이터의 필드와 일치하는지 검사해야 한다.

어테스테이션 명세 포맷 식별자

android-key

지원되는 어테스테이션 유형

Basic

구문(Syntax)

Android 키 어테스테이션 명세는 Android 어테스테이션 명세(일련의 DER 인코딩된 X.509 인증서)로 구성된다. 자세한 내용은 Android 개발자 문서 참조. 구문은 다음과 같이 정의된다:

$$attStmtType //= (
                      fmt: "android-key",
                      attStmt: androidStmtFormat
                  )

androidStmtFormat = {
                      alg: COSEAlgorithmIdentifier,
                      sig: bytes,
                      x5c: [ credCert: bytes, * (caCert: bytes) ]
                    }

서명 절차

authenticatorData어테스테이션용 인증자 데이터로, clientDataHash직렬화된 클라이언트 데이터의 해시로 둔다.

Android Key Attestation은 keyStore.getCertificateChain(myKeyUUID)를 호출하면서 challenge 값으로 clientDataHash를 제공하여 요청한다(예: setAttestationChallenge 사용). x5c는 반환값으로 설정한다.

인증자는 authenticatorDataclientDataHash를 연결하고, 자격 증명 개인키로 서명해 sig를 생성한다. alg는 서명 포맷 알고리즘으로 설정한다.

검증 절차

검증 절차 입력값 attStmt, authenticatorData, clientDataHash가 주어지면, 검증 절차는 다음과 같다:

  • attStmt가 위 구문에 부합하는 유효한 CBOR인지 검증하고 CBOR 디코딩하여 필드 추출.

  • sigauthenticatorDataclientDataHash를 연결한 값에 대해 x5c의 첫 번째 인증서에 있는 공개키와 alg에 명시된 알고리즘으로 유효한 서명인지 확인.

  • x5c 첫 번째 인증서의 공개키가 authenticatorDatacredentialPublicKey와 일치하는지 확인.

  • 어테스테이션 인증서 확장 데이터attestationChallenge 필드가 clientDataHash와 동일한지 확인.

  • 어테스테이션 인증서 확장 데이터의 적합한 인가 리스트를 사용해서 다음을 검증:

    • AuthorizationList.allApplications 필드가 두 인가 리스트(softwareEnforcedteeEnforced) 중 어디에도 존재하지 않아야 함. PublicKeyCredential은 반드시 RP ID 범위이어야 함.

    • 다음 검증에서는, RP가 신뢰 실행 환경의 키만 허용하면 teeEnforced만, 아니면 teeEnforcedsoftwareEnforced를 합친 리스트 사용.

      • AuthorizationList.origin 값이 KM_ORIGIN_GENERATED와 같은지 확인.

      • AuthorizationList.purpose 값이 KM_PURPOSE_SIGN와 같은지 확인.

  • 성공 시, 어테스테이션 유형 Basicattestation trust path x5c를 나타내는 구현별 값을 반환.

8.4.1. Android Key Attestation 명세의 인증서 요구사항

Android Key Attestation 어테스테이션 인증서android key attestation certificate extension data는 OID 1.3.6.1.4.1.11129.2.1.17로 식별되며, 스키마는 Android 개발자 문서에서 정의한다.

8.5. Android SafetyNet 어테스테이션 명세 포맷

참고: 이 형식은 더 이상 사용되지 않으며, 문서의 다음 개정에서 삭제될 예정이다.

인증자가 특정 Android 플랫폼의 플랫폼 인증자인 경우, 어테스테이션 명세가 SafetyNet API를 기반으로 할 수 있다. 이때 인증자 데이터는 SafetyNet API를 호출하는 측(일반적으로 Android 플랫폼에서 실행 중인 앱)이 완전히 제어하며, 어테스테이션 명세는 플랫폼의 무결성 및 호출 앱의 식별에 관한 정보를 제공한다(자세한 내용은 SafetyNet 공식 문서 참고).

어테스테이션 명세 포맷 식별자

android-safetynet

지원되는 어테스테이션 유형

Basic

구문(Syntax)

Android 어테스테이션 명세의 구문은 다음과 같이 정의된다:

$$attStmtType //= (
                      fmt: "android-safetynet",
                      attStmt: safetynetStmtFormat
                  )

safetynetStmtFormat = {
                          ver: text,
                          response: bytes
                      }

위 필드의 의미는 다음과 같다:

ver

SafetyNet API를 제공하는 Google Play Services의 버전 번호.

response

SafetyNet API의 getJwsResult() 호출 결과의 UTF-8 인코딩된 값. 이 값은 JWS [RFC7515] 객체(Compact Serialization 참고)이다(SafetyNet 공식 문서 참고).

서명 절차

authenticatorData어테스테이션용 인증자 데이터로, clientDataHash직렬화된 클라이언트 데이터의 해시로 둔다.

authenticatorDataclientDataHash를 연결하여 SHA-256 해시하고, 해시 결과를 attToBeSigned로 설정한다.

SafetyNet 어테스테이션을 요청하면서, attToBeSigned를 nonce 값으로 제공한다. response는 그 결과로, ver는 인증자에서 실행 중인 Google Play Services의 버전으로 설정한다.

검증 절차

검증 절차 입력값 attStmt, authenticatorData, clientDataHash가 주어질 때, 검증 절차는 다음과 같다:

  • attStmt가 위 구문에 맞는 유효한 CBOR인지 검증하고 CBOR 디코딩하여 필드 추출.

  • responsever 버전에 해당하는 유효한 SafetyNet 응답인지 SafetyNet 공식 문서 가이드대로 확인. 현재는 SafetyNet 응답 포맷이 하나이며, ver는 향후 확장용으로 예약됨.

  • response 페이로드의 nonce 속성이 authenticatorDataclientDataHash를 연결 후 SHA-256 해시(Base64 encoding) 값과 동일한지 확인.

  • SafetyNet 응답이 실제로 SafetyNet 서비스에서 온 것인지 SafetyNet 공식 문서 안내대로 검증.

  • 성공 시, 어테스테이션 유형 Basicattestation trust path x5c를 구현별 값으로 반환.

8.6. FIDO U2F 어테스테이션 명세 포맷

이 어테스테이션 명세 포맷은 [FIDO-U2F-Message-Formats]에 정의된 형식으로 FIDO U2F 인증자와 함께 사용한다.

어테스테이션 명세 포맷 식별자

fido-u2f

지원되는 어테스테이션 유형

Basic, AttCA

구문(Syntax)

FIDO U2F 어테스테이션 명세의 구문은 다음과 같이 정의됨:

$$attStmtType //= (
                      fmt: "fido-u2f",
                      attStmt: u2fStmtFormat
                  )

u2fStmtFormat = {
                    x5c: [ attestnCert: bytes ],
                    sig: bytes
                }

위 필드의 의미는 다음과 같다:

x5c

X.509 형식의 어테스테이션 인증서를 단일 요소 배열로 포함함.

sig

어테스테이션 서명. 이 서명은 [FIDO-U2F-Message-Formats]에서 정의된 (원시) U2F 등록 응답 메시지에 대해 인증자로부터 클라이언트가 받은 데이터에 대해 계산됨.

서명 절차

attested credentialcredential public key가 알고리즘 -7("ES256")이 아니면 중단 후 오류 반환. 그렇지 않으면, authenticatorData어테스테이션용 인증자 데이터로, clientDataHash직렬화된 클라이언트 데이터의 해시로 둔다.(SHA-256을 사용해 해시되므로 clientDataHash는 32바이트)

[FIDO-U2F-Message-Formats]Section 4.3에 따라 Registration Response Message를 생성. application 파라미터는 주어진 자격 증명범위 지정RP ID의 SHA-256 해시, challenge 파라미터는 clientDataHash, key handle 파라미터는 해당 credential ID로 설정. 이 Registration Response Message에서 (사용자 공개키, key handle, 어테스테이션 인증서 제외) 순수 서명 부분을 sig에, 어테스테이션 공개키 인증서를 x5c에 각각 설정.

검증 절차

검증 절차 입력값 attStmt, authenticatorData, clientDataHash가 주어졌을 때, 검증 절차는 다음과 같다:

  1. attStmt가 위 구문에 맞는 유효한 CBOR인지 검증하고 CBOR 디코딩 후 필드 추출.

  2. x5c가 정확히 1개의 요소인지 확인 후, 해당 요소를 attCert로 둔다. certificate public keyattCert가 가진 공개키로 둔다. 만약 certificate public key가 P-256 곡선 상의 타원 곡선(EC) 공개키가 아니면 알고리즘 종료 및 오류 반환.

  3. authenticatorData에서 주장된 rpIdHash를, authenticatorData.attestedCredentialData에서 credentialId, credentialPublicKey를 추출한다.

  4. COSE_KEY로 포맷된 credentialPublicKey(RFC9052 Section 7 참조)를 Raw ANSI X9.62 공개키 포맷(FIDO-Registry 3.6.2)으로 변환.

    • credentialPublicKey의 "-2"키(x좌표) 값이 32바이트인지 확인. 아니거나 없으면 알고리즘 종료 및 오류 반환.

    • credentialPublicKey의 "-3"키(y좌표) 값이 32바이트인지 확인. 아니거나 없으면 알고리즘 종료 및 오류 반환.

    • publicKeyU2F0x04 || x || y 연결 구조로 만든다.

      참고: 이것은 비압축 ECC 키 포맷임을 나타냄.

  5. verificationData를 (0x00 || rpIdHash || clientDataHash || credentialId || publicKeyU2F) 의 연결로 만든다(Section 4.3 참고).

  6. [SEC1] 4.1.4절 및 hash함수 SHA-256으로 verificationDatacertificate public keysig를 검증한다.

  7. 필요하면 x5c를 조사하고 외부 정보를 참고해 attStmtBasic 또는 AttCA 어테스테이션을 나타내는지 판별한다.

  8. 성공 시, 어테스테이션 유형 Basic, AttCA 또는 불확실성, 그리고 attestation trust path x5c를 구현별 값으로 반환한다.

8.7. None 어테스테이션 명세 포맷

None 어테스테이션 명세 포맷은 WebAuthn Relying Party가 어테스테이션 정보를 원하지 않는다는 의사를 표시할 때(자세한 내용은 § 5.4.7 Attestation Conveyance Preference Enumeration (enum AttestationConveyancePreference) 참조), 인증자가 제공한 어테스테이션 명세를 대체하는 데 사용된다.

인증자어테스테이션을 지원하지 않으면, 인증자가 이 형식의 어테스테이션 명세를 직접 생성할 수도 있다.

어테스테이션 명세 포맷 식별자

none

지원되는 어테스테이션 유형

None

구문(Syntax)

none 어테스테이션 명세의 구문은 다음과 같이 정의된다:

$$attStmtType //= (
                      fmt: "none",
                      attStmt: emptyMap
                  )

emptyMap = {}
서명 절차

위에 정의된 고정 어테스테이션 명세를 반환한다.

검증 절차

어테스테이션 유형 None 및 빈 attestation trust path를 나타내는 구현별 값을 반환한다.

8.8. Apple 익명 어테스테이션 명세 형식

이 어테스테이션 명세 형식은 Apple에서 WebAuthn을 지원하는 특정 Apple 기기에서만 사용됩니다.

어테스테이션 명세 형식 식별자

apple

지원 어테스테이션 타입

익명화 CA

구문

Apple 어테스테이션 명세의 구문은 아래와 같이 정의됩니다:

$$attStmtType //= (
                      fmt: "apple",
                      attStmt: appleStmtFormat
                  )

appleStmtFormat = {
                      x5c: [ credCert: bytes, * (caCert: bytes) ]
                  }

이 필드들의 의미는 다음과 같습니다:

x5c

credCert와 그 이후의 인증서 체인이 X.509 형식으로 각각 들어갑니다.

credCert

어테스테이션에 사용되는 자격 증명 공개키 인증서로, X.509 형식입니다.

서명 절차
  1. authenticatorData를 어테스테이션의 인증기 데이터로 하고, clientDataHash직렬화된 클라이언트 데이터의 해시로 둡니다.

  2. authenticatorDataclientDataHash를 연결하여 nonceToHash를 만듭니다.

  3. nonceToHash에 SHA-256 해시를 하여 nonce를 생성합니다.

  4. Apple 익명 어테스테이션 CA가 자격 증명 공개키에 대한 X.509 인증서를 발급하며, nonce를 OID 1.2.840.113635.100.8.2 확장 필드로 인증서에 포함합니다. credCert가 이 인증서입니다. credCert가 어테스테이션 증거가 되며, 포함된 nonce는 해당 어테스테이션이 실시간임을 증명합니다. 또한 nonceauthenticatorData클라이언트 데이터의 무결성도 보장합니다.

  5. x5ccredCert와 인증서 체인들을 넣습니다.

검증 절차

검증 절차 입력(attStmt, authenticatorData, clientDataHash)가 주어지면, 검증 절차는 다음과 같이 진행됩니다:

  1. attStmt가 위에서 정의한 구문대로의 유효한 CBOR인지 확인하고, CBOR 디코딩으로 필드를 추출합니다.

  2. authenticatorDataclientDataHash를 연결해 nonceToHash를 만듭니다.

  3. nonceToHash에 SHA-256 해시를 하여 nonce를 생성합니다.

  4. nonce값이 credCert의 OID 1.2.840.113635.100.8.2 확장 필드 값과 동일한지 검증합니다.

  5. 자격 증명 공개키credCert의 Subject Public Key 값이 같은지 검증합니다.

  6. 모두 성공하면 어테스테이션 타입 익명화 CA와 어테스테이션 트러스트 경로 x5c를 나타내는 구현별 값들을 반환합니다.

8.9. 복합 어테스테이션 명세 형식

"compound" 어테스테이션 명세 형식은 한 번의 ceremony에서 여러 개의 독립된(자기완결적) 어테스테이션 명세를 전달하는 데 사용됩니다.

어테스테이션 명세 형식 식별자

compound

지원 어테스테이션 타입

제한 없음. § 6.5.3 어테스테이션 타입 참고.

구문

복합 어테스테이션 명세의 구문은 다음과 같이 정의됩니다:

$$attStmtType //= (
                      fmt: "compound",
                      attStmt: [2* nonCompoundAttStmt]
                  )

nonCompoundAttStmt = { $$attStmtType } .within { fmt: text .ne "compound", * any => any }
서명 절차

해당 없음

검증 절차

검증 절차 입력값 attStmt, authenticatorData, clientDataHash가 주어지면, 검증 절차는 다음과 같습니다:

  1. attStmtsubStmt에 대해, attestation statement format identifier subStmt.fmt에 해당하는 verification procedureverification procedure inputs subStmt, authenticatorData, clientDataHash와 함께 평가한다.

    하나 이상의 subStmt에 대한 검증이 실패하면, Relying Party 정책에 따라 적절한 결과를 결정한다.

  2. Relying Party 정책에 따라 충분히 많은 수의 항목attStmt에서 성공적으로 검증된 경우, 성공한 verification procedure의 출력 중 아무 조합이나 구현별 값을 반환한다.

9. WebAuthn 확장

공개키 자격 증명의 생성, 인증 어서션의 요청 및 생성을 위한 § 5 Web Authentication API에서 정의된 메커니즘은 특정 용례에 맞게 확장할 수 있습니다. 각 용례는 등록 확장 또는 인증 확장을 정의함으로써 지원됩니다.

모든 확장은 클라이언트 확장입니다. 즉, 확장은 클라이언트와의 통신과 처리 과정을 포함합니다. 클라이언트 확장은 다음과 같은 단계와 데이터를 정의합니다:

공개키 자격 증명을 생성하거나 인증 assertion을 요청할 때, WebAuthn Relying Party는 확장(extension) 집합의 사용을 요청할 수 있다. 이 확장들은 클라이언트 및/또는 WebAuthn Authenticator가 지원하는 경우 요청된 동작 시점에 실행된다. Relying Party는 각 확장에 대한 클라이언트 확장 입력값get() 호출 시(인증 확장) 또는 create() 호출 시(등록 확장) 클라이언트에 전달한다. 클라이언트클라이언트 확장 처리를 지원하는 각 확장에 대해 수행하고, 각 확장의 명세에 따라 클라이언트 데이터를 확장하며, 그 안에 확장 식별자클라이언트 확장 출력값을 포함시킨다.

확장은 authenticator extension이 될 수 있으며, 이는 확장이 인증자와의 통신 및 처리에 관여함을 의미한다. 인증자 확장은 다음 단계 및 데이터를 정의함:

인증자 확장의 경우, 클라이언트 확장 처리의 일부로, 클라이언트는 각 확장에 대해(대게 관련 클라이언트 확장 입력 값을 바탕으로) CBOR 인증자 확장 입력 값을 생성하여, create() 호출(등록 확장용) 또는 get() 호출(인증 확장용)에서 인증자에 전달한다. 이러한 인증자 확장 입력 값은 CBOR로 표현되며, 확장 식별자를 이름(name), 대응하는 인증자 확장 입력을 값(value)으로 하는 name-value 쌍으로 전달된다. 인증자는 자신이 지원하는 확장에 대해 추가 처리를 하고, 각 확장에 대해 CBOR 인증자 확장 출력을 반환한다. 인증자 확장 출력은 서명된 인증자 데이터 일부로 반환되므로, 인증자 확장은 서명되지 않은 확장 출력도 추가적으로 지정할 수 있다(예: 출력이 인증자 데이터에 의존적일 때). 인증자 확장클라이언트 확장 처리의 일부로 인증자 확장 출력서명되지 않은 확장 출력클라이언트 확장 출력 생성의 인풋으로 활용한다.

모든 WebAuthn 확장은 클라이언트와 인증자 모두에 대해 OPTIONAL이다. 따라서 Relying Party가 요청한 확장은 브라우저나 OS에서 무시되어 인증자에 전달되지 않거나, 인증자에서 무시될 수 있다. 확장을 무시하는 것은 WebAuthn API 처리에서 결코 실패로 간주되지 않으므로, Relying Party는 API 호출에 확장을 포함할 때, 일부 또는 모든 확장이 무시되는 경우를 반드시 처리할 준비가 되어 있어야 한다.

모든 WebAuthn 확장클라이언트 또는 인증자가 이를 지원하지 않아도 사용자의 보안이나 프라이버시에 위험이 없도록 정의되어야 한다. 예를 들어 확장에서 클라이언트 처리과정이 요구된다면, 단순히 클라이언트 확장 입력을 JSON에서 CBOR로 변환만 수행하는 pass-through가 의미적으로 잘못된 인증자 확장 입력을 만들게 정의해도 무방하며, 이 경우 인증자에서 확장이 무시된다. 모든 확장이 OPTIONAL이므로 이는 기능적 실패를 초래하지 않는다.

등록된 WebAuthn 확장의 최신 목록은 IANA "WebAuthn Extension Identifiers" registry [IANA-WebAuthn-Registries][RFC8809]를 참고할 수 있다.

9.1. 확장 식별자

확장은 확장 저자가 지정하는 문자열인 확장 식별자로 식별됩니다.

확장 식별자는 [IANA-WebAuthn-Registries]의 IANA "WebAuthn Extension Identifiers" registry에 등록하는 것이 좋으며([RFC8809]), 등록된 모든 확장 식별자는 서로 고유합니다.

등록되지 않은 확장 식별자는 전역적으로 고유하도록, 예를 들어 정의 엔티티 이름을 포함(myCompany_extension 등)하는 식으로 지어야 합니다.

모든 확장 식별자는 최대 32 옥타이트 이내, 인쇄 가능한 USASCII 문자만(따옴표, 역슬래시 제외)이어야 하며, [RFC5234]의 VCHAR이지만 %x22/5c 없이 구성되어야 하고, 구현체는 대소문자를 구분해서 비교해야 합니다.

여러 버전이 존재할 수 있는 확장은 식별자에 버전을 포함하도록 해야 합니다. 실제로, 버전이 다르면 각기 다른 확장으로 간주됩니다. 예: myCompany_extension_01

§ 10 정의된 확장은 추가 확장과 그 식별자를 정의합니다. 최신 목록은 IANA "WebAuthn Extension Identifiers" [IANA-WebAuthn-Registries]에서 확인하십시오.

9.2. 확장 정의 방법

확장의 정의는 확장 식별자클라이언트 확장 입력값 인자를 명시해야 하며, 이 인자는 get() 또는 create() 호출을 통해 전달된다. 클라이언트 확장 처리 규칙과 클라이언트 확장 출력값을 명시해야 한다. 확장이 인증자와 통신하는 경우(인증자 확장이라는 의미), CBOR 인증자 확장 입력 인자를 authenticatorGetAssertion 또는 authenticatorMakeCredential 호출을 통해 전달함을 지정해야 하며, 인증자 확장 처리 규칙과 CBOR 인증자 확장 출력값도 명시해야 한다. 확장에서는 unsigned extension outputs 또한 명시할 수 있다.

클라이언트에서 처리되는 클라이언트 확장은 반드시 클라이언트 확장 출력값을 반환해야 하며, 이를 통해 WebAuthn Relying Party는 확장이 클라이언트에 의해 처리되었음을 알 수 있다. 유사하게, 인증자 처리가 필요한 확장은 반드시 인증자 확장 출력값을 반환하여 Relying Party가 해당 처리가 인증자에서 이루어졌음을 알 수 있도록 해야 한다. 결과값이 별도로 필요 없는 확장은, 처리되었음을 나타내기 위해 JSON Boolean 클라이언트 확장 출력값true로 반환해야 한다. 마찬가지로, 별도의 결과값이 필요 없는 인증자 확장은 값을 반환해야 하며, true로 설정된 CBOR Boolean 인증자 확장 출력값을 반환해야 한다.

9.3. 요청 파라미터의 확장

확장은 최대 두 개의 요청 인자를 정의한다. 클라이언트 확장 입력값은 JSON으로 인코딩할 수 있는 값이며, WebAuthn Relying Party에서 클라이언트로 get() 또는 create() 호출에서 전달된다. CBOR 인증자 확장 입력값은 클라이언트에서 인증자로, 이러한 호출이 처리되는 동안 인증자 확장에 대해 전달된다.

Relying Party는 확장의 사용을 동시에 요청하고, extensions 옵션에 create() 또는 get() 호출 시 확장 식별자를 키로, 클라이언트 확장 입력값을 값으로 하는 엔트리를 포함시킨다.

참고: 다른 문서에서 확장 입력값이 확장 식별자 대신 키로 사용되지 않는 사례가 있다. 새로운 확장에는 위 규칙이 계속 적용된다.

var assertionPromise = navigator.credentials.get({
    publicKey: {
        // Other members omitted for brevity
        extensions: {
            // An "entry key" identifying the "webauthnExample_foobar" extension,
            // whose value is a map with two input parameters:
            "webauthnExample_foobar": {
              foo: 42,
              bar: "barfoo"
            }
        }
    }
});

확장 정의는 해당 클라이언트 확장 입력값의 유효 값을 명시해야 한다. 클라이언트는 유효하지 않은 입력값의 확장은 무시해야 한다. 확장에서 Relying Party로부터 인자를 요구하지 않는다면, Boolean 타입 클라이언트 인수로 정의하며, true로 확장 요청을 표시해야 한다.

클라이언트 처리에만 영향을 주는 확장은 인증자 확장 입력값을 명시할 필요 없다. 인증자 처리가 포함되는 확장은 클라이언트 확장 입력값에서 인증자 확장 입력값을 어떻게 계산할지 방법을 반드시 명시해야 하며, CDDL 타입 AuthenticationExtensionsAuthenticatorInputsAuthenticationExtensionsAuthenticatorOutputs에 대한 확장도 반드시 정의해야 한다. 이 때, $$extensionInput$$extensionOutput group sockets의 추가 선택지로 확장 식별자를 엔트리 키로 정의해야 한다. 입력 파라미터를 요구하지 않고(즉 클라이언트 확장 입력값true인 Boolean 값으로 정의되는 확장)은 인증자 확장 입력 또한 CBOR major type 7, value 21의 상수 Boolean true로 정의해야 한다.

다음 예시는 식별자 webauthnExample_foobar로 정의된 확장이 인증자 확장 입력으로 부호 없는 정수를 받고, 인증자 확장 출력으로 바이트 문자열(1개 이상) 배열을 반환하는 경우이다:

$$extensionInput //= (
  webauthnExample_foobar: uint
)
$$extensionOutput //= (
  webauthnExample_foobar: [+ bytes]
)

일부 인증자는 Bluetooth Low-Energy, NFC 등 저대역폭 링크로 통신하므로, 확장은 인증자 인자(argument)가 가능한 한 작아야 한다.

9.4. 클라이언트 확장 처리

확장은 자격 증명 생성 또는 assertion 생성 중 클라이언트에 대해 추가 처리 요건을 정의할 수 있다. 확장에 대한 클라이언트 확장 입력값은 이 클라이언트 처리의 입력값으로 사용된다. 지원하는 클라이언트 확장마다, 클라이언트는 clientExtensions 확장 식별자를 키로, 해당 확장의 클라이언트 확장 입력을 값으로 추가한다.

마찬가지로, 클라이언트 확장 출력getClientExtensionResults() 결과에서 딕셔너리 형태로 나타나며, 확장 식별자가 키이고, 각 확장의 클라이언트 확장 출력 값이 값이 된다. 클라이언트 확장 입력과 마찬가지로, 클라이언트 확장 출력도 JSON으로 인코딩될 수 있는 값이어야 한다. 무시된 확장에 대해서는 어떤 값도 반환하면 안 된다.

인증자 처리가 필요한 확장은 반드시 클라이언트 확장 입력으로 CBOR 인증자 확장 입력을 결정하는 방법과, (사용할 경우)CBOR 인증자 확장 출력/ unsigned extension output클라이언트 확장 출력 값으로 결정하는 방법을 정의해야 한다.

9.5. 인증자 확장 처리

처리된 각 인증자 확장CBOR 인증자 확장 입력 값은 authenticatorMakeCredentialauthenticatorGetAssertion 연산의 extensions 파라미터에 포함된다. extensions 파라미터는 각 키가 확장 식별자이고, 해당 값이 인증자 확장 입력CBOR 맵이다.

확장 출력은 extensions 부분에 담긴다. 인증자 데이터extensions 부분은, 각 키가 확장 식별자이고, 해당 값이 그 확장에 대한 인증자 확장 출력인 CBOR 맵이다.

Unsigned extension outputs인증자 데이터와 독립적으로 표현되며, 인증자가 별도의 맵으로 반환하며 확장 식별자를 키로 한다. 이 맵에는 unsigned 출력을 사용하는 인증자 확장만 항목이 들어간다. unsigned output은 확장 출력이 인증자 데이터에 대한 서명일 때(그렇지 않으면 자기 자신을 서명해야 하므로 불가), 또는 일부 확장 출력이 Relying Party로 전송되지 않아야 할 때 사용할 수 있다.

참고: [FIDO-CTAP]에서 unsigned extension outputsauthenticatorMakeCredentialauthenticatorGetAssertion 양쪽 모두에서 unsignedExtensionOutputs라는 최상위 필드의 CBOR 맵으로 반환된다.

지원하는 각 확장에 대해, 해당 확장에 대한 인증자 확장 처리 규칙을 사용해 인증자 확장 출력unsigned extension output(사용 시)을 인증자 확장 입력 및 그 외 입력들로부터 생성한다. 무시된 확장에 대해서는 어떤 값도 반환되면 안 된다.

10. 정의된 확장

이 절과 하위 절에서는 IANA "WebAuthn Extension Identifiers" 레지스트리([IANA-WebAuthn-Registries])에 추가로 등록될 확장들을 정의합니다. 이 확장들은 다양한 상호운용성을 목표로 사용자 에이전트에서 구현될 수 있습니다.

10.1. 클라이언트 확장

이 절에서는 오직 클라이언트 확장만을 정의합니다.

10.1.1. FIDO AppID 확장 (appid)

이 확장 기능은 이전에 레거시 FIDO U2F JavaScript API [FIDOU2FJavaScriptAPI]를 통해 자격 증명을 등록한 WebAuthn Relying Partyassertion을 요청할 수 있도록 합니다. FIDO API는 Relying Party에 대해 AppID라는 대체 식별자를 사용하며, 이 API들을 통해 생성된 자격 증명은 해당 식별자에 스코프 됩니다. 이 확장 기능이 없으면, 스코프RP ID로 변경하려면 자격 증명을 다시 등록해야 합니다.

appid 확장 입력을 설정하는 것 외에도, 이 확장 기능을 사용하려면 Relying Party가 추가 처리를 수행해야 하며, 이를 통해 사용자가 등록된 U2F 자격 증명을 사용하여 인증할 수 있습니다:

  1. 원하는 U2F 자격 증명들을 allowCredentials 옵션의 get() 메서드에 나열합니다:

    • type 멤버를 public-key로 설정합니다.

    • id 멤버를 원하는 자격 증명의 해당 U2F 키 핸들로 설정합니다. U2F 키 핸들은 일반적으로 base64url 인코딩을 사용하지만, id에서 사용될 때는 반드시 바이너리 형태로 디코딩 되어야 합니다.

    allowCredentials 에는 WebAuthn credential ID와 U2F 키 핸들을 혼합해서 포함할 수 있습니다; 이 확장 기능을 통해 appid 를 지정해도 사용자는 RP IDrpId로 스코프 된 WebAuthn 등록 자격 증명을 사용할 수 있습니다.

  2. assertion 검증 시, rpIdHashRP ID 대신 AppID의 해시일 수 있습니다.

이 확장 기능은 FIDO 호환 자격 증명 생성을 허용하지 않습니다. 그러므로 WebAuthn으로 생성된 자격 증명은 FIDO JavaScript API와 역호환되지 않습니다.

Note: appid 값은 Relying Party가 예전에 레거시 FIDO API에서 사용했던 AppID로 설정해야 합니다. 이는 Relying Party의 WebAuthn RP ID를 AppID 포맷으로 변환한 결과와 같지 않을 수 있습니다. 예를 들어 예전에 사용한 AppID가 "https://accounts.example.com"일 수 있지만, 현재 RP ID는 "example.com"일 수 있습니다.

확장 식별자

appid

작동 적용 범위

Authentication

클라이언트 확장 입력

FIDO AppID를 지정하는 단일 DOMString

partial dictionary AuthenticationExtensionsClientInputs {
  DOMString appid;
};
partial dictionary AuthenticationExtensionsClientInputsJSON {
  DOMString appid;
};
클라이언트 확장 처리
  1. facetId에 호출자의 origin을 넘겨 FIDO 앱 호출자의 FacetID 결정 알고리즘을 실행합니다.

  2. appId에 확장 입력값을 할당합니다.

  3. facetIdappId를 FIDO caller의 FacetID가 AppID에 권한이 있는지 확인하는 알고리즘에 전달합니다. 알고리즘이 appId를 거부하면, "SecurityError" DOMException을 반환합니다.

  4. allowCredentialDescriptorList 빌드 시, U2F 인증기가 자격 증명이 적용 불가능함을 나타낼 경우(예: SW_WRONG_DATA 반환), 클라이언트는 U2F 앱 파라미터를 appId의 SHA-256 해시로 설정하여 재시도해야 합니다. 이로 인해 적용 가능한 자격 증명이 있다면, 클라이언트는 해당 자격 증명을 allowCredentialDescriptorList에 포함해야 합니다. appId 값이 authenticatorGetAssertionrpId 파라미터를 대체합니다.

  5. output 값을 불리언 false로 설정합니다.

  6. assertionCreationData 생성 시, U2F 인증기가 RP ID 대신 appId의 SHA-256 해시를 사용해 assertion을 생성하면 outputtrue로 설정합니다.

Note: 실제 구현에서는 caller의 FacetID가 AppID에 권한이 있는지 확인하는 알고리즘의 4단계 이후를 구현하지 않는 경우가 많습니다. 대신 3단계에서는 호스트 비교가 Relax되어 동일 사이트의 호스트도 허용됩니다.

클라이언트 확장 출력

output 값을 반환합니다. true이면 AppID가 사용되었으므로, assertion 검증Relying PartyrpIdHashRP ID가 아니라 AppID의 해시임을 예상해야 합니다.

partial dictionary AuthenticationExtensionsClientOutputs {
  boolean appid;
};
partial dictionary AuthenticationExtensionsClientOutputsJSON {
  boolean appid;
};
인증기 확장 입력

없음.

인증기 확장 처리

없음.

인증기 확장 출력

없음.

10.1.2. FIDO AppID 제외 확장(appidExclude)

이 등록 확장 기능은 WebAuthn Relying Parties가 레거시 FIDO U2F JavaScript API [FIDOU2FJavaScriptAPI]로 생성된 특정 자격 증명을 포함하는 인증기를 제외할 수 있도록 합니다.

FIDO U2F JavaScript API에서 전환하는 동안, Relying Party는 이미 레거시 자격 증명을 등록한 사용자 집단을 가질 수 있습니다. appid 확장 기능은 로그인 플로우를 원활하게 전환할 수 있도록 하지만, 등록 플로우를 전환할 때 excludeCredentials 필드는 그 내용이 WebAuthn 자격 증명으로 간주되기 때문에 레거시 자격 증명을 가진 인증기를 효과적으로 제외하지 못합니다. 이 확장 기능은 클라이언트 플랫폼excludeCredentials의 내용을 WebAuthn과 레거시 FIDO 자격 증명 모두로 간주하도록 지시합니다. U2F 키 핸들은 일반적으로 base64url 인코딩을 사용하지만 excludeCredentials에서 사용할 때는 바이너리 형태로 디코딩되어야 합니다.

확장 식별자

appidExclude

작동 적용 범위

Registration

클라이언트 확장 입력

FIDO AppID를 지정하는 단일 DOMString

partial dictionary AuthenticationExtensionsClientInputs {
  DOMString appidExclude;
};
partial dictionary AuthenticationExtensionsClientInputsJSON {
  DOMString appidExclude;
};
클라이언트 확장 처리

새 자격 증명 생성 시:

  1. RP ID 설정 직후 다음을 수행합니다:

    1. facetId에 호출자의 origin을 넘겨 FIDO 앱 호출자의 FacetID 결정 알고리즘을 실행합니다.

    2. appId를 확장 입력 appidExclude의 값으로 할당합니다.

    3. facetIdappId를 FIDO caller의 FacetID가 AppID에 권한이 있는지 확인하는 알고리즘에 전달합니다. 알고리즘이 appId를 거부하면, "SecurityError" DOMException을 반환하며, 새 자격 증명 생성 알고리즘과 이 절차를 종료합니다.

      Note: 실제 구현에서는 caller의 FacetID가 AppID에 권한이 있는지 확인하는 알고리즘의 4단계 이후를 구현하지 않는 경우가 많습니다. 대신 3단계에서는 호스트 비교가 Relax되어 동일 사이트의 호스트도 허용됩니다.

    4. 그 외에는 정상 처리 과정을 계속 진행합니다.

  2. authenticatorMakeCredential 호출 직전에 다음을 수행합니다:

    1. authenticator가 U2F 프로토콜 [FIDO-U2F-Message-Formats]을 지원하는 경우 credential descriptor CexcludeCredentialDescriptorList에서 반복:

      1. Cauthenticator의 U2F로 생성되었는지 U2F_AUTHENTICATE 메시지를 authenticator에 보내 다음과 같이 "다섯 부분"을 설정하여 확인합니다:

        control byte

        0x07 ("check-only")

        challenge parameter

        32 랜덤 바이트

        application parameter

        appId의 SHA-256 해시

        key handle length

        C.id (byte 단위 길이)

        key handle

        C.id 값(즉, credential id)

      2. authenticatormessage:error:test-of-user-presence-required (성공)을 응답하면: 해당 authenticator의 기본 처리를 중단하고 플랫폼별 방식(예: UI로 표시, 또는 사용자 동의 요청 등)으로 해당 인증기가 적용 불가능함을 나타냅니다. 사용자 동의는 위와 동일하게 control byte0x03 ("enforce-user-presence-and-sign")으로 설정해 U2F_AUTHENTICATE 메시지를 한 번 더 보내고, 응답은 무시하여 달성할 수 있습니다.

    2. 정상 처리 과정을 계속 진행합니다.

클라이언트 확장 출력

확장이 동작되었음을 Relying Party에 알리기 위해 true 값을 반환합니다.

partial dictionary AuthenticationExtensionsClientOutputs {
  boolean appidExclude;
};
partial dictionary AuthenticationExtensionsClientOutputsJSON {
  boolean appidExclude;
};
인증기 확장 입력

없음.

인증기 확장 처리

없음.

인증기 확장 출력

없음.

10.1.3. 자격 증명 속성 확장(credProps)

클라이언트 등록 확장클라이언트가 알고 있는 특정 자격 증명 속성WebAuthn Relying Party공개키 자격 증명 소스등록 절차를 통해 생성될 때 보고할 수 있도록 지원합니다.

현재 한 가지 자격 증명 속성이 정의되어 있습니다: 클라이언트 측 검색 가능한 자격 증명 속성입니다.

확장 식별자

credProps

작동 적용 범위

Registration

클라이언트 확장 입력

Relying Party가 이 확장 기능을 요청했음을 나타내기 위해 Boolean 값 true를 사용합니다.

partial dictionary AuthenticationExtensionsClientInputs {
    boolean credProps;
};
partial dictionary AuthenticationExtensionsClientInputsJSON {
    boolean credProps;
};
클라이언트 확장 처리

authenticatorMakeCredential 작업 호출에 사용된 requireResidentKey 파라미터 값을 rk에 할당합니다.

클라이언트 확장 출력

Set clientExtensionResults["credProps"]["rk"]authenticatorMakeCredential 작업 호출에 사용된 requireResidentKey 파라미터 값으로 설정합니다.

dictionary CredentialPropertiesOutput {
    boolean rk;
};

partial dictionary AuthenticationExtensionsClientOutputs {
    CredentialPropertiesOutput credProps;
};
partial dictionary AuthenticationExtensionsClientOutputsJSON {
    CredentialPropertiesOutput credProps;
};
rk, of type boolean

이 OPTIONAL 속성은 추상적으로 client-side discoverable credential property 또는 resident key credential property로 알려져 있습니다. 이 속성은 PublicKeyCredentialregistration ceremony 결과로 반환된 경우, client-side discoverable credential인지 여부를 나타내는 Boolean 값입니다. rk 값이 true이면 자격 증명은 discoverable credential입니다. rk 값이 false이면 자격 증명은 server-side credential입니다. rk 가 없는 경우, 해당 자격 증명이 discoverable credential인지 server-side credential인지 알 수 없습니다.

Note: 일부 인증기클라이언트 플랫폼이 요청하지 않아도 검색 가능한 자격 증명을 생성합니다. 이런 경우 클라이언트 플랫폼은 이 rk 속성을 생략해야 할 수도 있습니다(확실하지 않으므로 false로 셋팅하지 않기 위해). Relying PartycredProps 확장 기능이 지원되는 경우 클라이언트 플랫폼이 최대한 rk 값을 채우려 할 것으로 가정해야 합니다. 따라서 rk 속성이 없는 경우 생성된 자격 증명은 대개 비검색 자격 증명임을 의미합니다.

인증기 확장 입력

없음.

인증기 확장 처리

없음.

인증기 확장 출력

없음.

10.1.4. 의사 난수 함수 확장 (prf)

클라이언트 등록 확장인증 확장신뢰 당사자자격 증명과 연관된 의사 난수 함수(PRF)의 출력을 평가할 수 있도록 합니다. 이 확장에서 제공하는 PRF는 임의 길이의 BufferSource를 32바이트 BufferSource 로 매핑합니다.

예를 들어, PRF의 출력값은 대칭 키로 사용되어 사용자 데이터를 암호화할 수 있습니다. 이 암호화된 데이터는 연결된 자격 증명을 통해 주장(assertion)을 얻는 능력 없이는 접근할 수 없습니다. 아래의 조항을 사용해 단일 assertion 작업에서 두 입력에 대해 PRF를 평가하면, 새로운 무작위 입력을 선택해 새 출력으로 다시 암호화함으로써 assertion 시 암호화 키를 주기적으로 변경할 수 있습니다. 입력값이 예측할 수 없다면, 사용자 검증을 통과할 수 있고 인증기(authenticator)에 일시적 접근 권한을 가진 공격자라 해도 올바른 PRF 입력값을 모르면 암호 키를 알 수 없습니다.

이 확장은 [FIDO-CTAP] hmac-secret 확장을 기반으로 하지만, 다른 방법으로도 구현할 수 있습니다. hmac-secret는 입력값과 출력값을 오직 사용자 에이전트만 수행할 수 있는 방식으로 암호화해야 하며, WebAuthn 사용처와 기본 플랫폼 사용처를 분리하기 위하여 별도의 클라이언트 확장으로 정의됩니다. 이 분리는 제공된 PRF 입력값에 대해 컨텍스트 문자열로 해싱하여 임의의 입력을 사용한 PRF 평가를 방지함으로써 달성됩니다.

hmac-secret 확장은 자격증명마다 두 개의 PRF를 제공합니다: 사용자 검증이 수행될 때 쓰이는 것과, 그렇지 않은 모든 요청에 사용되는 것. 이 확장은 자격증명 당 단일 PRF만 노출하며, hmac-secret 위에서 구현할 때에는 사용자 검증이 수행될 때 사용하는 PRF여야만 합니다. 이는 필요하다면 UserVerificationRequirement 를 오버라이드합니다.

이 확장은 CTAP2 hmac-secret를 사용하지 않는 인증기에 대해서도 구현될 수 있습니다. 클라이언트와 인증기 간의 이 인터페이스 및 PRF의 구성은 추상적으로만 정의됩니다.

참고: hmac-secret 위에서 구현할 경우, 그렇지 않으면 존재하지 않는 인증기 확장 출력이 생깁니다. 이 출력들은 암호화되어 신뢰 당사자가 사용할 수 없지만, 인증기 데이터가 서명되어 있기 때문에 클라이언트가 삭제할 수도 없습니다.

확장 식별자

prf

작동 적용 범위

등록인증

클라이언트 확장 입력값
dictionary AuthenticationExtensionsPRFValues {
    required BufferSource first;
    BufferSource second;
};
dictionary AuthenticationExtensionsPRFValuesJSON {
    required Base64URLString first;
    Base64URLString second;
};

dictionary AuthenticationExtensionsPRFInputs {
    AuthenticationExtensionsPRFValues eval;
    record<DOMString, AuthenticationExtensionsPRFValues> evalByCredential;
};
dictionary AuthenticationExtensionsPRFInputsJSON {
    AuthenticationExtensionsPRFValuesJSON eval;
    record<DOMString, AuthenticationExtensionsPRFValuesJSON> evalByCredential;
};

partial dictionary AuthenticationExtensionsClientInputs {
    AuthenticationExtensionsPRFInputs prf;
};
partial dictionary AuthenticationExtensionsClientInputsJSON {
    AuthenticationExtensionsPRFInputsJSON prf;
};
eval, 타입: AuthenticationExtensionsPRFValues

평가할 PRF의 한 개 또는 두 개의 입력값. 모든 인증기가 자격증명 생성 시 PRF 평가를 지원하는 것은 아니기에 출력값이 제공될 수도, 안 될 수도 있습니다. 만약 제공되지 않는다면 출력을 얻으려면 assertion이 필요합니다.

evalByCredential, 타입: record<DOMString, AuthenticationExtensionsPRFValues>

base64url 인코딩자격증명 ID를 PRF 입력값에 매핑하여 자격증명별로 평가하는 레코드. assertionallowCredentials 가 비어있지 않을 때만 적용됩니다.

클라이언트 확장 처리 (등록)
계속 번역
  1. evalByCredential 이 존재하면, 이름이 "NotSupportedError"인 DOMException 을 반환합니다.

  2. eval 이 존재하면:

    • salt1SHA-256(UTF8Encode("WebAuthn PRF") || 0x00 || eval.first) 값으로 정합니다.

    • eval.second 가 존재하면, salt2SHA-256(UTF8Encode("WebAuthn PRF") || 0x00 || eval.second) 값으로 정합니다.

  3. 인증기가 CTAP2 hmac-secret 확장 [FIDO-CTAP]을 지원하면:

    1. 인증기 확장 입력에서 hmac-secrettrue로 설정합니다.

    2. salt1이 정의되어 있고 [FIDO-CTAP]에 대한 미래 확장이 생성 시점 PRF 평가를 허용하면, salt1과, 만약 정의되어 있으면 salt2 값을 사용해 hmac-secret 입력을 적절히 설정합니다.

    3. 인증기 확장 출력에서 enabledhmac-secret의 값으로 설정합니다. 존재하지 않으면 enabledfalse로 합니다.

    4. 복호화된 PRF 결과(가 있을 경우)로 results 를 설정합니다.

  4. 인증기가 CTAP2 hmac-secret 확장을 지원하지 않지만, 아래 추상 인증기 처리를 지원하는 다른 구현을 지원하는 경우:

    1. enabledtrue로 설정합니다.

    2. salt1이 정의되어 있으면, 명시되지 않은 방법으로 인증기에 PRF 입력값으로 salt1과 (정의되어 있으면) salt2를 그 순서대로 전달합니다.

    3. 명시되지 않은 방법으로 인증기에서 PRF 출력을 수신합니다. results 에 평가 결과(가 있을 경우)를 설정합니다.

클라이언트 확장 처리 (인증)
  1. evalByCredential 이 비어있지 않으나 allowCredentials 가 비어 있으면, 이름이 "NotSupportedError"인 DOMException 을 반환합니다.

  2. evalByCredential 내의 어떤 가 빈 문자열이거나, 올바른 base64url 인코딩이 아니거나, 자격증명 ID 중 어떤 요소의 id 와 동일하지 않다면, 이름이 "SyntaxError"인 DOMException 을 반환합니다.

  3. prf 확장 출력을 빈 딕셔너리로 초기화합니다.

  4. ev를 null로 초기화하고, 적용될 수 있는 PRF 입력값을 찾습니다:

    1. evalByCredential 이 존재하고 entrykey가 반환될 자격증명 IDbase64url 인코딩이면 그 valueev를 설정합니다.

    2. ev가 null이고 eval 이 존재하면 ev를 해당 값으로 설정합니다.

  5. ev가 null이 아니면:

    1. salt1SHA-256(UTF8Encode("WebAuthn PRF") || 0x00 || ev.first) 값으로 정합니다.

    2. ev.second 가 존재하면 salt2SHA-256(UTF8Encode("WebAuthn PRF") || 0x00 || ev.second) 값으로 정합니다.

    3. 인증기가 CTAP2 hmac-secret 확장 [FIDO-CTAP]을 지원하면:

      1. salt1과, 존재하면 salt2를 파라미터로 hmac-secret 확장을 인증기로 보냅니다.

      2. 확장 결과를 복호화하여 results 에 PRF 결과(값이 있으면)를 설정합니다.

    4. 인증기가 CTAP2 hmac-secret 확장을 지원하지 않되, 추상 인증기 처리를 지원하면:

      1. 명시되지 않은 방법으로 salt1과, 정의되어 있으면 salt2를 인증기에 PRF 입력값으로 전달합니다.

      2. 명시되지 않은 방법으로 인증기에서 PRF 출력을 AuthenticationExtensionsPRFValuesresults로 수신합니다. resultsresults로 설정합니다.

인증기 확장 입력/출력

이 확장은 인증기의 구현에 추상적인 것으로, [FIDO-CTAP] hmac-secret 확장이나, 클라이언트-인증기 간 통신을 위한 명시되지 않은 인터페이스를 사용합니다. 그러므로 입력과 출력에 대한 CBOR 인터페이스는 명시하지 않습니다.

인증기 확장 처리

이 확장을 지원하는 인증기[FIDO-CTAP] hmac-secret 확장에 정의된 인증기 처리를 구현합니다.

이 확장을 지원하지 않는 인증기는 다음의 추상적 절차를 구현할 수 있습니다:

  1. 현재 자격증명과 연관된 의사 난수 함수 PRF를 가져오거나 초기화합니다:

    PRF는 정확히 32바이트 길이의 출력을 가지며, 2256개 이상의 함수 집합에서 균등 임의로 선택됩니다.
    PRF의 선택은 사용자 검증 상태와 독립적이어야 합니다.
    PRF는 이 확장 구현 외에 다른 용도로 사용하지 않아야 합니다.
    PRF를 해당 자격증명과 자격증명의 수명 동안 연관시킵니다.

  2. 명시되지 않은 방법으로 클라이언트로부터 salt1과, 선택적으로 salt2를 그 순서로 수신합니다.
    아무 입력도 없으면 salt1salt2는 정의되지 않습니다.

  3. salt1이 정의되어 있으면:

    1. resultsAuthenticationExtensionsPRFValues 구조로 하여, 아래와 같이 PRF 평가 결과를 포함시킵니다:

      • results.firstPRF(salt1)로 설정합니다.

      • salt2가 정의되어 있으면, results.secondPRF(salt2)로 설정합니다.

    2. 명시되지 않은 방법으로 클라이언트results를 PRF 출력값으로 전달합니다.

클라이언트 확장 출력
dictionary AuthenticationExtensionsPRFOutputs {
boolean enabled;
AuthenticationExtensionsPRFValues results;
};
dictionary AuthenticationExtensionsPRFOutputsJSON {
boolean enabled;
AuthenticationExtensionsPRFValuesJSON results;
};

partial dictionary AuthenticationExtensionsClientOutputs {
AuthenticationExtensionsPRFOutputs prf;
};
partial dictionary AuthenticationExtensionsClientOutputsJSON {
AuthenticationExtensionsPRFOutputsJSON prf;
};
enabled, 타입: boolean

true이면 PRF를 생성된 자격증명에 사용할 수 있음을 의미합니다. 이는 등록 중에만 보고되며 인증에는 포함되지 않습니다.

results, 타입: AuthenticationExtensionsPRFValues

eval 또는 evalByCredential에 입력된 값에 대한 PRF 평가 결과입니다. 등록 중에는 출력이 제공되지 않을 수 있습니다. 자세한 내용은 eval의 설명을 참고하세요.

일부 사용 사례, 예를 들어 PRF 출력값이 오직 클라이언트 측에서만 사용할 암호화 키를 파생하는 데 사용되는 경우, results 출력을 생략해야 할 수도 있습니다. PublicKeyCredential 이 원격 서버로 전송되는 경우, 예를 들어 § 7 WebAuthn 신뢰 당사자 작업을 수행할 때 그러할 수 있습니다. 특히 RegistrationResponseJSONAuthenticationResponseJSONPublicKeyCredential.toJSON() 으로 반환할 때 본 results 출력을 포함할 수 있으므로 주의해야 합니다.

10.1.5. 대용량 blob 저장 확장(largeBlob)

클라이언트 등록 확장인증 확장Relying Party가 자격 증명과 연관된 불투명 데이터를 저장할 수 있도록 허용합니다. 인증기는 소량의 데이터만 저장할 수 있고, 대부분의 Relying Party는 사용자에 대해 임의의 양의 상태를 저장할 수 있는 온라인 서비스이기 때문에, 이 기능은 특정 경우에만 유용합니다. 예를 들어 Relying Party가 중앙 집중식 인증 서비스 운용 대신 인증서를 발급하고 싶을 수 있습니다.

Note: Relying Party는 불투명 데이터가 저장 용량이 제한된 디바이스에 쓸 때 압축된다고 가정할 수 있으므로 직접 압축할 필요가 없습니다.

인증서 시스템은 자격 증명의 공개키에 서명을 해야 하고, 공개키는 생성 이후에만 얻을 수 있기 때문에, 이 확장은 등록 맥락에서 blob을 쓰는 기능을 추가하지 않습니다. 그러나 Relying Party는 추후 인증 확장을 사용하려 한다면 자격 증명 생성 시 등록 확장을 사용해야 합니다.

인증서는 일반적인 인증기의 저장 역량에 비해 상당히 큰 편이므로, 사용자 에이전트는 사용자가 이 제한된 리소스 할당을 잘 안내받고 남용을 방지할 수 있도록 적합한 표시 및 확인 방식을 고려해야 합니다.

참고: 상호 운용성을 위해, 사용자 에이전트가 [FIDO-CTAP]를 이용하여 인증기에 대용량 blob을 저장하는 경우, 해당 명세에 명시된 대용량, 자격 증명별 blob 저장 절차를 따라야 합니다.

Note: 로밍 인증기[FIDO-CTAP]을 교차 플랫폼 전송 프로토콜로 사용할 경우, 이 Large Blob 확장은 검색 가능한 자격 증명에만 지원되며, 다음 조건을 만족하지 않으면 에러를 반환할 수 있습니다: authenticatorSelection.residentKeypreferred 또는 required로 설정되어야 합니다. 단, FIDO-CTAP를 사용하지 않는 인증기는 이 확장을 검색 가능한 자격 증명에 한정하지 않을 수 있습니다.

확장 식별자

largeBlob

작동 적용 범위

등록인증

클라이언트 확장 입력
partial dictionary AuthenticationExtensionsClientInputs {
    AuthenticationExtensionsLargeBlobInputs largeBlob;
};
partial dictionary AuthenticationExtensionsClientInputsJSON {
    AuthenticationExtensionsLargeBlobInputsJSON largeBlob;
};

enum LargeBlobSupport {
  "required",
  "preferred",
};

dictionary AuthenticationExtensionsLargeBlobInputs {
    DOMString support;
    boolean read;
    BufferSource write;
};
dictionary AuthenticationExtensionsLargeBlobInputsJSON {
    DOMString support;
    boolean read;
    Base64URLString write;
};
support, of type DOMString

LargeBlobSupport 값 중 하나를 가지는 DOMString. (§ 2.1.1 Enumerations as DOMString types 참고.) 등록 시에만 유효합니다.

read, of type boolean

이 불리언은 Relying Party가 기존 자격 증명에 연결된, 이전에 쓴 blob을 가져오고 싶음을 나타냅니다. 인증 시에만 유효합니다.

write, of type BufferSource

불투명 바이트 문자열로, Relying Party가 기존 자격 증명에 저장하길 원하는 값입니다. 인증 시에만 유효합니다.

클라이언트 확장 처리 (등록)
  1. read 또는 write 가 포함되어 있다면:

    1. DOMException 중 이름이 “NotSupportedError”인 예외를 반환합니다.

  2. supportrequired인 경우:

    1. supported 값을 true로 설정합니다.

      Note: 대형 blob 저장이 가능한 인증기가 추후 제공되는 상황을 대비합니다. 이 처리는 [[Create]](origin, options, sameOriginWithAncestors)의 step 12에서 일어납니다. AuthenticationExtensionsLargeBlobOutputs 값은 적합한 인증기가 없으면 무시됩니다.

    2. 후보 인증기가 나타나면 (step 22), options 평가 전에 continue (즉, 후보 인증기 무시) 대형 blob을 지원하지 않는 경우

  3. 그 외 (support 항목이 없거나 preferred인 경우):

    1. 선택된 인증기가 대형 blob을 지원하면 supportedtrue로, 아니면 false로 설정합니다.

클라이언트 확장 처리 (인증)
  1. support 항목이 있으면:

    1. DOMException 중 이름이 “NotSupportedError”인 예외를 반환합니다.

  2. readwrite 가 모두 있으면:

    1. DOMException 중 이름이 “NotSupportedError”인 예외를 반환합니다.

  3. readtrue이면:

    1. 클라이언트 확장 출력largeBlob을 초기화합니다.

    2. 인증기가 성공을 응답하면 ([[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)), 대응 자격 증명에 연결된 largeBlob 데이터를 읽습니다.

    3. 성공 시 blob 값을 결과로 설정합니다.

      Note: 읽기에 실패하면 largeBlobAuthenticationExtensionsClientOutputs 에는 나타나지만, blob 멤버가 없음.

  4. write 가 있으면:

    1. allowCredentials 가 정확히 1개의 요소만 포함하지 않으면:

      1. DOMException 중 이름이 “NotSupportedError”인 예외를 반환합니다.

    2. assertion 작업 성공 시, 해당 자격 증명에 write 내용을 인증기에 저장 시도.

    3. 성공 시 written true, 실패 시 false로 설정.

클라이언트 확장 출력
partial dictionary AuthenticationExtensionsClientOutputs {
    AuthenticationExtensionsLargeBlobOutputs largeBlob;
};
partial dictionary AuthenticationExtensionsClientOutputsJSON {
    AuthenticationExtensionsLargeBlobOutputsJSON largeBlob;
};

dictionary AuthenticationExtensionsLargeBlobOutputs {
    boolean supported;
    ArrayBuffer blob;
    boolean written;
};
dictionary AuthenticationExtensionsLargeBlobOutputsJSON {
    boolean supported;
    Base64URLString blob;
    boolean written;
};
supported, of type boolean

생성된 자격 증명이 대형 blob 저장을 지원하는 경우에만 true. 등록 출력에만 나타납니다.

blob, of type ArrayBuffer

rawId로 식별되는 크리덴셜에 연동된 불투명 바이트 문자열입니다. readtrue일 때만 유효합니다.

written, of type boolean

write 내용이 지정된 자격 증명에 연결된 인증기에 성공적으로 저장되었음을 나타내는 불리언.

인증기 확장 처리

이 확장은 사용자 에이전트가 large blob을 인증기에 저장하거나 인증기로부터 조회하도록 지정합니다. 따라서 Relying Party에 대해 직접적인 인증기 상호작용을 명세하지 않습니다.

10.2. 인증기 확장

이 절에서는 클라이언트 확장이면서 인증기 확장인 확장들을 정의합니다.

이 절은 현재 비어 있습니다.

11. 사용자 에이전트 자동화

사용자 에이전트 자동화 및 웹 애플리케이션 테스트 목적을 위해, 본 문서는 [WebDriver] 확장 명령 여러 가지를 정의합니다.

11.1. WebAuthn WebDriver 확장 기능(Capability)

아래에 정의된 확장 명령의 사용 가능 여부를 광고하기 위해, 새로운 확장 기능(Capability)이 정의됩니다.

기능(Capability) Key 값 타입(Value Type) 설명
가상 인증기 지원 "webauthn:virtualAuthenticators" boolean 엔드포인트 노드가 모든 가상 인증기 명령을 지원하는지 나타냄

기능을 검증할 때, 다음은 "webauthn:virtualAuthenticators"value와 함께 검증하는 확장별 단계입니다:

  1. valueboolean이 아니면, WebDriver 오류WebDriver error code invalid argument와 함께 반환합니다.

  2. 그 외에는 deserializedvalue로 설정합니다.

기능을 매칭할 때, "webauthn:virtualAuthenticators"value의 확장별 매칭 단계는 다음과 같습니다:

  1. valuetrue이고 엔드포인트 노드가상 인증기 명령들을 하나도 지원하지 않으면, 매칭은 실패합니다.

  2. 그 외에는 매칭이 성공합니다.

11.1.1. 인증기 확장 기능(Capabilities)

또한, 본 명세에서 정의한 모든 인증기 확장(즉, 인증기 확장 처리가 정의된 것)에 대해 확장 기능(Capability)이 개별로 정의됩니다:

기능 Key 값 타입 설명
의사난수함수(PRF) 확장 지원 "webauthn:extension:prf" boolean 엔드포인트 노드 WebAuthn WebDriver 구현이 prf 확장을 지원하는지 나타냄
대용량 blob 저장 확장 지원 "webauthn:extension:largeBlob" boolean 엔드포인트 노드 WebAuthn WebDriver 구현이 largeBlob 확장을 지원하는지 나타냄
credBlob 확장 지원 "webauthn:extension:credBlob" boolean 엔드포인트 노드 WebAuthn WebDriver 구현이 [FIDO-CTAP]에 정의된 credBlob 확장을 지원하는지 나타냄

기능을 검증할 때, 인증기 확장 기능 keyvalue를 검증하는 확장별 단계는 다음과 같습니다:

  1. valueboolean이 아니면, WebDriver 오류WebDriver error code invalid argument와 함께 반환합니다.

  2. 그 외에는 deserializedvalue로 설정합니다.

기능 매칭 시, 인증기 확장 기능 keyvalue의 확장별 매칭 단계는 다음과 같습니다:

  1. valuetrue이고 엔드포인트 노드 WebAuthn WebDriver 구현이 key로 식별되는 인증기 확장을 지원하지 않으면, 매칭은 실패합니다.

  2. 그 외에는 매칭이 성공합니다.

정의된 인증기 확장을 구현하는 User-Agent는 대응하는 인증기 확장 기능도 함께 구현해야 합니다.

11.2. 가상 인증기

이들 WebDriver 확장 명령가상 인증기를 생성하고 조작합니다: 인증기 모델의 소프트웨어 구현입니다. 가상 인증기가상 인증기 데이터베이스에 저장됩니다. 저장된 각 가상 인증기는 다음 속성들을 가집니다:

authenticatorId

최대 48자의 [RFC3986] 부록 A에서 정의된 unreserved 조합으로 구성된 널이 아닌 문자열로, 가상 인증기를 고유하게 식별합니다.

protocol

가상 인증기가 사용하는 프로토콜: "ctap1/u2f", "ctap2" 또는 "ctap2_1" [FIDO-CTAP] 중 하나입니다.

transport

시뮬레이트되는 AuthenticatorTransport 값입니다. transportinternal로 설정된 경우, 인증기는 플랫폼 연결을 시뮬레이션합니다. 그렇지 않으면 크로스-플랫폼 연결을 시뮬레이션합니다.

hasResidentKey

true로 설정된 경우, 인증기는 클라이언트 측 검색 가능한 자격 증명을 지원합니다.

hasUserVerification

true로 설정된 경우, 인증기는 사용자 확인을 지원합니다.

isUserConsenting

모든 사용자 동의 권한 부여 제스처의 결과와, 확장적으로, 사용자 존재 테스트의 결과를 결정합니다. 가상 인증기에서 수행됩니다. true로 설정하면 사용자 동의가 항상 허용됩니다. false로 설정하면 동의가 거부됩니다.

isUserVerified

사용자 확인의 결과를 가상 인증기에서 결정합니다. true로 설정하면 사용자 확인이 항상 성공합니다. false로 설정하면 실패합니다.

Note: 이 속성은 hasUserVerificationfalse로 설정된 경우 아무런 효과가 없습니다.

extensions

해당 가상 인증기가 지원하는 확장 식별자의 문자열 배열입니다.

가상 인증기extensions 배열에 포함된 모든 인증기 확장을 지원해야 합니다. 배열에 포함되지 않은 인증기 확장은 지원해서는 안 됩니다.

defaultBackupEligibility

새로 생성되는 모든 공개키 자격 증명 소스에서 백업 적합성 자격 증명 속성의 기본 상태를 결정합니다. 이 값은 반드시 해당 가상 인증기로 authenticatorMakeCredential 작업 수행 시 BE 인증기 데이터 플래그에 반영되어야 합니다.

defaultBackupState

새로 생성되는 모든 공개키 자격 증명 소스에서 백업 상태 자격 증명 속성의 기본 상태를 결정합니다. 이 값은 반드시 해당 가상 인증기로 authenticatorMakeCredential 작업 수행 시 BS 인증기 데이터 플래그에 반영되어야 합니다.

11.3. 가상 인증기 추가

가상 인증기 추가 WebDriver 확장 명령는 소프트웨어 가상 인증기를 생성합니다. 다음과 같이 정의됩니다.

HTTP Method URI 템플릿
POST /session/{session id}/webauthn/authenticator

인증기 구성은 JSON 오브젝트로, 원격 엔드 단계parameters로 전달됩니다. 다음과 같은 keyvalue 쌍을 포함합니다.

Key 값 타입 허용 값 기본값
protocol string "ctap1/u2f", "ctap2", "ctap2_1" None
transport string AuthenticatorTransportNone
hasResidentKey boolean true, false false
hasUserVerification boolean true, false false
isUserConsenting boolean true, false true
isUserVerified boolean true, false false
extensions string array 확장 식별자 배열 빈 배열
defaultBackupEligibility boolean true, false false
defaultBackupState boolean true, false false

원격 엔드 단계는 다음과 같습니다.

  1. parameters가 JSON 오브젝트가 아니면, WebDriver 오류WebDriver 오류 코드 invalid argument를 반환합니다.

    Note: parameters인증기 구성 오브젝트입니다.

  2. authenticator라는 새 가상 인증기를 생성합니다.

  3. parameters의 각 열거형 자체 속성에 대해:

    1. key를 속성 이름으로 합니다.

    2. value속성 얻기parameters에서 key를 가져온 결과로 합니다.

    3. 인증기 구성key에 해당하는 key가 없으면 WebDriver 오류WebDriver 오류 코드 invalid argument를 반환합니다.

    4. value가 해당 key허용 값 중에 없으면, WebDriver 오류WebDriver 오류 코드 invalid argument를 반환합니다.

    5. 속성 설정 keyvalueauthenticator에 설정합니다.

  4. 인증기 구성 내에 기본값이 정의된 각 속성에 대해:

    1. 만약 keyauthenticator의 정의된 속성이 아니라면, 속성 설정 keydefaultauthenticator에 설정합니다.

  5. 인증기 구성의 각 속성에 대해:

    1. keyauthenticator에 정의된 속성이 아니라면, WebDriver 오류WebDriver 오류 코드 invalid argument를 반환합니다.

  6. authenticator.extensions의 각 extension에 대해:

    1. extension확장 식별자가 아니거나, 엔드포인트 노드 WebAuthn WebDriver 구현체에서 지원하지 않으면 WebDriver 오류WebDriver 오류 코드 unsupported operation을 반환합니다.

  7. 유효한 고유 authenticatorId를 생성합니다.

  8. 속성 설정 authenticatorIdauthenticatorIdauthenticator에 설정합니다.

  9. authenticator가상 인증기 데이터베이스에 저장합니다.

  10. 성공으로 authenticatorId 데이터를 반환합니다.

11.4. 가상 인증기 제거

가상 인증기 제거 WebDriver 확장 명령는 기존에 생성된 가상 인증기를 제거합니다. 다음과 같이 정의됩니다.

HTTP Method URI 템플릿
DELETE /session/{session id}/webauthn/authenticator/{authenticatorId}

원격 엔드 단계는 다음과 같습니다.

  1. authenticatorId가상 인증기와 일치하지 않으면, 가상 인증기 데이터베이스에서 WebDriver 오류WebDriver 오류 코드 invalid argument를 반환합니다.

  2. Virtual AuthenticatorauthenticatorId로 식별하여 Virtual Authenticator Database에서 제거합니다

  3. 성공을 반환합니다.

11.5. 자격 증명 추가

자격 증명 추가 WebDriver 확장 명령는 기존 가상 인증기공개키 자격 증명 소스를 주입합니다. 다음과 같이 정의됩니다.

HTTP Method URI 템플릿
POST /session/{session id}/webauthn/authenticator/{authenticatorId}/credential

자격 증명 파라미터는 JSON 오브젝트로, 원격 엔드 단계parameters로 전달됩니다. 다음과 같은 keyvalue 쌍을 포함합니다.

Key 설명 값 타입
credentialId Credential IDBase64url 인코딩을 사용해 인코딩됩니다. string
isResidentCredential true클라이언트 측 검색 가능 자격 증명이 생성됩니다. false서버 측 자격 증명 이 생성됩니다. boolean
rpId 자격 증명에 스코프 되는 Relying Party ID. string
privateKey 비대칭 키 패키지로, private key 하나를 포함하고 [RFC5958] 기준, Base64url 인코딩으로 인코딩됩니다. string
userHandle 자격 증명에 연관된 userHandleBase64url 인코딩으로 인코딩. 이 속성은 정의되지 않을 수도 있음. string
signCount 자격 증명에 연관된 서명 카운터의 초기값. number
largeBlob 자격 증명별 대형 blob공개키 자격 증명 소스에 연관시키며, Base64url 인코딩을 사용. 이 속성은 정의되지 않을 수도 있음. string
backupEligibility 공개키 자격 증명 소스의 시뮬레이션된 백업 적합성. 지정되지 않으면 가상 인증기defaultBackupEligibility 속성의 값을 사용. 시뮬레이션된 백업 적합성BE 인증기 데이터 플래그에 반드시 반영되어야 함 (이 공개키 자격 증명 소스authenticatorGetAssertion 작업 시). boolean
backupState 공개키 자격 증명 소스의 시뮬레이션된 백업 상태. 지정되지 않으면 가상 인증기defaultBackupState 속성의 값을 사용. 시뮬레이션된 백업 상태BS 인증기 데이터 플래그에 반드시 반영되어야 함 (이 공개키 자격 증명 소스authenticatorGetAssertion 작업 시). boolean
userName username (자격 증명 연관). 지정되지 않으면 빈 문자열 사용. string
userDisplayName userdisplayName (자격 증명 연관). 지정되지 않으면 빈 문자열 사용. string

원격 엔드 단계:

  1. parameters가 JSON 오브젝트가 아니면, WebDriver 오류WebDriver 오류 코드 invalid argument 반환.

    Note: parameters자격 증명 파라미터 오브젝트입니다.

  2. parameterscredentialId 속성에 대해 Base64url 인코딩을 디코딩한 값을 credentialId로 합니다.

  3. credentialId가 실패하면 WebDriver 오류WebDriver 오류 코드 invalid argument를 반환.

  4. isResidentCredentialparametersisResidentCredential 속성의 값으로 합니다.

  5. isResidentCredential이 지정되어 있지 않으면 WebDriver 오류WebDriver 오류 코드 invalid argument를 반환.

  6. rpIdparametersrpId 속성의 값으로 합니다.

  7. rpId가 올바른 RP ID가 아니면 WebDriver 오류WebDriver 오류 코드 invalid argument를 반환.

  8. privateKeyparametersprivateKey 속성에 Base64url 인코딩을 디코딩한 값으로 합니다.

  9. privateKey가 실패하면 WebDriver 오류WebDriver 오류 코드 invalid argument 반환.

  10. privateKey가 유효하게 인코딩된 P-256 곡선의 단일 ECDSA 개인키가 아니면, [RFC5958] 기준,WebDriver 오류WebDriver 오류 코드 invalid argument 반환.

  11. parametersuserHandle 속성이 정의되어 있으면:

    1. parametersuserHandle에 대해 Base64url 인코딩을 디코딩한 결과를 userHandle로 합니다.

    2. userHandle이 실패하면 WebDriver 오류WebDriver 오류 코드 invalid argument 반환.

  12. 그 외:

    1. isResidentCredentialtrue이면, WebDriver 오류WebDriver 오류 코드 invalid argument 반환.

    2. userHandlenull로 설정합니다.

  13. authenticatorId가상 인증기와 일치하지 않으면, 가상 인증기 데이터베이스에서 WebDriver 오류WebDriver 오류 코드 invalid argument 반환.

  14. authenticatorauthenticatorId와 일치하는 가상 인증기로 설정합니다.

  15. isResidentCredentialtrue이고, authenticatorhasResidentKeyfalse이면, WebDriver 오류WebDriver 오류 코드 invalid argument 반환.

  16. authenticatorlargeBlob 확장을 지원하고 parameterslargeBlob 속성이 정의되어 있으면:

    1. largeBlobparameterslargeBlob 속성에 대해 Base64url 인코딩을 디코딩한 결과로 합니다.

    2. largeBlob이 실패하면 WebDriver 오류WebDriver 오류 코드 invalid argument 반환.

  17. 그 외:

    1. largeBlobnull로 설정합니다.

  18. backupEligibilityparametersbackupEligibility 속성 값으로 합니다.

  19. backupEligibility가 정의되지 않으면, authenticatordefaultBackupEligibility 값을 사용합니다.

  20. backupStateparametersbackupState 속성 값으로 설정.

  21. backupState가 정의되지 않으면, authenticatordefaultBackupState 값을 사용합니다.

  22. userNameparametersuserName 속성 값으로 설정.

  23. userName이 정의되지 않으면 빈 문자열로 설정합니다.

  24. userDisplayNameparametersuserDisplayName 속성 값으로 설정.

  25. userDisplayName이 정의되지 않으면 빈 문자열로 설정합니다.

  26. credentialisResidentCredentialtrue클라이언트 측 검색 가능한 공개키 자격 증명 소스로, 아니면 서버 측 공개키 자격 증명 소스로 새로 생성합니다. 항목은 다음과 같습니다.

    type

    public-key

    id

    credentialId

    privateKey

    privateKey

    rpId

    rpId

    userHandle

    userHandle

    otherUI

    userName, userDisplayName로 구성

  27. credential백업 적합성 자격 증명 특성backupEligibility로 설정합니다.

  28. credential백업 상태 자격 증명 특성backupState로 설정합니다.

  29. credential서명 카운터 counter를 연결하고, 시작 값으로 parameterssignCount 또는 0을 사용합니다.

  30. largeBlobnull이 아니면, 자격 증명별 대형 blobcredentiallargeBlob으로 설정

  31. credentialcounterauthenticator의 데이터베이스에 저장합니다.

  32. 성공을 반환합니다.

11.6. 자격 증명 가져오기(Get Credentials)

자격 증명 가져오기 WebDriver 확장 명령가상 인증기에 저장된 모든 공개키 자격 증명 소스마다 하나의 자격 증명 파라미터 객체를 반환합니다. 이는 자격 증명 추가로 저장되었는지, 또는 navigator.credentials.create() 로 저장되었는지와 관계없이 모두 포함합니다. 정의는 다음과 같습니다:

HTTP 메서드 URI 템플릿
GET /session/{session id}/webauthn/authenticator/{authenticatorId}/credentials

원격 엔드 단계는 다음과 같습니다:

  1. authenticatorId가상 인증기 데이터베이스에 저장된 어떠한 가상 인증기와도 일치하지 않으면, WebDriver 오류WebDriver error code invalid argument와 함께 반환합니다.

  2. credentialsArray를 빈 배열로 둡니다.

  3. authenticatorId로 식별되는 인증기가 관리하는 각 공개키 자격 증명 소스 credential마다, 해당하는 자격 증명 파라미터 Object를 생성해 credentialsArray에 추가합니다.

  4. 성공과 데이터 credentialsArray를 반환합니다.

11.7. 자격 증명 제거(Remove Credential)

자격 증명 제거 WebDriver 확장 명령가상 인증기에 저장된 공개키 자격 증명 소스를 하나 제거합니다. 정의는 다음과 같습니다:

HTTP 메서드 URI 템플릿
DELETE /session/{session id}/webauthn/authenticator/{authenticatorId}/credentials/{credentialId}

원격 엔드 단계는 다음과 같습니다:

  1. authenticatorId가상 인증기 데이터베이스에 저장된 어떤 가상 인증기와도 일치하지 않으면, WebDriver 오류WebDriver error code invalid argument 와 함께 반환합니다.

  2. authenticatorauthenticatorId로 식별된 가상 인증기로 둡니다.

  3. credentialIdauthenticator가 관리하는 어떤 공개키 자격 증명 소스에도 일치하지 않으면, WebDriver 오류WebDriver error code invalid argument와 함께 반환합니다.

  4. authenticator가 관리하는 credentialId로 식별된 공개키 자격 증명 소스를 제거합니다.

  5. 성공을 반환합니다.

11.8. 모든 자격 증명 제거(Remove All Credentials)

모든 자격 증명 제거 WebDriver 확장 명령은 특정 가상 인증기에 저장된 모든 공개키 자격 증명 소스를 제거합니다. 정의는 다음과 같습니다:

HTTP 메서드 URI 템플릿
DELETE /session/{session id}/webauthn/authenticator/{authenticatorId}/credentials

원격 엔드 단계는 다음과 같습니다:

  1. authenticatorId가상 인증기 데이터베이스에 저장된 어떤 가상 인증기와도 일치하지 않으면, WebDriver 오류WebDriver error code invalid argument와 함께 반환합니다.

  2. authenticatorId로 식별된 가상 인증기에서 모든 공개키 자격 증명 소스를 제거합니다.

  3. 성공을 반환합니다.

11.9. 사용자 검증 상태 설정(Set User Verified)

사용자 검증 상태 설정 확장 명령가상 인증기isUserVerified 속성을 설정합니다. 정의는 다음과 같습니다:

HTTP 메서드 URI 템플릿
POST /session/{session id}/webauthn/authenticator/{authenticatorId}/uv

원격 엔드 단계는 다음과 같습니다:

  1. parameters가 JSON 객체가 아니면, WebDriver 오류WebDriver error code invalid argument 와 함께 반환합니다.

  2. authenticatorId가상 인증기 데이터베이스에 저장된 어떤 가상 인증기와도 일치하지 않으면, WebDriver 오류WebDriver error code invalid argument와 함께 반환합니다.

  3. parametersisUserVerified 속성이 정의되어 있지 않으면 WebDriver 오류WebDriver error code invalid argument와 함께 반환합니다.

  4. authenticatorauthenticatorId로 식별된 가상 인증기로 둡니다.

  5. authenticatorisUserVerified 속성을 parametersisUserVerified 값으로 설정합니다.

  6. 성공을 반환합니다.

11.10. 자격 증명 속성 설정(Set Credential Properties)

자격 증명 속성 설정 확장 명령가상 인증기공개키 자격 증명 소스backupEligibilitybackupState 자격 증명 속성을 설정할 수 있습니다. 정의는 다음과 같습니다:

HTTP 메서드 URI 템플릿
POST /session/{session id}/webauthn/authenticator/{authenticatorId}/credentials/{credentialId}/props

Set Credential Properties Parameters는 JSON 오브젝트로, 원격 엔드 단계parameters로 전달됩니다. 다음과 같은 keyvalue 쌍을 포함합니다:

Key 설명 값 타입
backupEligibility 백업 자격(backup eligibility) 자격 증명 속성 boolean
backupState 백업 상태(backup state) 자격 증명 속성 boolean

원격 엔드 단계는 다음과 같습니다:

  1. parameters가 JSON 오브젝트가 아니면, WebDriver 오류WebDriver 오류 코드 invalid argument를 반환합니다.

    Note: parametersSet Credential Properties Parameters 객체입니다.

  2. authenticatorId가상 인증기와 일치하지 않으면 가상 인증기 데이터베이스에서 WebDriver 오류WebDriver 오류 코드 invalid argument를 반환합니다.

  3. credentialcredentialId와 일치하는 authenticator가 관리하는 공개키 자격 증명 소스로 합니다.

  4. credential이 비어 있으면, WebDriver 오류WebDriver 오류 코드 invalid argument를 반환합니다.

  5. backupEligibilityparametersbackupEligibility 속성 값으로 합니다.

  6. backupEligibility가 정의된 경우, credential백업 적합성 자격 증명 속성backupEligibility 값으로 설정합니다.

    참고: 일반적으로 backupEligibility 속성은 공개키 크리덴셜 소스에 영구적으로 적용됩니다. 자격 증명 속성 설정은 테스트 및 디버깅 목적으로 이를 변경할 수 있습니다.

  7. backupStateparametersbackupState 속성 값으로 합니다.

  8. backupState가 정의된 경우, credential백업 상태 자격 증명 속성backupState 값으로 설정합니다.

  9. 성공을 반환합니다.

12. IANA 고려 사항

12.1. WebAuthn 어테스테이션 명세 식별자 등록 업데이트

이 절에서는 § 8 정의된 어테스테이션 명세에서 정의된 아래 어테스테이션 명세 식별자들을 IANA "WebAuthn Attestation Statement Format Identifiers" 레지스트리 [IANA-WebAuthn-Registries]에 대해 업데이트하며, [RFC8809]에 의해 제정되었고, 최초 [WebAuthn-1]에서 등록된 식별자가 본 명세를 참조하도록 변경합니다.

  • WebAuthn 어테스테이션 명세 식별자: packed

  • 설명: "packed" 어테스테이션 명세 형식은 WebAuthn에 최적화된 어테스테이션 형식입니다. 매우 간결하며 확장 가능한 인코딩을 제공합니다. 제한된 리소스(예: 시큐어 엘리먼트)를 가지는 인증기도 구현할 수 있습니다.

  • 명세 문서: 본 명세의 § 8.2 Packed Attestation Statement Format

  • WebAuthn 어테스테이션 명세 식별자: tpm

  • 설명: TPM 어테스테이션 명세 형식은 packed 명세 형식과 동일한 형식을 반환하지만 rawData, signature 등 계산 방법이 다릅니다.

  • 명세 문서: 본 명세의 § 8.3 TPM Attestation Statement Format

  • WebAuthn 어테스테이션 명세 식별자: android-key

  • 설명: 안드로이드 "N" 및 이후 버전의 플랫폼 인증기는 이 독자적 하드웨어 어테스테이션을 제공합니다.

  • 명세 문서: 본 명세의 § 8.4 Android Key Attestation Statement Format

  • WebAuthn 어테스테이션 명세 식별자: android-safetynet

  • 설명: 안드로이드 기반의 플랫폼 인증기는 Android SafetyNet API 기반 어테스테이션 명세를 생성할 수 있습니다.

  • 명세 문서: 본 명세의 § 8.5 Android SafetyNet Attestation Statement Format

  • WebAuthn 어테스테이션 명세 식별자: fido-u2f

  • 설명: FIDO U2F 인증기에 사용합니다.

  • 명세 문서: 본 명세의 § 8.6 FIDO U2F Attestation Statement Format

12.2. WebAuthn 어테스테이션 명세 식별자 신규 등록

이 절에서는 § 8 정의된 어테스테이션 명세에서 새롭게 정의된 어테스테이션 명세 식별자를 IANA "WebAuthn Attestation Statement Format Identifiers" 레지스트리 [IANA-WebAuthn-Registries]에 신규로 등록함을 명시합니다. 이는 [RFC8809]에 의해 제정되었습니다.

12.3. WebAuthn 확장 식별자 등록 업데이트

이 절에서는 § 10 정의된 확장에서 정의된 아래 확장 식별자 값을 IANA "WebAuthn Extension Identifiers" 레지스트리 [IANA-WebAuthn-Registries]에 대해 업데이트함을 명시합니다. 이 레지스트리는 [RFC8809]에 의해 제정되었고, 원래는 [WebAuthn-1]에서 등록된 값입니다.

12.4. WebAuthn 확장 식별자 등록

이 섹션은 섹션 § 10 정의된 확장(Defined Extensions)에서 새로 정의된 아래 나열된 확장 식별자 값을, [RFC8809]에 의해 설립된 IANA "WebAuthn Extension Identifiers" 레지스트리 [IANA-WebAuthn-Registries]에 등록합니다.

12.5. Well-Known URI 등록

이 섹션은 IANA "Well-Known URIs" 레지스트리 [IANA-Well-Known-URIs]에 다음 well-known URI를 등록합니다.

13. 보안 고려사항

이 사양은 웹 API(Web API)와 암호화 피어 엔티티 인증 프로토콜을 정의합니다. 웹 인증 API(Web Authentication API)를 통해 웹 개발자(즉, "작성자(authors)")는 등록인증 세레모니(ceremonies)에서 웹 인증 프로토콜을 활용할 수 있습니다. 웹 인증 프로토콜 엔드포인트를 구성하는 엔티티는 사용자 제어 WebAuthn 인증기(Authenticators)WebAuthn 신뢰 당사자(Relying Party)신뢰 당사자(Relying Party) 웹 애플리케이션을 호스팅하는 컴퓨팅 환경입니다. 이 모델에서 사용자 에이전트는 WebAuthn 클라이언트(WebAuthn Client)와 함께 인증기(authenticators)신뢰 당사자(Relying Parties) 사이의 중개자 역할을 합니다. 또한, 인증기(authenticators)는 자신의 출처(provenance)를 신뢰 당사자(Relying Parties)에게 증명(attest)할 수 있습니다.

현재 이 사양은 상세한 보안 고려 사항을 다루지 않습니다. 그러나 [FIDOSecRef] 문서는 이 사양에 전반적으로 적용할 수 있는 보안 분석을 제공합니다. 또한 [FIDOAuthnrSecReqs] 문서 모음은 인증기(authenticator) 보안 특성에 대한 유용한 정보를 제공합니다.

아래 하위 섹션은 현재 웹 인증(Web Authentication) 특정 보안 고려 사항을 포함합니다. 이들은 대상 청중에 따라 나뉩니다. 일반적인 보안 고려 사항은 이 섹션의 직접적인 하위 섹션이며, 인증기(authenticator), 클라이언트(client), 신뢰 당사자(Relying Party) 구현자를 위한 보안 고려 사항은 각각의 하위 섹션으로 그룹화되어 있습니다.

13.1. 자격 증명 ID 서명 안 함(Credential ID Unsigned)

인증 어서션(authentication assertion)과 함께 제공되는 자격 증명 ID(credential ID)는 서명되지 않습니다. 이것은 문제가 되지 않습니다. 인증기(authenticator)가 잘못된 자격 증명 ID(credential ID)를 반환하거나, 공격자가 자격 증명 ID(credential ID)를 가로채서 조작할 경우 발생할 수 있는 일은, WebAuthn 신뢰 당사자(WebAuthn Relying Party)가 반환된 서명된 인증기 데이터(authenticator data) (즉, 어서션(assertion))를 검증할 올바른 자격 증명 공개 키(credential public key)를 찾지 못하게 되는 것이며, 따라서 상호 작용은 오류로 종료되기 때문입니다.

13.2. 클라이언트와 인증기 간의 물리적 근접성

WebAuthn 인증기 모델(authenticator model)에서는 일반적으로 로밍 인증기(roaming authenticators)클라이언트(client)와 물리적으로 가깝고 직접 통신한다고 가정합니다. 이러한 배치에는 몇 가지 중요한 장점이 있습니다.

클라이언트(client)인증기(authenticator) 간의 물리적 근접성은 소유한 것(something you have) 인증 요소(authentication factor)의 핵심 강점입니다. 예를 들어, 로밍 인증기(roaming authenticator)가 USB 또는 블루투스를 통해서만 통신할 수 있는 경우, 이러한 전송의 제한된 범위는 악의적인 행위자가 인증기(authenticator)와 상호 작용하려면 물리적으로 해당 범위 내에 있어야 한다는 것을 보장합니다. 이것은 원격에서 호출될 수 있는 인증기(authenticator)의 경우에는 반드시 참은 아닙니다. 인증기(authenticator)사용자 존재(user presence)를 검증하더라도, 사용자는 원격으로 시작된 악의적인 요청을 승인하도록 속일 수 있습니다.

클라이언트(client)인증기(authenticator) 간의 직접 통신은 클라이언트(client)자격 증명(credentials)에 대한 범위(scope) 제한을 강제할 수 있음을 의미합니다. 이와 대조적으로, 클라이언트(client)인증기(authenticator) 간의 통신이 제3자에 의해 중재되는 경우, 클라이언트(client)범위(scope) 제한을 강제하고 인증기(authenticator)에 대한 액세스를 제어하기 위해 제3자를 신뢰해야 합니다. 어느 쪽도 실패하지 않으면 악의적인 신뢰 당사자(Relying Party)가 다른 신뢰 당사자(Relying Parties)에 대해 유효한 인증 어서션(authentication assertions)를 받거나, 악의적인 사용자가 다른 사용자에 대한 인증 어서션(authentication assertions)에 대한 액세스를 얻는 결과가 발생할 수 있습니다.

인증기(authenticator)클라이언트(client)와 물리적으로 가까이 있을 필요가 없거나, 클라이언트(client)인증기(authenticator)가 직접 통신하지 않는 솔루션을 설계하는 경우, 설계자는 이것이 범위(scope) 제한의 강제 및 인증기(authenticator)소유한 것(something you have) 인증 요소로서의 강도에 어떤 영향을 미치는지 고려해야 합니다(SHOULD).

13.3. 인증기(authenticators)에 대한 보안 고려 사항

13.3.1. 증명 인증서 계층 구조(Attestation Certificate Hierarchy)

증명 인증서의 3계층 계층 구조(즉, 증명 루트, 증명 발급 CA, 증명 인증서)를 권장합니다(RECOMMENDED). 또한 각 WebAuthn 인증기(WebAuthn Authenticator) 기기 라인(즉, 모델)마다 인증기 모델의 특정 버전에 문제가 있는 경우 이를 격리하는 데 도움이 되도록 별도의 발급 CA를 사용하는 것이 좋습니다(RECOMMENDED).

증명 루트 인증서가 단일 WebAuthn 인증기(WebAuthn Authenticator) 기기 라인(즉, AAGUID)에 전용되지 않은 경우, 인증기 데이터(authenticator data)에 대해 검증할 수 있도록 AAGUID를 증명 인증서 자체에 지정해야 합니다(SHOULD).

13.3.2. 증명 인증서 및 증명 인증서 CA 손상(Attestation Certificate and Attestation Certificate CA Compromise)

증명 인증서 발급에 사용되는 중간 CA 또는 루트 CA가 손상된 경우, WebAuthn 인증기(WebAuthn Authenticator) 증명 키 쌍(attestation key pairs)은 여전히 안전하지만 해당 인증서는 더 이상 신뢰할 수 없습니다. WebAuthn 인증기(WebAuthn Authenticator) 제조업체는 인증기(authenticator) 모델에 대한 증명 공개 키(attestation public keys)를 기록한 경우, 새로운 중간 CA 또는 새로운 루트 CA에서 이러한 키에 대한 새로운 증명 인증서(attestation certificates)를 발급할 수 있습니다. 루트 CA가 변경되는 경우 WebAuthn 신뢰 당사자(WebAuthn Relying Parties)는 신뢰하는 루트 인증서를 그에 따라 업데이트해야 합니다(MUST).

WebAuthn 인증기(WebAuthn Authenticator) 증명 인증서(attestation certificate)개인 키(private key)가 손상된 경우 발급 CA에 의해 폐지되어야 합니다(MUST). WebAuthn 인증기 제조업체는 노출이 펌웨어 결함으로 인한 것이라면 새로운 증명 개인 키(attestation private keys)인증서(certificates)를 이미 제조된 WebAuthn 인증기(WebAuthn Authenticators)에 주입하기 위해 펌웨어 업데이트를 배포해야 할 수 있습니다. (이 과정은 이 사양의 범위를 벗어납니다.) WebAuthn 인증기(WebAuthn Authenticator) 제조업체가 이러한 기능을 갖고 있지 않은 경우, 신뢰 당사자(Relying Parties)가 영향을 받은 WebAuthn 인증기(WebAuthn Authenticators)의 추가적인 증명 명세서(attestation statements)를 신뢰하는 것이 불가능할 수 있습니다.

§ 13.4.5 폐지된 증명 인증서(Revoked Attestation Certificates)에서 신뢰 당사자(Relying Parties)에 대한 관련 보안 고려 사항도 참조하십시오.

13.4. 신뢰 당사자(Relying Parties)에 대한 보안 고려 사항

13.4.1. WebAuthn 신뢰 당사자(WebAuthn Relying Parties)에 대한 보안 이점

이 사양이 WebAuthn 신뢰 당사자(WebAuthn Relying Parties)에게 제공하는 주요 이점은 다음과 같습니다.

  1. 사용자와 계정은 광범위하게 호환되고 사용하기 쉬운 다중 요소 인증을 사용하여 보호할 수 있습니다.

  2. Relying Party는 사용자에게 authenticator 하드웨어를 제공할 필요가 없습니다. 대신 각 사용자는 독립적으로 적합한 authenticator를 획득할 수 있으며, 동일한 authenticator를 여러 Relying Party와 함께 사용할 수 있습니다. Relying Party는 선택적으로 authenticator의 보안 특성에 대한 요구사항을 attestation statement를 검사함으로써 강화할 수 있습니다. 이 값은 authenticator에 의해 반환됩니다.

  3. 인증 세레모니(Authentication ceremonies)중간자 공격(man-in-the-middle attacks)에 강합니다. 등록 세레모니(Registration ceremonies)의 경우 아래의 § 13.4.4 증명 제한 사항(Attestation Limitations)을 참조하십시오.

  4. 신뢰 당사자(Relying Party)는 코드 변경을 최소하거나 전혀 하지 않고도 PIN, 생체 인식 및/또는 향후 방법과 같은 여러 유형의 사용자 검증(user verification)를 자동으로 지원할 수 있으며, 사용자가 선택한 인증기(authenticator)를 통해 선호하는 방법을 결정하게 할 수 있습니다.

  5. 신뢰 당사자(Relying Party)는 위의 이점을 얻기 위해 추가 비밀을 저장할 필요가 없습니다.

적합성(Conformance) 섹션에 명시된 것처럼, 신뢰 당사자(Relying Party)는 위의 모든 보안 이점을 얻기 위해 § 7 WebAuthn 신뢰 당사자 작업(WebAuthn Relying Party Operations)에 설명된 대로 동작해야 합니다(MUST). 그러나 이와 약간 다른 주목할 만한 사용 사례가 아래의 § 13.4.4 증명 제한 사항(Attestation Limitations)에 설명되어 있습니다.

13.4.2. 임베디드 사용에 대한 가시성 고려 사항

§ 5.10 iframe 요소 내에서 웹 인증 사용(Using Web Authentication within iframe elements)에 설명된 대로 iframe 내와 같은 임베디드 컨텍스트에서 WebAuthn을 단순하게 사용하면 사용자가 UI 리드레싱(UI Redressing) 공격, 일명 "클릭재킹(Clickjacking)"에 취약해질 수 있습니다. 이는 공격자가 자신의 UI를 신뢰 당사자(Relying Party)의 의도된 UI 위에 오버레이하고 사용자가 신뢰 당사자(Relying Party)와 의도치 않은 작업을 수행하도록 속이려는 시도입니다. 예를 들어, 이러한 기술을 사용하여 공격자는 사용자를 속여 물건을 구매하거나 돈을 이체하게 할 수 있습니다.

WebAuthn 특정 UI는 일반적으로 클라이언트 플랫폼(client platform)에서 처리되므로 UI 리드레싱(UI Redressing)에 취약하지 않지만, 임베디드 WebAuthn 사용 콘텐츠를 가진 신뢰 당사자(Relying Party)는 콘텐츠의 UI가 사용자에게 표시되는지 확인하는 것이 중요할 수 있습니다. 이를 위한 새로운 수단은 실험적인 Intersection Observer v2isVisible 속성 상태를 관찰하는 것입니다. 예를 들어, 임베디드 컨텍스트에서 실행되는 신뢰 당사자(Relying Party)의 스크립트는 isVisblefalse로 설정된 것을 감지하면 팝업 창에서 사전에 로드하여 콘텐츠가 가려지는 것을 방지할 수 있습니다.

13.4.3. 암호화적 챌린지(Cryptographic Challenges)

암호화 프로토콜로서 웹 인증(Web Authentication)은 재생 공격(replay attacks)을 방지하기 위해 무작위화된 챌린지에 의존합니다. 따라서 PublicKeyCredentialCreationOptions.challengePublicKeyCredentialRequestOptions.challenge 값은 신뢰할 수 있는 환경(예: 서버 측)에서 신뢰 당사자(Relying Parties)가 무작위로 생성해야 하며(MUST), 클라이언트 응답의 challenge 값은 생성된 값과 일치해야 합니다(MUST). 이것은 클라이언트의 동작에 의존하지 않는 방식으로 수행되어야 합니다(SHOULD). 예를 들어, 신뢰 당사자(Relying Party)는 작업이 완료될 때까지 챌린지를 일시적으로 저장해야 합니다(SHOULD). 불일치를 허용하면 프로토콜의 보안이 손상됩니다.

챌린지는 WebAuthn 세레모니 시간 초과에 대한 권장 범위 및 기본값(recommended range and default for a WebAuthn ceremony timeout)의 상한과 유사한 기간 동안 유효해야 합니다(SHOULD).

재생 공격을 방지하기 위해 챌린지는 추측이 불가능하도록 충분한 엔트로피를 포함해야 합니다(MUST). 따라서 챌린지는 최소 16바이트 길이여야 합니다(SHOULD).

13.4.4. 증명 제한 사항(Attestation Limitations)

이 섹션은 규범적이지 않습니다.

새 자격 증명 등록(registering a new credential) 시, 존재하는 경우 증명 명세서(attestation statement)WebAuthn 신뢰 당사자(WebAuthn Relying Party)가 다양한 인증기(authenticator) 품질에 대한 보증을 도출할 수 있게 합니다. 예를 들어, 인증기(authenticator) 모델 또는 자격 증명 개인 키(credential private keys)를 저장하고 보호하는 방식 등입니다. 그러나 증명 명세서(attestation statement)는 그 자체로는 신뢰 당사자(Relying Party)증명 개체(attestation object)가 사용자가 의도한 인증기(authenticator)에 의해 생성되었는지, 중간자 공격자(man-in-the-middle attacker)에 의해 생성되지 않았는지 확인할 수 있는 수단을 제공하지 않는다는 점에 유의하는 것이 중요합니다. 예를 들어, 이러한 공격자는 신뢰 당사자(Relying Party) 스크립트에 주입된 악성 코드를 사용할 수 있습니다. 따라서 신뢰 당사자(Relying Party)는 TLS 및 관련 기술과 같은 다른 수단에 의존하여 증명 개체(attestation object)중간자 공격(man-in-the-middle attacks)으로부터 보호해야 합니다.

등록 세레모니(Registration ceremony)가 안전하게 완료되었다고 가정하고, 인증기(authenticator)자격 증명 개인 키(credential private key)의 기밀성을 유지한다고 가정하면, 해당 공개 키 자격 증명(public key credential)을 사용하는 후속 인증 세레모니(Authentication ceremonies)중간자 공격(man-in-the-middle attacks)에 대한 변조에 강합니다.

위의 논의는 모든 증명 유형(attestation types)에 적용됩니다. 모든 경우 중간자 공격자(man-in-the-middle attacker)PublicKeyCredential 개체, 즉 증명 명세서(attestation statement) 및 등록할 자격 증명 공개 키(credential public key)를 교체하고, 후속하여 동일한 공격자를 통과하는 동일한 신뢰 당사자(Relying Party)에 대한 향후 인증 어서션(authentication assertions)범위 지정(scoped)하여 변조하는 것이 가능합니다.

이러한 공격은 감지 가능할 수 있습니다. 신뢰 당사자(Relying Party)가 사용자의 키가 아닌 공격자의 자격 증명 공개 키(credential public key)를 등록했기 때문에, 공격자는 해당 신뢰 당사자(Relying Party)와의 모든 후속 인증 세레모니(Authentication ceremonies)를 변조해야 합니다. 공격을 받지 않은 세레모니는 실패하므로 공격이 드러날 수 있습니다.

자체 증명(Self Attestation)없음(None)을 제외한 증명 유형(Attestation types)신뢰 당사자(Relying Parties)가 모델 지정과 같은 인증기(authenticator) 정보를 사용자에게 표시할 수 있으므로 이러한 공격의 어려움을 높일 수 있습니다. 따라서 공격자는 사용자의 인증기(authenticator)와 동일한 모델의 정품 인증기(authenticator)를 사용해야 할 수 있으며, 사용자는 신뢰 당사자(Relying Party)가 기대한 것과 다른 인증기(authenticator) 모델을 보고한다는 것을 알 수 있습니다.

참고(Note): 위에서 설명한 중간자 공격(man-in-the-middle attacks)의 모든 변형은 기존 비밀번호 인증에 대한 중간자 공격(man-in-the-middle attack)보다 공격자가 수행하기가 더 어렵습니다.

13.4.5. 폐지된 증명 인증서(Revoked Attestation Certificates)

증명 인증서(attestation certificate) 검증이 폐지된 중간 증명 CA 인증서로 인해 실패하고, 신뢰 당사자(Relying Party)의 정책이 이러한 상황에서 등록/인증 요청을 거부하도록 요구하는 경우, 신뢰 당사자(Relying Party)는 CA 손상 날짜 이후 동일한 중간 CA에 연결된 증명 인증서(attestation certificate)를 사용하여 등록된 공개 키 자격 증명(public key credentials)도 등록 취소(또는 "자체 증명(self attestation)"과 동일한 신뢰 수준으로 표시)하는 것이 좋습니다(RECOMMENDED). 따라서 신뢰 당사자(Relying Parties)는 등록 취소 후 등록(registration)이 수행된 경우 관련 공개 키 자격 증명(public key credentials)을 등록 취소하기 위해 등록(registration) 중에 중간 증명 CA 인증서를 기억하는 것이 좋습니다(RECOMMENDED).

§ 13.3.2 증명 인증서 및 증명 인증서 CA 손상(Attestation Certificate and Attestation Certificate CA Compromise)에서 인증기(authenticators)에 대한 관련 보안 고려 사항도 참조하십시오.

13.4.6. 자격 증명 분실 및 키 이동성(Credential Loss and Key Mobility)

이 사양은 자격 증명 개인 키(credential private keys)를 백업하거나 인증기(authenticators) 간에 공유하기 위한 프로토콜을 정의하지 않습니다. 일반적으로 자격 증명 개인 키(credential private key)는 생성된 인증기(authenticator)를 절대로 떠나지 않아야 합니다. 따라서 인증기(authenticator)를 분실하는 것은 일반적으로 분실된 인증기(authenticator)바인딩된(bound) 모든 자격 증명(credentials)을 잃는 것을 의미하며, 사용자가 신뢰 당사자(Relying Party)에 등록된 자격 증명(credential)이 하나뿐인 경우 계정이 잠길 수 있습니다. 개인 키를 백업하거나 공유하는 대신 웹 인증 API(Web Authentication API)를 사용하면 동일한 사용자에게 여러 자격 증명(credentials)을 등록할 수 있습니다. 예를 들어, 사용자는 자주 사용하는 클라이언트 기기(client devices)플랫폼 자격 증명(platform credentials)을 등록하고, 백업용으로 새롭거나 드물게 사용하는 클라이언트 기기(client devices)와 함께 사용할 하나 이상의 로밍 자격 증명(roaming credentials)을 등록할 수 있습니다.

신뢰 당사자(Relying Parties)는 사용자가 동일한 사용자 계정(user account)에 여러 자격 증명(credentials)을 등록하도록 허용하고 권장해야 합니다(SHOULD). 신뢰 당사자(Relying Parties)는 이러한 다양한 자격 증명(credentials)이 서로 다른 인증기(authenticators)바인딩된(bound) 상태인지 확인하기 위해 excludeCredentialsuser.id 옵션을 사용해야 합니다(SHOULD).

13.4.7. 보호되지 않은 계정 감지(Unprotected account detection)

이 섹션은 규범적이지 않습니다.

이 보안 고려 사항은 첫 번째 인증 단계로 비어있지 않은(non-empty) allowCredentials 인자를 사용하여 인증 세레모니(Authentication ceremonies)를 지원하는 신뢰 당사자(Relying Parties)에게 적용됩니다. 예를 들어, 첫 번째 인증 단계로 서버 측 자격 증명(server-side credentials)을 사용하는 인증의 경우입니다.

이 경우 allowCredentials 인자는 어떤 사용자 계정(user accounts)에 WebAuthn 자격 증명이 등록되어 있고 어떤 계정에 없는지에 대한 정보를 유출할 위험이 있으며, 이는 계정 보호 강도의 신호가 될 수 있습니다. 예를 들어, 공격자가 사용자 이름만 제공하여 인증 세레모니(Authentication ceremony)를 시작할 수 있고, 신뢰 당사자(Relying Party)가 일부 사용자 계정(user accounts)에는 비어있지 않은 allowCredentials로 응답하고, 다른 사용자 계정(user accounts)에는 실패 또는 비밀번호 챌린지로 응답한다고 가정합니다. 그러면 공격자는 후자의 사용자 계정(user accounts)는 성공적인 인증을 위해 WebAuthn 어서션(assertion)이 필요하지 않을 가능성이 높으며, 따라서 공격을 잠재적으로 취약한 해당 계정에 집중할 수 있다고 결론 내릴 수 있습니다.

이 문제는 § 14.6.2 사용자 이름 열거(Username Enumeration)§ 14.6.3 자격 증명 ID를 통한 개인 정보 유출(Privacy leak via credential IDs)에 설명된 문제와 유사하며, 유사한 방식으로 완화할 수 있습니다.

13.4.8. 코드 인젝션 공격(Code injection attacks)

신뢰 당사자(Relying Party)공개 키 자격 증명(public key credentials) 범위(scope) 내의 원점(origin)에서 실행되는 모든 악성 코드는 WebAuthn이 제공할 수 있는 모든 보안 보장을 무효화할 잠재력이 있습니다. WebAuthn 클라이언트(WebAuthn Clients)보안 컨텍스트(secure contexts)에서만 WebAuthn API를 노출하므로 가장 기본적인 공격을 완화하지만 신뢰 당사자(Relying Parties)는 추가적인 예방 조치와 결합해야 합니다(SHOULD).

코드 인젝션은 여러 가지 방식으로 발생할 수 있습니다. 이 섹션에서는 가능한 시나리오를 지적하고 적절한 완화 방법을 제안하려고 하지만, 모든 목록은 아닙니다.

13.4.9. 자격 증명의 원점(origin) 유효성 검사

자격 증명 등록(registering a credential)어서션 검증(verifying an assertion) 시, 신뢰 당사자(Relying Party)클라이언트 데이터(client data)origin 멤버를 유효성 검사해야 합니다(MUST).

신뢰 당사자(Relying Party)는 예기치 않은 origin 값을 허용해서는 안 됩니다(MUST). 이를 허용하면 악의적인 웹사이트가 유효한 자격 증명(credentials)을 얻을 수 있습니다. WebAuthn 자격 증명의 범위(scope)는 등록된 RP ID 외부의 도메인에서 사용을 방지하지만, 신뢰 당사자(Relying Party)의 원점 유효성 검사는 결함이 있는 인증기(authenticator)가 자격 증명 범위(scope)를 강제하지 못하는 경우 보호의 추가 계층으로 작용합니다. 잠재적인 악의적인 서브도메인에 대한 논의는 § 13.4.8 코드 인젝션 공격(Code injection attacks)을 참조하십시오.

유효성 검사는 신뢰 당사자(Relying Party)의 필요에 따라 정확한 문자열 일치 또는 기타 방법으로 수행할 수 있습니다(MAY). 예를 들어:

  • https://example.org에서만 제공되는 웹 애플리케이션은 originhttps://example.org과 정확히 같아야 합니다(SHOULD).

    이것은 originhttps:// 문자열 뒤에 RP ID가 오는 문자열로 예상되는 가장 간단한 경우입니다.

  • 소수의 도메인에서 제공되는 웹 애플리케이션은 origin이 허용된 원점 목록의 요소와 정확히 같아야 한다고 요구할 수 있습니다. 예를 들어 목록 ["https://example.org", "https://login.example.org"]입니다.

  • 관련 원점 요청(related origin requests)을 활용하는 웹 애플리케이션은 origin이 허용된 원점 목록의 요소와 정확히 같아야 한다고 요구할 수도 있습니다. 예를 들어 목록 ["https://example.co.uk", "https://example.de", "https://myexamplerewards.com"]입니다. 이 목록은 일반적으로 RP ID의 well-known URI에 나열된 원점과 일치합니다. § 5.11 관련 원점 간의 웹 인증 사용(Using Web Authentication across related origins)을 참조하십시오.

  • 다양한 도메인에서 제공되며 자주 변경되는 웹 애플리케이션은 origin 을 구조적으로 파싱하고, URL scheme이 https임을 요구하며 권한(authority)이 RP ID와 같거나 그 하위 도메인 중 하나여야 합니다. 예를 들어, example.org 혹은 example.org의 하위 도메인 등이 포함될 수 있습니다.

    참고(Note): § 13.4.8 코드 인젝션 공격(Code injection attacks)에서 RP ID의 모든 서브도메인을 허용할 때의 위험에 대한 논의를 참조하십시오.

  • 동반 네이티브 애플리케이션이 있는 웹 애플리케이션은 origin이 네이티브 애플리케이션에 대한 운영 체제 종속 식별자가 되도록 허용할 수 있습니다. 예를 들어, 이러한 신뢰 당사자(Relying Party)origin이 목록 ["https://example.org", "example-os:appid:204ffa1a5af110ac483f131a1bef8a841a7adb0d8d135908bbd964ed05d2653b"]의 요소 중 하나와 정확히 같아야 한다고 요구할 수 있습니다.

클라이언트 데이터(client data)topOrigin 멤버를 유효성 검사할 때도 유사한 고려 사항이 적용됩니다. topOrigin이 있는 경우 신뢰 당사자(Relying Party)는 해당 값이 예상되는지 유효성 검사해야 합니다(MUST). 이 유효성 검사는 신뢰 당사자(Relying Party)의 필요에 따라 정확한 문자열 일치 또는 기타 방법으로 수행할 수 있습니다(MAY). 예를 들어:

  • 크로스 원점 iframe에 포함되지 않으려는 웹 애플리케이션은 topOriginorigin과 정확히 같아야 한다고 요구할 수 있습니다.

  • 소수의 도메인에 있는 크로스 원점 iframe에 포함되려는 웹 애플리케이션은 topOrigin이 허용된 원점 목록의 요소와 정확히 같아야 한다고 요구할 수 있습니다. 예를 들어 목록 ["https://example-partner1.org", "https://login.partner2-example.org"]입니다.

  • 다수의 도메인에 있는 크로스 원점 iframe에 포함되려는 웹 애플리케이션은 topOrigin의 모든 값을 허용하거나 동적 절차를 사용하여 특정 세레모니에 대해 주어진 topOrigin 값이 허용되는지 확인할 수 있습니다.

14. 프라이버시 고려사항

[FIDO-Privacy-Principles]의 개인 정보 보호 원칙도 이 사양에 적용됩니다.

이 섹션은 대상 청중에 따라 나뉩니다. 일반적인 개인 정보 보호 고려 사항은 이 섹션의 직접적인 하위 섹션이며, 인증기(authenticator), 클라이언트(client), 신뢰 당사자(Relying Party) 구현자를 위한 개인 정보 보호 고려 사항은 각각의 하위 섹션으로 그룹화되어 있습니다.

14.1. 익명화 방지 조치(De-anonymization Prevention Measures)

이 섹션은 규범적이지 않습니다.

웹 인증 API(Web Authentication API) 설계의 많은 측면은 개인 정보 보호 우려에 의해 동기가 부여되었습니다. 이 사양에서 고려된 주요 관심사는 사용자의 개인 신원, 즉 사람 식별 또는 동일한 사람에게 속하는 별도의 신원 상관 관계(correlation)의 보호입니다. 웹 인증 API(Web Authentication API)는 어떤 형태의 전역 식별자도 사용하거나 제공하지 않지만, 다음과 같은 잠재적으로 상관 관계를 맺을 수 있는 식별자가 사용됩니다.

위 정보의 일부는 신뢰 당사자(Relying Party)와 필연적으로 공유됩니다. 다음 섹션에서는 악의적인 신뢰 당사자(Relying Parties)가 이를 사용하여 사용자의 개인 신원을 발견하는 것을 방지하기 위해 취해진 조치를 설명합니다.

14.2. 익명, 범위 지정(scoped), 상관 관계 없는(non-correlatable) 공개 키 자격 증명(Public Key Credentials)

이 섹션은 규범적이지 않습니다.

강력한 인증을 활성화하기 위해 자격 증명 ID(Credential IDs)자격 증명 공개 키(credential public keys)는 필연적으로 WebAuthn 신뢰 당사자(WebAuthn Relying Party)와 공유되지만, 식별 정보를 최소화하도록 설계되었으며 신뢰 당사자(Relying Parties) 간에 공유되지 않습니다.

또한 클라이언트 측 검색 가능 공개 키 자격 증명 소스(client-side discoverable public key credential source)신뢰 당사자(Relying Party)가 지정한 사용자 핸들(user handle)을 선택적으로 포함할 수 있습니다. 그러면 자격 증명(credential)을 사용하여 사용자를 식별하고 인증(authenticate)할 수 있습니다. 이것은 개인 정보 보호에 민감한 신뢰 당사자(Relying Party)가 전통적인 사용자 이름 없이 사용자 계정(user account) 생성을 허용하여 신뢰 당사자(Relying Parties) 간의 비상관성(non-correlatability)을 더욱 향상시킬 수 있음을 의미합니다.

14.3. 인증기 로컬 생체 인식(Biometric Recognition)

생체 인증기(Biometric authenticators)인증기(authenticator) 내부에서 생체 인식(biometric recognition)을 수행합니다. 단 플랫폼 인증기(platform authenticators)의 경우 구현에 따라 생체 데이터가 클라이언트(client)에게도 표시될 수 있습니다. 생체 데이터는 WebAuthn 신뢰 당사자(WebAuthn Relying Party)에게 공개되지 않으며, 공개 키 자격 증명(public key credential)의 생성 및 등록(registration) 또는 사용을 위한 사용자 검증(user verification)을 로컬에서 승인하는 데만 사용됩니다. 따라서 악의적인 신뢰 당사자(Relying Party)는 생체 데이터를 통해 사용자의 개인 신원을 발견할 수 없으며, 신뢰 당사자(Relying Party)에서의 보안 침해로 인해 다른 신뢰 당사자(Relying Parties)에서 로그인 위조에 사용할 생체 데이터가 노출되지 않습니다.

신뢰 당사자(Relying Party)생체 인식(biometric recognition)을 요구하는 경우, 이것은 생체 인증기(biometric authenticator)사용자 검증(user verification)을 수행한 후 서명된 어서션(assertion) 응답에서 UV 플래그(flag)를 설정하여 결과를 신호함으로써 로컬에서 수행됩니다. 신뢰 당사자(Relying Party)에게 생체 데이터 자체를 공개하는 것이 아닙니다.

14.4. 인증기(authenticators)에 대한 개인 정보 보호 고려 사항

14.4.1. 증명 개인 정보 보호(Attestation Privacy)

증명 인증서(Attestation certificates)증명 키 쌍(attestation key pairs)은 사용자를 추적하거나 동일한 사용자의 다양한 온라인 신원을 연결하는 데 사용할 수 있습니다. 이것은 다음을 포함하여 여러 가지 방법으로 완화할 수 있습니다.

14.4.2. 인증기에 저장된 개인 식별 정보의 개인 정보 보호

인증기(Authenticators)는 이 사양에 정의된 것 외에 클라이언트(clients)에게 추가 정보를 제공할 수 있습니다(MAY). 예를 들어, 사용자가 인증 세레모니(Authentication ceremony)에 사용할 자격 증명(credential)을 선택할 수 있는 풍부한 UI를 클라이언트(client)가 제공할 수 있도록 합니다. 인증기(authenticator)가 그렇게 선택하는 경우, 성공적인 사용자 검증(user verification)이 수행되지 않은 한 개인 식별 정보를 노출해서는 안 됩니다(SHOULD NOT). 인증기(authenticator)가 둘 이상의 등록된 사용자와 함께 사용자 검증(user verification)을 지원하는 경우, 인증기(authenticator)는 현재 검증된(verified) 사용자 이외의 사용자의 개인 식별 정보를 노출해서는 안 됩니다(SHOULD NOT). 결과적으로, 사용자 검증(user verification)을 수행할 수 없는 인증기(authenticator)는 개인 식별 정보를 저장해서는 안 됩니다(SHOULD NOT).

이 논의의 목적상, id 멤버로서 전달되는 사용자 핸들(user handle)은 개인 식별 정보로 간주되지 않습니다. § 14.6.1 사용자 핸들 내용(User Handle Contents)를 참조하십시오.

이러한 권장 사항은 인증기(authenticator)에 대한 물리적 액세스를 가진 공격자가 해당 인증기(authenticator)의 등록된 사용자에 대한 개인 식별 정보를 추출하는 것을 방지하는 데 도움이 됩니다.

14.5. 클라이언트(clients)에 대한 개인 정보 보호 고려 사항

14.5.1. 등록 세레모니 개인 정보 보호(Registration Ceremony Privacy)

동의(consent) 없이 식별되는 것으로부터 사용자를 보호하기 위해, [[Create]](origin, options, sameOriginWithAncestors) 메서드의 구현은 악의적인 WebAuthn 신뢰 당사자(WebAuthn Relying Party)가 다음 경우들을 구별할 수 있게 하는 정보가 유출되지 않도록 주의해야 합니다. 여기서 "제외됨(excluded)"은 신뢰 당사자(Relying Party)excludeCredentials에 나열한 자격 증명(credentials) 중 하나 이상이 인증기(authenticator)바인딩된(bound) 상태임을 의미합니다.

위 경우가 구별 가능한 경우, 악의적인 신뢰 당사자(Relying Party)가 사용 가능한 자격 증명(credentials)을 탐색(probing)하여 사용자를 식별할 수 있는 정보가 유출됩니다. 예를 들어, 이러한 정보 유출 중 하나는 제외된 인증기(authenticator)가 사용 가능해지자마자 클라이언트가 실패 응답을 반환하는 경우입니다. 이 경우 - 특히 제외된 인증기(authenticator)플랫폼 인증기(platform authenticator)인 경우 - 신뢰 당사자(Relying Party)는 사용자가 수동으로 취소할 수 있기 전에 세레모니(ceremony)가 취소되었음을 감지할 수 있으며, 따라서 excludeCredentials 매개변수에 나열된 자격 증명(credentials) 중 하나 이상이 사용자에게 사용 가능하다는 결론을 내릴 수 있습니다.

그러나 구별 가능한 오류가 반환되기 전에 사용자가 새 자격 증명 생성에 동의(consented)한 경우에는 위 내용은 문제가 되지 않습니다. 이 경우 사용자는 유출될 정보를 공유할 의도를 확인했기 때문입니다.

14.5.2. 인증 세레모니 개인 정보 보호(Authentication Ceremony Privacy)

동의(consent) 없이 식별되는 것으로부터 사용자를 보호하기 위해, [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 메서드의 구현은 악의적인 WebAuthn 신뢰 당사자(WebAuthn Relying Party)가 다음 경우들을 구별할 수 있게 하는 정보가 유출되지 않도록 주의해야 합니다. 여기서 "지정됨(named)"은 신뢰 당사자(Relying Party)allowCredentials에 나열한 자격 증명(credential)을 의미합니다.

위의 경우들이 구분 가능하다면, 악의적인 Relying Party가 어떤 credentials이 사용 가능한지 탐색하여 사용자를 식별할 수 있는 정보가 유출됩니다. 예를 들어, 이런 정보 유출은 클라이언트가 authenticator에서 명명된 credential을 발견한 후에만 인증 절차를 취소하거나 진행할 수 있는 안내와 컨트롤을 표시하는 경우 발생할 수 있습니다. 이 경우 Relying Party가 해당 client의 동작을 알고 있다면, Relying Partyceremony가 사용자가 취소했음을, timeout 때문이 아님을 감지할 수 있고, 따라서 allowCredentials 파라미터에 나열된 credentials 중 최소 하나가 사용자에게 사용 가능함을 결론지을 수 있습니다.

이 문제는 지정된 자격 증명(credentials)의 사용 가능 여부와 관계없이 사용자가 언제든 인증 세레모니(Authentication ceremony)를 취소할 수 있도록 하는 컨트롤을 표시하여 해결할 수 있습니다.

14.5.3. 운영 체제 계정 간의 개인 정보 보호

다중 사용자 운영 체제가 있는 클라이언트 기기(client device)플랫폼 인증기(platform authenticator)가 포함된 경우, 플랫폼 인증기(platform authenticator)클라이언트 기기(client device)는 모든 플랫폼 자격 증명(platform credential)의 존재가 해당 플랫폼 자격 증명(platform credential)을 생성한 운영 체제 사용자에게만 노출되도록 협력해야 합니다(SHOULD).

14.5.4. 클라이언트 기능 공개(Disclosing Client Capabilities)

getClientCapabilities 메서드는 WebAuthn 신뢰 당사자(WebAuthn Relying Parties)가 클라이언트 및/또는 사용자와 함께 성공할 확률이 높은 등록 및 인증 환경을 조성하는 데 도움을 줍니다.

WebAuthn 클라이언트(WebAuthn Client)의 기능 지원 또는 미지원은 지문 위험(fingerprinting risk)이 될 수 있습니다. 이 위험을 줄이기 위해 클라이언트는 false 값을 반환하는 것보다는 반환된 레코드에서 키를 생략하는 것을 선호해야 합니다(SHOULD). 키를 생략하면(§ 5.1.7 클라이언트 기능의 가용성 - PublicKeyCredential의 getClientCapabilities() 메서드(Availability of client capabilities - PublicKeyCredential’s getClientCapabilities() Method)에 설명된 대로) 기능이 지원되지 않음을 명시적으로 확인하는 것보다 지문 위험 표면이 적습니다. 클라이언트 구현은 클라이언트 정책 및/또는 사용자 동의에 따라 기능 공개를 제한할 수도 있습니다(MAY).

14.6. 신뢰 당사자(Relying Parties)에 대한 개인 정보 보호 고려 사항

14.6.1. 사용자 핸들 내용(User Handle Contents)

user handle§ 14.4.2 Privacy of personally identifying information Stored in Authenticators에서 개인 식별 정보로 간주되지 않으며, authenticatorsuser handles을 사용자 인증 전에 공개할 수도 있으므로, Relying Party는 개인 식별 정보, 예를 들어 이메일 주소나 사용자명을 user handle에 포함시키면 안 됩니다. 이는 해시값도 포함되며, 해시 함수가 salted 방식으로 salt 값이 Relying Party에게만 private한 경우를 제외하고, 해싱은 추측 가능한 입력값의 탐색을 막지 못하므로 해시도 사용하지 않아야 합니다. user handle은 64 바이트 랜덤값을 사용하는 것이 권장되며, 이 값을 user account에 저장하는 것이 좋습니다.

14.6.2. 사용자 이름 열거(Username Enumeration)

등록(registration) 또는 인증 세레모니(Authentication ceremony)를 시작할 때 WebAuthn 신뢰 당사자(WebAuthn Relying Party)가 등록된 사용자에 대한 민감한 정보를 유출할 위험이 있습니다. 예를 들어, 신뢰 당사자(Relying Party)가 사용자 이름으로 이메일 주소를 사용하고 공격자가 "alex.mueller@example.com"에 대한 인증(authentication) 세레모니(ceremony)를 시작하려고 시도하고 신뢰 당사자(Relying Party)가 실패로 응답하지만, 그 후 "j.doe@example.com"에 대한 인증 세레모니(Authentication ceremony)를 성공적으로 시작하면, 공격자는 "j.doe@example.com"은 등록되었고 "alex.mueller@example.com"은 등록되지 않았다고 결론을 내릴 수 있습니다. 따라서 신뢰 당사자(Relying Party)는 "j.doe@example.com"이 이 신뢰 당사자(Relying Party)사용자 계정(user account)을 가지고 있다는 잠재적으로 민감한 정보를 유출한 것입니다.

다음은 신뢰 당사자(Relying Party)가 구현하여 이러한 공격으로 인한 정보 유출을 완화하거나 방지할 수 있는 조치에 대한 비규범적이고 완전하지 않은 목록입니다.

14.6.3. 자격 증명 ID를 통한 개인 정보 유출(Privacy leak via credential IDs)

이 섹션은 규범적이지 않습니다.

이 개인 정보 보호 고려 사항은 첫 번째 인증 단계로 비어있지 않은(non-empty) allowCredentials 인자를 사용하여 인증 세레모니(Authentication ceremonies)를 지원하는 신뢰 당사자(Relying Parties)에게 적용됩니다. 예를 들어, 첫 번째 인증 단계로 서버 측 자격 증명(server-side credentials)을 사용하는 인증의 경우입니다.

이 경우 allowCredentials 인자는 인증되지 않은 호출자에게 사용자의 자격 증명 ID(credential IDs)를 노출하므로 개인 식별 정보를 유출할 위험이 있습니다. 자격 증명 ID(Credential IDs)신뢰 당사자(Relying Parties) 간에 상관 관계를 맺을 수 없도록 설계되었지만, 자격 증명 ID(credential ID)의 길이는 어떤 유형의 인증기(authenticator)가 이를 생성했는지에 대한 힌트가 될 수 있습니다. 사용자는 여러 신뢰 당사자(Relying Parties)에 대해 동일한 사용자 이름 및 인증기(authenticators) 세트를 사용할 가능성이 높으므로, allowCredentials자격 증명 ID(credential IDs) 수와 그 길이는 사용자의 익명화를 해제하는 전역 상관 관계 핸들로 작용할 수 있습니다. 사용자의 자격 증명 ID(credential IDs)를 알면 사용자의 인증기(authenticators) 중 하나에 대한 일시적인 물리적 액세스만으로도 사용자의 신원에 대한 추측을 확인할 수 있습니다.

이러한 정보 유출을 방지하기 위해 신뢰 당사자(Relying Party)는 예를 들어 다음을 수행할 수 있습니다.

위의 예방 조치를 사용할 수 없는 경우, 즉 사용자 이름만으로 allowCredentials를 노출해야 하는 경우, 신뢰 당사자(Relying Party)§ 14.6.2 사용자 이름 열거(Username Enumeration)에서 논의된 것과 같이 가상의 자격 증명 ID(credential IDs)를 반환하는 동일한 접근 방식을 사용하여 개인 정보 유출을 완화할 수 있습니다.

자격 증명 ID(credential id)가 인식되지 않았음을 신호(signalling)할 때, WebAuthn 신뢰 당사자(WebAuthn Relying Party)는 인증되지 않은 호출자에게 자격 증명 ID(credential IDs)를 노출하는 것을 피하기 위해 signalAllAcceptedCredentials(options) 메서드 대신 signalUnknownCredential(options) 메서드를 사용해야 합니다(SHOULD).

15. 접근성 고려 사항

사용자 검증이 가능한 인증기는, 로밍이든 플랫폼이든, 사용자에게 둘 이상의 사용자 검증 방법을 제공해야 합니다. 예를 들어, 지문 인식과 핀(PIN) 입력 모두를 제공할 수 있습니다. 이렇게 하면 선택한 방법이 어떤 이유로 작동하지 않을 경우 다른 사용자 검증 수단으로 대체할 수 있습니다. 로밍 인증기의 경우 인증기와 플랫폼이 함께 작동하여 핀(PIN) 입력과 같은 사용자 검증 방법을 제공할 수도 있다는 점에 유의하세요 [FIDO-CTAP].

신뢰 당사자등록 시점에 사용자가 향후 인가 제스처를 올바르게 완료할 수 있도록 배려해야 합니다. 예를 들어, 인증기에 이름을 지정하거나, 장치에 연결할 사진을 선택하거나, 자유 형식의 텍스트 설명을 입력(예: 자기 자신을 위한 메모)하는 것 등이 해당될 수 있습니다.

의식이 타이밍에 의존하는 경우, 예: 등록 의식 (참고 timeout) 또는 인증 의식 (참고 timeout)의 경우, [WCAG21]지침 2.2 충분한 시간을 따라야 합니다. 클라이언트 플랫폼신뢰 당사자가 제공한 타임아웃이 위 [WCAG21] 지침을 적절히 따르지 않는다고 판단되면, 클라이언트 플랫폼은 타임아웃을 적절히 조정할 수 있습니다.

WebAuthn 의식 타임아웃에 대한 권장 범위 및 기본값은 다음과 같습니다:

  • 권장 범위: 300000 밀리초 ~ 600000 밀리초.

  • 권장 기본값: 300000 밀리초 (5분).

16. 테스트 벡터

이 섹션은 규범적(normative)이지 않습니다.

이 섹션은 구현 검증에 사용할 수 있는 예시 값을 나열합니다.

예시는 같은 등록인증 절차 쌍으로 의사코드(pseudocode)로 제시하며, 동일한 자격증명(credential)에 대해 작성됩니다. 바이트 문자열 리터럴과 주석은 CDDL [RFC8610] 표기법으로 표기합니다. 이 예시들은 포괄적이지 않으며 WebAuthn 확장을 포함하지 않습니다.

각 예시는 입력에서 출력까지의 흐름으로 구성되어 있으며, 일부 중간값도 포함하고 있습니다. 등록 예시에서 Relying Partychallenge 입력값을 정의하고, 클라이언트clientDataJSON 출력을 생성하며, 인증자(Authenticator)attestationObject 출력을 생성합니다. 인증 예시에서는 Relying Partychallenge 입력값을 정의하고, 클라이언트clientDataJSON 출력을 생성하며, 인증자(Authenticator)authenticatorDatasignature 출력을 생성합니다. 이외의 암호상 상관없는 입력 및 출력은 생략합니다.

인증자(Authenticator) 구현자는 자신들이 다음과 같이 구조화된 attestationObject, authenticatorDatasignature 출력을 생성하는지 확인할 수 있습니다. 클라이언트 구현자는 clientDataJSON 과 같은 구조의 출력을 생성하는지 확인할 수 있습니다. Relying Party 구현자는 동일한 challenge 입력값이 주어졌을 때 등록 출력을 검증할 수 있는지, 동일한 challenge 입력값 및 등록 예시에서 파생된 credential public keycredential ID로 인증 출력을 검증할 수 있는지 확인할 수 있습니다.

모든 예시는 RP ID example.org, origin https://example.org 그리고 필요한 경우 topOrigin https://example.com을 사용합니다. 명시되지 않는 이상 attestation 없음을 포함합니다. clientDataJSON, attestationObject 및 attestation certificate 같은 복합 객체는 의사코드에 명시되지 않은 추가(일반적으로 상수) 데이터가 포함될 수 있습니다.

모든 난수 값은 HKDF-SHA-256 [RFC5869] 를 사용해 CDDL에서 'WebAuthn test vectors'로 표시된 기본 입력 키 자료, 또는 h’576562417574686e207465737420766563746f7273'과 동일한 자료에서 결정적으로 생성됩니다. ECDSA 서명은 결정적 nonce [RFC6979] 를 사용합니다. 예시의 RSA 키는 p ≥ 1024인 두 개의 가장 작은 Mersenne 소수 2p - 1로 구성됩니다.

참고:

Note: CTAP2를 구현한 인증자는 [FIDO-CTAP]에 따라 이 명세와는 다른 키를 사용하여 attestation object 를 반환할 수 있습니다. 여기 예시는 WebAuthn Relying Party가 기대하는 포맷을 따릅니다. 따라서 CTAP2에서 생성된 attestation object는 비트 단위로 일치하도록 키 변환이 필요할 수 있습니다.

16.1. Attestation 신뢰 루트 인증서

attestation을 포함하는 모든 예시는 아래에 attestation_ca_cert로 제시된 attestation 신뢰 루트 인증서를 사용하며, 이는 X.509 DER [RFC5280]로 인코딩되어 있습니다:

attestation_ca_key = h'7809337f05740a96a78eedf9e9280499dcc8f2aa129616049ec1dccfe103eb2a'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='Attestation CA', L=32)
attestation_ca_serial_number = h'ed7f905d8bd0b414d1784913170a90b6'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='Attestation CA', L=16)
attestation_ca_cert = h'30820207308201ada003020102021100ed7f905d8bd0b414d1784913170a90b6300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a3062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d030107034200043269300e5ff7b699015f70cf80a8763bf705bc2e2af0c1b39cff718b7c35880ca30f319078d91b03389a006fdfc8a1dcd84edfa07d30aa13474a248a0dab5baaa3423040300f0603551d130101ff040530030101ff300e0603551d0f0101ff040403020106301d0603551d0e0416041445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d04030203480030450220483063b6bb08dcc83da33a02c11d2f42203176893554d138c614a36908724cc8022100f5ef2c912d4500b3e2f5b591d0622491e9f220dfd1f9734ec484bb7e90887663'

16.2. attestation 없는 ES256 자격증명

등록:

challenge = h'00c30fb78531c464d2b6771dab8d7b603c01162f2fa486bea70f283ae556e130'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='none.ES256', L=32)

credential_private_key = h'6e68e7a58484a3264f66b77f5d6dc5bc36a47085b615c9727ab334e8c369c2ee'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='none.ES256', L=32)
client_data_gen_flags = h'f9'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='none.ES256', L=1)
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
extraData_random = h'06441e0e375c4c1ad70620302532c4e5' = b64'BkQeDjdcTBrXBiAwJTLE5Q'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='none.ES256', L=16)
aaguid = h'8446ccb9ab1db374750b2367ff6f3a1f'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='none.ES256', L=16)
credential_id = h'f91f391db4c9b2fde0ea70189cba3fb63f579ba6122b33ad94ff3ec330084be4'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='none.ES256', L=32)>
; auth_data_UV_BE_BS는 인증자 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만, BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'ba'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='none.ES256', L=1)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22414d4d507434557878475453746e63647134313759447742466938767049612d7077386f4f755657345441222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20426b5165446a646354427258426941774a544c453551227d'
attestationObject = h'a363666d74646e6f6e656761747453746d74a068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b559000000008446ccb9ab1db374750b2367ff6f3a1f0020f91f391db4c9b2fde0ea70189cba3fb63f579ba6122b33ad94ff3ec330084be4a5010203262001215820afefa16f97ca9b2d23eb86ccb64098d20db90856062eb249c33a9b672f26df61225820930a56b87a2fca66334b03458abf879717c12cc68ed73290af2e2664796b9220'

인증:

challenge = h'39c0e7521417ba54d43e8dc95174f423dee9bf3cd804ff6d65c857c9abf4d408'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='none.ES256', L=32)

client_data_gen_flags = h'4a'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='none.ES256', L=1)
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
; auth_data_UV_BS는 인증자 데이터 플래그의 UV 및 BS 비트를 설정하지만, BS는 등록 시 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BS = h'38'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='none.ES256', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b51900000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a224f63446e55685158756c5455506f334a5558543049393770767a7a59425039745a63685879617630314167222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
signature = h'3046022100f50a4e2e4409249c4a853ba361282f09841df4dd4547a13a87780218deffcd380221008480ac0f0b93538174f575bf11a1dd5d78c6e486013f937295ea13653e331e87'

16.3. 자기 증명(Self Attestation)을 사용한 ES256 자격증명

등록:

challenge = h'7869c2b772d4b58eba9378cf8f29e26cf935aa77df0da89fa99c0bdc0a76f7e5'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='packed-self.ES256', L=32)

credential_private_key = h'b4bbfa5d68e1693b6ef5a19a0e60ef7ee2cbcac81f7fec7006ac3a21e0c5116a'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='packed-self.ES256', L=32)
client_data_gen_flags = h'db'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='packed-self.ES256', L=1)
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
extraData_random = h'53d8535ef284d944643276ffd3160756' = b64'U9hTXvKE2URkMnb_0xYHVg'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='packed-self.ES256', L=16)
aaguid = h'df850e09db6afbdfab51697791506cfc'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='packed-self.ES256', L=16)
credential_id = h'455ef34e2043a87db3d4afeb39bbcb6cc32df9347c789a865ecdca129cbef58c'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='packed-self.ES256', L=32)>
; auth_data_UV_BE_BS는 인증자 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만, BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'fd'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='packed-self.ES256', L=1)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a2265476e4374334c55745936366b336a506a796e6962506b31716e666644616966715a774c33417032392d55222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a205539685458764b453255526b4d6e625f307859485667227d'
attestationObject = h'a363666d74667061636b65646761747453746d74a263616c672663736967584630440220067a20754ab925005dbf378097c92120031581c73228d1fb4f5b881bcd7da98302207fc7b147558c7c0eba3af18bd9d121fa3d3a26d17fe3f220272178f473b6006d68617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b55d00000000df850e09db6afbdfab51697791506cfc0020455ef34e2043a87db3d4afeb39bbcb6cc32df9347c789a865ecdca129cbef58ca5010203262001215820eb151c8176b225cc651559fecf07af450fd85802046656b34c18f6cf193843c5225820927b8aa427a2be1b8834d233a2d34f61f13bfd44119c325d5896e183fee484f2'

인증:

challenge = h'4478a10b1352348dd160c1353b0d469b5db19eb91c27f7dfa6fed39fe26af20b'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='packed-self.ES256', L=32)

client_data_gen_flags = h'1f'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='packed-self.ES256', L=1)
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
extraData_random = h'8136f9debcfa121496a265c6ce2982d5' = b64'gTb53rz6EhSWomXGzimC1Q'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='packed-self.ES256', L=16)
; auth_data_UV_BS는 등록 시 BE가 설정된 경우에만 BS가 설정된다는 조건 하에 인증자 데이터 플래그의 UV 및 BS 비트를 설정합니다
auth_data_UV_BS = h'a1'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0a', info='packed-self.ES256', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50900000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a225248696843784e534e493352594d45314f7731476d3132786e726b634a5f6666707637546e2d4a71386773222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a206754623533727a36456853576f6d58477a696d433151227d'
signature = h'304402203310b9431903c401f1be2bdc8d23a4007682dbbddcf846994947b7f465daf84002204e94dd00047b316061b3b99772b7efd95994a83ef584b3b6b825ea3550251b66'

16.4. clientDataJSON에 "crossOrigin": true를 포함한 ES256 자격증명

등록:

challenge = h'3be5aacd03537142472340ab5969f240f1d87716e20b6807ac230655fa4b3b49'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='none.ES256.crossOrigin', L=32)

credential_private_key = h'96c940e769bd9f1237c119f144fa61a4d56af0b3289685ae2bef7fb89620623d'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='none.ES256.crossOrigin', L=32)>
client_data_gen_flags = h'71'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='none.ES256.crossOrigin', L=1)
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
extraData_random = h'cd9aae12d0d1f435aaa56e6d0564c5ba' = b64'zZquEtDR9DWqpW5tBWTFug'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='none.ES256.crossOrigin', L=16)
aaguid = h'883f4f6014f19c09d87aa38123be48d0'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='none.ES256.crossOrigin', L=16)
credential_id = h'6e1050c0d2ca2f07c755cb2c66a74c64fa43065c18f938354d9915db2bd5ce57'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='none.ES256.crossOrigin', L=32)>
; auth_data_UV_BE_BS는 인증자 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만, BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'27'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='none.ES256.crossOrigin', L=1)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a224f2d57717a514e5463554a484930437257576e7951504859647862694332674872434d475666704c4f306b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a207a5a7175457444523944577170573574425754467567227d'
attestationObject = h'a363666d74646e6f6e656761747453746d74a068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54500000000883f4f6014f19c09d87aa38123be48d000206e1050c0d2ca2f07c755cb2c66a74c64fa43065c18f938354d9915db2bd5ce57a501020326200121582022200a473f90b11078851550d03b4e44a2279f8c4eca27b3153dedfe03e4e97d225820cbd0be95e746ad6f5a8191be11756e4c0420e72f65b466d39bc56b8b123a9c6e'

인증:

challenge = h'876aa517ba83fdee65fcffdbca4c84eeae5d54f8041a1fc85c991e5bbb273137'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='none.ES256.crossOrigin', L=32)

client_data_gen_flags = h'57'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='none.ES256.crossOrigin', L=1)
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
extraData_random = h'f76a5c4d50f401bcbeab876d9a3e9e7e' = b64'92pcTVD0Aby-q4dtmj6efg'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='none.ES256.crossOrigin', L=16)
; auth_data_UV_BS는 등록 시 BE가 설정된 경우에만 BS가 설정된다는 조건 하에 인증자 데이터 플래그의 UV 및 BS 비트를 설정합니다
auth_data_UV_BS = h'0c'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0a', info='none.ES256.crossOrigin', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50500000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a226832716c463771445f65356c5f505f62796b7945377135645650674547685f49584a6b655737736e4d5463222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a2039327063545644304162792d713464746d6a36656667227d'
signature = h'3046022100eb12fcf23b12764c0f122e22371fab92e283879fd798f38ee1841c951b6e40e7022100c76237ff9db77b3c56f30837cda6a09acfa2e915544e609c0733b1184036d1cf'

16.5. clientDataJSON에 "topOrigin"을 포함한 ES256 자격증명

등록:

challenge = h'4e1f4c6198699e33c14f192153f49d7e0e8e3577d5ac416c5f3adc92a41f27e5'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='none.ES256.topOrigin', L=32)

credential_private_key = h'a2d6de40ab974b80d8c1ef78c6d4300097754f7e016afe7f8ea0ad9798b0d420'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='none.ES256.topOrigin', L=32)>
client_data_gen_flags = h'54'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='none.ES256.topOrigin', L=1)
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
aaguid = h'97586fd09799a76401c200455099ef2a'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='none.ES256.topOrigin', L=16)
credential_id = h'b8ad59b996047ab18e2ceb57206c362da57458793481f4a8ebf101c7ca7cc0f1'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='none.ES256.topOrigin', L=32)>
; auth_data_UV_BE_BS는 인증자 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만, BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'a0'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='none.ES256.topOrigin', L=1)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a225468394d595a68706e6a504254786b68555f53646667364f4e58665672454673587a72636b7151664a2d55222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22746f704f726967696e223a2268747470733a2f2f6578616d706c652e636f6d227d'
attestationObject = h'a363666d74646e6f6e656761747453746d74a068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b5410000000097586fd09799a76401c200455099ef2a0020b8ad59b996047ab18e2ceb57206c362da57458793481f4a8ebf101c7ca7cc0f1a5010203262001215820a1c47c1d82da4ebe82cd72207102b380670701993bc35398ae2e5726427fe01d22582086c1080d82987028c7f54ecb1b01185de243b359294a0ed210cd47480f0adc88'

인증:

challenge = h'd54a5c8ca4b62a8e3bb321e3b2bc73856f85a10150db2939ac195739eb1ea066'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='none.ES256.topOrigin', L=32)

client_data_gen_flags = h'77'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='none.ES256.topOrigin', L=1)
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
extraData_random = h'52216824c5514070c0156162e2fc54a5' = b64'UiFoJMVRQHDAFWFi4vxUpQ'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='none.ES256.topOrigin', L=16)
; auth_data_UV_BS는 등록 시 BE가 설정된 경우에만 BS가 설정된다는 조건 하에 인증자 데이터 플래그의 UV 및 BS 비트를 설정합니다
auth_data_UV_BS = h'9f'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='none.ES256.topOrigin', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50500000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22315570636a4b53324b6f34377379486a7372787a68572d466f51465132796b3572426c584f6573656f4759222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22746f704f726967696e223a2268747470733a2f2f6578616d706c652e636f6d222c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a205569466f4a4d56525148444146574669347678557051227d'
signature = h'3045022100b5a70c81780d5fcc9a4f2ae9caae99058f8accaf58b91fb59329646c28ac6ffc022012e101c165db3c8e9957f0c54dd6ca9b56bc3bd2f280bd2faa6c1d02c6e5c171'

16.6. 매우 긴 credential ID를 가진 ES256 자격증명

등록:

challenge = h'1113c7265ccf5e65124282fa1d7819a7a14cb8539aa4cdbec7487e5f35d8ec6c'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='none.ES256.long-credential-id', L=32)

credential_private_key = h'6fd2149bb5f1597fe549b138794bde61893b2dc32ca316de65f04808dac211dc'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='none.ES256.long-credential-id', L=32)>
client_data_gen_flags = h'90'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='none.ES256.long-credential-id', L=1)
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
aaguid = h'8f3360c2cd1b0ac14ffe0795c5d2638e'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='none.ES256.long-credential-id', L=16)
credential_id = h'3a761a4e1674ad6c4305869435c0eee9c286172c229bb91b48b4ada140c0863417031305cce5b4a27a88d7fe728a5f5a627de771b4b40e77f187980c124f9fe832d7136010436a056cce716680587d23187cf1fc2c62ae86fc3e508ee9617ffc74fbc10488ec16ec5e9096328669a898709b655e549738c666c1ae6281dc3b5f733c251d3eefb76ee70a3805ca91bcc18e49c8dc7f63ebcb486ba8c3d6ab52b88ff72c6a5bb47c32f3ee8683a3ddc8abf60870448ec8a21b5bdcb183c7dead870255575a6df96eb1b6a2a1019780cba9e4887b17ff1164bbbcc10eb0d86ed75984cd3fa3419103024507dfd9ce8f92c56af7914cb0bb50b87ba82a312bb7dcd93028dbdcd6adb266979667158335171e3682d37755701edbf9d872846a291d49e57ef09da1ec637f5052ed2aa7407f7e61827468e94b461844f4c67be5fa9c6055a566f8fdfc29d4bf78a9ff275f552cc68ba543fa3962eea36fd1ea8453764577d021d0a181efc1f6100ab2e4110039e21ee16970bda7432b6134492155afc126295b3a2eccd12c66a68e340969e995e3e8c9c476e395cfc21203414110779474f1c9797406637dbe414f132519d3bf0ce4f01734ef0e1a12c3ad604ff15d766b1624db6a5a7ccbff7bc35c9908df94aba277e0af48f04ff3d16381c47e5a37ed3988a67a3b1ecaa926336b33391fff04128f869991c9fabd905b6fe3ceef5f8b630ec1c5d2636d5b1961ad5ca5004170f6f5e482792aad989b0287fe91e5c479403397152f1fa56aa79b156eb47e6c8ea3eb175c34cfb38ad8e772874639b1023d4d01395c94e55831671cc022aa6fa1e02a02c2e4abc776f6960e51f83b71a8c0f207b6a347573977812c9aa5480b0011aa739bd4b76c18c000cc4757cceccb920f007c40c00e37e5ab21476cd9f6054a8fffb55a108f5c706e2cea2049d81fd321ff47d2a5761b0800955ab1d4f4889f55a84e2601c684f17a4ade7453ea49591d0b59c8d9a765052f62219cf6ef4a5dd9539f0617d6ebbebce7c000455475d18449e25c49ef9a1e3efe18c09082ebe2058d7c347defaa92f0664553b805c7d76bbfce5f330aca220ac90a789380fc479ea0d8793205813cca590a912f699ad52f991a1bc0a503c3ec4b2a696719e3c26591a87127f7305cc7e72f4c8e39355ebb06a5b1042990f38710ee7aa612ee4374bb82e878585a70a96c2a6b47f101a4ff154be4fd76a3167577a5cc54d9167c154c69ac35485e44cc898b719e1be3cc9c0fb5624b8f8a0dae10947a41bf848b6c1bb33d1006ec077d7e286e3f2a7b4843716390119449fe2721e81a5ed2333d331c7120765da58fadae73c19d9a8c4509cf8ac1e9d98b799a5274509069739b5823f3fb496663820033426988eefca53e580e0f9e0dfe0992fc2e53a97e053639f98577058f995bdbd41cefdb'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='none.ES256.long-credential-id', L=1023)>
; auth_data_UV_BE_BS는 인증자 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만, BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'69'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='none.ES256.long-credential-id', L=1)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22455250484a6c7a50586d5553516f4c364858675a7036464d75464f61704d322d7830682d587a5859374777222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
attestationObject = h'a363666d74646e6f6e656761747453746d74a0686175746844617461590483bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b549000000008f3360c2cd1b0ac14ffe0795c5d2638e03ff3a761a4e1674ad6c4305869435c0eee9c286172c229bb91b48b4ada140c0863417031305cce5b4a27a88d7fe728a5f5a627de771b4b40e77f187980c124f9fe832d7136010436a056cce716680587d23187cf1fc2c62ae86fc3e508ee9617ffc74fbc10488ec16ec5e9096328669a898709b655e549738c666c1ae6281dc3b5f733c251d3eefb76ee70a3805ca91bcc18e49c8dc7f63ebcb486ba8c3d6ab52b88ff72c6a5bb47c32f3ee8683a3ddc8abf60870448ec8a21b5bdcb183c7dead870255575a6df96eb1b6a2a1019780cba9e4887b17ff1164bbbcc10eb0d86ed75984cd3fa3419103024507dfd9ce8f92c56af7914cb0bb50b87ba82a312bb7dcd93028dbdcd6adb266979667158335171e3682d37755701edbf9d872846a291d49e57ef09da1ec637f5052ed2aa7407f7e61827468e94b461844f4c67be5fa9c6055a566f8fdfc29d4bf78a9ff275f552cc68ba543fa3962eea36fd1ea8453764577d021d0a181efc1f6100ab2e4110039e21ee16970bda7432b6134492155afc126295b3a2eccd12c66a68e340969e995e3e8c9c476e395cfc21203414110779474f1c9797406637dbe414f132519d3bf0ce4f01734ef0e1a12c3ad604ff15d766b1624db6a5a7ccbff7bc35c9908df94aba277e0af48f04ff3d16381c47e5a37ed3988a67a3b1ecaa926336b33391fff04128f869991c9fabd905b6fe3ceef5f8b630ec1c5d2636d5b1961ad5ca5004170f6f5e482792aad989b0287fe91e5c479403397152f1fa56aa79b156eb47e6c8ea3eb175c34cfb38ad8e772874639b1023d4d01395c94e55831671cc022aa6fa1e02a02c2e4abc776f6960e51f83b71a8c0f207b6a347573977812c9aa5480b0011aa739bd4b76c18c000cc4757cceccb920f007c40c00e37e5ab21476cd9f6054a8fffb55a108f5c706e2cea2049d81fd321ff47d2a5761b0800955ab1d4f4889f55a84e2601c684f17a4ade7453ea49591d0b59c8d9a765052f62219cf6ef4a5dd9539f0617d6ebbebce7c000455475d18449e25c49ef9a1e3efe18c09082ebe2058d7c347defaa92f0664553b805c7d76bbfce5f330aca220ac90a789380fc479ea0d8793205813cca590a912f699ad52f991a1bc0a503c3ec4b2a696719e3c26591a87127f7305cc7e72f4c8e39355ebb06a5b1042990f38710ee7aa612ee4374bb82e878585a70a96c2a6b47f101a4ff154be4fd76a3167577a5cc54d9167c154c69ac35485e44cc898b719e1be3cc9c0fb5624b8f8a0dae10947a41bf848b6c1bb33d1006ec077d7e286e3f2a7b4843716390119449fe2721e81a5ed2333d331c7120765da58fadae73c19d9a8c4509cf8ac1e9d98b799a5274509069739b5823f3fb496663820033426988eefca53e580e0f9e0dfe0992fc2e53a97e053639f98577058f995bdbd41cefdba50102032620012158203b8176b7504489cc593046d7988abb7905a742de6ac2cdc748a873c663e90cb12258201436d5edc9a75f23999eef9d5950a5c2455514ee1014084720f841a06b828a11'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='none.ES256.long-credential-id', L=1023)>
; auth_data_UV_BE_BS는 인증자 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만, BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'69'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='none.ES256.long-credential-id', L=1)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22455250484a6c7a50586d5553516f4c364858675a7036464d75464f61704d322d7830682d587a5859374777222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
attestationObject = h'a363666d74646e6f6e656761747453746d74a0686175746844617461590483bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b549000000008f3360c2cd1b0ac14ffe0795c5d2638e03ff3a761a4e1674ad6c4305869435c0eee9c286172c229bb91b48b4ada140c0863417031305cce5b4a27a88d7fe728a5f5a627de771b4b40e77f187980c124f9fe832d7136010436a056cce716680587d23187cf1fc2c62ae86fc3e508ee9617ffc74fbc10488ec16ec5e9096328669a898709b655e549738c666c1ae6281dc3b5f733c251d3eefb76ee70a3805ca91bcc18e49c8dc7f63ebcb486ba8c3d6ab52b88ff72c6a5bb47c32f3ee8683a3ddc8abf60870448ec8a21b5bdcb183c7dead870255575a6df96eb1b6a2a1019780cba9e4887b17ff1164bbbcc10eb0d86ed75984cd3fa3419103024507dfd9ce8f92c56af7914cb0bb50b87ba82a312bb7dcd93028dbdcd6adb266979667158335171e3682d37755701edbf9d872846a291d49e57ef09da1ec637f5052ed2aa7407f7e61827468e94b461844f4c67be5fa9c6055a566f8fdfc29d4bf78a9ff275f552cc68ba543fa3962eea36fd1ea8453764577d021d0a181efc1f6100ab2e4110039e21ee16970bda7432b6134492155afc126295b3a2eccd12c66a68e340969e995e3e8c9c476e395cfc21203414110779474f1c9797406637dbe414f132519d3bf0ce4f01734ef0e1a12c3ad604ff15d766b1624db6a5a7ccbff7bc35c9908df94aba277e0af48f04ff3d16381c47e5a37ed3988a67a3b1ecaa926336b33391fff04128f869991c9fabd905b6fe3ceef5f8b630ec1c5d2636d5b1961ad5ca5004170f6f5e482792aad989b0287fe91e5c479403397152f1fa56aa79b156eb47e6c8ea3eb175c34cfb38ad8e772874639b1023d4d01395c94e55831671cc022aa6fa1e02a02c2e4abc776f6960e51f83b71a8c0f207b6a347573977812c9aa5480b0011aa739bd4b76c18c000cc4757cceccb920f007c40c00e37e5ab21476cd9f6054a8fffb55a108f5c706e2cea2049d81fd321ff47d2a5761b0800955ab1d4f4889f55a84e2601c684f17a4ade7453ea49591d0b59c8d9a765052f62219cf6ef4a5dd9539f0617d6ebbebce7c000455475d18449e25c49ef9a1e3efe18c09082ebe2058d7c347defaa92f0664553b805c7d76bbfce5f330aca220ac90a789380fc479ea0d8793205813cca590a912f699ad52f991a1bc0a503c3ec4b2a696719e3c26591a87127f7305cc7e72f4c8e39355ebb06a5b1042990f38710ee7aa612ee4374bb82e878585a70a96c2a6b47f101a4ff154be4fd76a3167577a5cc54d9167c154c69ac35485e44cc898b719e1be3cc9c0fb5624b8f8a0dae10947a41bf848b6c1bb33d1006ec077d7e286e3f2a7b4843716390119449fe2721e81a5ed2333d331c7120765da58fadae73c19d9a8c4509cf8ac1e9d98b799a5274509069739b5823f3fb496663820033426988eefca53e580e0f9e0dfe0992fc2e53a97e053639f98577058f995bdbd41cefdba50102032620012158203b8176b7504489cc593046d7988abb7905a742de6ac2cdc748a873c663e90cb12258201436d5edc9a75f23999eef9d5950a5c2455514ee1014084720f841a06b828a11'>
; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='none.ES256.long-credential-id', L=1023)>
; auth_data_UV_BE_BS는 인증자 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만, BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'69'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='none.ES256.long-credential-id', L=1)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22455250484a6c7a50586d5553516f4c364858675a7036464d75464f61704d322d7830682d587a5859374777222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
attestationObject = h'a363666d74646e6f6e656761747453746d74a0686175746844617461590483bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b549000000008f3360c2cd1b0ac14ffe0795c5d2638e03ff3a761a4e1674ad6c4305869435c0eee9c286172c229bb91b48b4ada140c0863417031305cce5b4a27a88d7fe728a5f5a627de771b4b40e77f187980c124f9fe832d7136010436a056cce716680587d23187cf1fc2c62ae86fc3e508ee9617ffc74fbc10488ec16ec5e9096328669a898709b655e549738c666c1ae6281dc3b5f733c251d3eefb76ee70a3805ca91bcc18e49c8dc7f63ebcb486ba8c3d6ab52b88ff72c6a5bb47c32f3ee8683a3ddc8abf60870448ec8a21b5bdcb183c7dead870255575a6df96eb1b6a2a1019780cba9e4887b17ff1164bbbcc10eb0d86ed75984cd3fa3419103024507dfd9ce8f92c56af7914cb0bb50b87ba82a312bb7dcd93028dbdcd6adb266979667158335171e3682d37755701edbf9d872846a291d49e57ef09da1ec637f5052ed2aa7407f7e61827468e94b461844f4c67be5fa9c6055a566f8fdfc29d4bf78a9ff275f552cc68ba543fa3962eea36fd1ea8453764577d021d0a181efc1f6100ab2e4110039e21ee16970bda7432b6134492155afc126295b3a2eccd12c66a68e340969e995e3e8c9c476e395cfc21203414110779474f1c9797406637dbe414f132519d3bf0ce4f01734ef0e1a12c3ad604ff15d766b1624db6a5a7ccbff7bc35c9908df94aba277e0af48f04ff3d16381c47e5a37ed3988a67a3b1ecaa926336b33391fff04128f869991c9fabd905b6fe3ceef5f8b630ec1c5d2636d5b1961ad5ca5004170f6f5e482792aad989b0287fe91e5c479403397152f1fa56aa79b156eb47e6c8ea3eb175c34cfb38ad8e772874639b1023d4d01395c94e55831671cc022aa6fa1e02a02c2e4abc776f6960e51f83b71a8c0f207b6a347573977812c9aa5480b0011aa739bd4b76c18c000cc4757cceccb920f007c40c00e37e5ab21476cd9f6054a8fffb55a108f5c706e2cea2049d81fd321ff47d2a5761b0800955ab1d4f4889f55a84e2601c684f17a4ade7453ea49591d0b59c8d9a765052f62219cf6ef4a5dd9539f0617d6ebbebce7c000455475d18449e25c49ef9a1e3efe18c09082ebe2058d7c347defaa92f0664553b805c7d76bbfce5f330aca220ac90a789380fc479ea0d8793205813cca590a912f699ad52f991a1bc0a503c3ec4b2a696719e3c26591a87127f7305cc7e72f4c8e39355ebb06a5b1042990f38710ee7aa612ee4374bb82e878585a70a96c2a6b47f101a4ff154be4fd76a3167577a5cc54d9167c154c69ac35485e44cc898b719e1be3cc9c0fb5624b8f8a0dae10947a41bf848b6c1bb33d1006ec077d7e286e3f2a7b4843716390119449fe2721e81a5ed2333d331c7120765da58fadae73c19d9a8c4509cf8ac1e9d98b799a5274509069739b5823f3fb496663820033426988eefca53e580e0f9e0dfe0992fc2e53a97e053639f98577058f995bdbd41cefdba50102032620012158203b8176b7504489cc593046d7988abb7905a742de6ac2cdc748a873c663e90cb12258201436d5edc9a75f23999eef9d5950a5c2455514ee1014084720f841a06b828a11'>
; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='none.ES256.long-credential-id', L=32)>
client_data_gen_flags = h'80'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='none.ES256.long-credential-id', L=1)>
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
; auth_data_UV_BS는 등록 시 BE가 설정된 경우에만 BS가 설정된다는 조건 하에 인증자 데이터 플래그의 UV 및 BS 비트를 설정합니다
auth_data_UV_BS = h'e5'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='none.ES256.long-credential-id', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50d00000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22377833727057334f53505a307045664d396a75566d53574d36485a4935634f573875384d6f647047446a73222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
signature = h'304502203ecef83fb12a0cae7841055f9f87103a99fd14b424194bbf06c4623d3ee6e3fd022100d2ace346db262b1374a6b70faa51f518a42ddca13a4125ce6f5052a75bac9fb6'

16.7. Packed attestation을 사용한 ES256 자격증명

등록:

challenge = h'c1184a5fddf8045e13dc47f54b61f5a656b666b59018f16d870e9256e9952012'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='packed.ES256', L=32)

credential_private_key = h'36ed7bea2357cefa8c4ec7e134f3312d2e6ca3058519d0bcb4c1424272010432'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='packed.ES256', L=32)>
client_data_gen_flags = h'8d'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='packed.ES256', L=1)
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
extraData_random = h'f5af1b3588ca0a05ab05753e7c29756a' = b64'9a8bNYjKCgWrBXU-fCl1ag'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='packed.ES256', L=16)
aaguid = h'876ca4f52071c3e9b25509ef2cdf7ed6'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='packed.ES256', L=16)
credential_id = h'c9a6f5b3462d02873fea0c56862234f99f081728084e511bb7760201a89054a5'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='packed.ES256', L=32)>
; auth_data_UV_BE_BS는 인증자 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만, BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'4f'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='packed.ES256', L=1)>
attestation_private_key = h'ec2804b222552b4b277d1f58f8c4343c0b0b0db5474eb55365c89d66a2bc96be'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='packed.ES256', L=32)>
attestation_cert_serial_number = h'88c220f83c8ef1feafe94deae45faad0'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='packed.ES256', L=16)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a227752684b58393334424634543345663153324831706c61325a725751475046746877365356756d56494249222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20396138624e596a4b436757724258552d66436c316167227d'
attestationObject = h'a363666d74667061636b65646761747453746d74a363616c6726637369675847304502203f19ec4b229f46ab8c45eff29b904ff10c0390dc40bf1216f04a78f4ceba3425022100fe7041a32759aff05a0f9f26c70a999c7a284451ba89234a1d3483c25e21925b637835638159022530820221308201c8a00302010202110088c220f83c8ef1feafe94deae45faad0300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d03010703420004a91ba4389409dd38a428141940ca8feb1ac0d7b4350558104a3777a49322f3798440f378b3398ab2d3bb7bf91322c92eb23556f59ad0a836fec4c7663b0e4dc3a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414a589ba72d060842ab11f74fb246bdedab16f9b9b301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d0403020348003045022041726b9d85ecd8a5ed51163722ca3a20886fd9b242a0aa0453d442116075defd502207ef471e530ac87961a88a7f0d0c17b091ffc6b9238d30f79f635b417be5910e768617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54d00000000876ca4f52071c3e9b25509ef2cdf7ed60020c9a6f5b3462d02873fea0c56862234f99f081728084e511bb7760201a89054a5a50102032620012158201cf27f25da591208a4239c2e324f104f585525479a29edeedd830f48e77aeae522582059e4b7da6c0106e206ce390c93ab98a15a5ec3887e57f0cc2bece803b920c423'

인증:

challenge = h'b1106fa46a57bef1781511c0557dc898a03413d5f0f17d244630c194c7e1adb5'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='packed.ES256', L=32)

client_data_gen_flags = h'75'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0a', info='packed.ES256', L=1)
; extraData는 client_data_gen_flags의 비트 0x01이 1일 때에만 clientDataJSON에 추가됩니다
extraData_random = h'019330c8cc486c3f3eba0b85369eabf1' = b64'AZMwyMxIbD8-uguFNp6r8Q'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0b', info='packed.ES256', L=16)
; auth_data_UV_BS는 등록 시 BE가 설정된 경우에만 BS가 설정된다는 조건 하에 인증자 데이터 플래그의 UV 및 BS 비트를 설정합니다
auth_data_UV_BS = h'46'   ; 파생: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0c', info='packed.ES256', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50d00000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a2273524276704770587676463446524841565833496d4b4130453958773858306b526a44426c4d6668726255222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20415a4d77794d78496244382d756775464e7036723851227d'
signature = h'30450220694969d3ee928de6f02ef23a9c644d7d779916451734a94b432542f498a1ebe90221008b0819c824218a97152cd099c55bfb1477b29d900a49a64018314f9bfccda163'

16.17. WebAuthn 확장용 테스트 벡터 (WebAuthn Extensions)

이 섹션은 WebAuthn 확장에 대한 예시 값을 나열합니다.

16.17.1. 의사 난수 함수 확장 (prf)

이 섹션은 의사 난수 함수(prf) 확장에 대한 예시 값을 나열합니다.

prf 확장은 CTAP2의 hmac-secret 확장 [FIDO-CTAP]과 통합되기 때문에, 예시는 두 부분으로 나뉩니다: WebAuthn 클라이언트 및 WebAuthn Relying Party와 관련된 WebAuthn prf 확장의 입력 및 출력 예시들; 그리고 WebAuthn prf 확장과 CTAP2의 hmac-secret 확장 간의 매핑 예시들로, 이는 WebAuthn 클라이언트와 WebAuthn 인증기(Authenticator)에 관련됩니다.

16.17.1.1. 웹 인증 API

다음 예시는 WebAuthn 클라이언트 구현과 WebAuthn Relying Partyprf 확장 사용을 테스트하는 데에 이용될 수 있습니다. 예시들은 포괄적이지 않습니다.

  • enabled 출력은 등록 절차 동안 항상 존재하며, 인증 절차 동안에는 결코 존재하지 않습니다:

    // Example extension inputs:
    { prf: { }
    
    // Example client extension outputs from navigator.credentials.create():
    { prf: { enabled: true } } }
    
    // Example client extension outputs from navigator.credentials.get():
    { prf: { } }
    
  • results 출력은 등록 절차 또는 인증 절차 중에 eval 또는 evalByCredential 입력이 존재하는 경우에 나타날 수 있습니다:

    // Example extension inputs:
    { prf: { eval: { first: new Uint8Array([1, 2, 3, 4]) } } }
    
    // Example client extension outputs from navigator.credentials.create():
    { prf: { enabled: true } }
    { prf: { enabled: false } }
    { prf: { enabled: true, results: { first: ArrayBuffer } } }
    
    // Example client extension outputs from navigator.credentials.get():
    { prf: { } }
    { prf: { results: { first: ArrayBuffer } } }
    
  • results.second 출력은 results 출력이 존재하고 선택된 PRF 입력에 second 입력이 포함되어 있었을 경우에 한해 존재합니다:

    // Example extension inputs:
    {
      prf: {
        eval: {
          first: new Uint8Array([1, 2, 3, 4]),
          second: new Uint8Array([5, 6, 7, 8]),
        },
        evalByCredential: {
          "e02eZ9lPp0UdkF4vGRO4-NxlhWBkL1FCmsmb1tTfRyE": {
            first: new Uint8Array([9, 10, 11, 12]),
          }
        }
      }
    }
    
    // Example client extension outputs from navigator.credentials.get() if credential "e02eZ9lP..." was used:
    { prf: { results: { first: ArrayBuffer } } }
    
    // Example client extension outputs from navigator.credentials.get() if a different credential was used:
    { prf: { } }
    { prf: { results: { first: ArrayBuffer, second: ArrayBuffer } } }
    
  • firstsecond 출력은 모든 BufferSource 타입이 될 수 있습니다. 동일한 firstsecond 입력은 동일한 firstsecond 출력을 초래합니다:

    // Example extension inputs:
    {
      prf: {
        evalByCredential: {
          "e02eZ9lPp0UdkF4vGRO4-NxlhWBkL1FCmsmb1tTfRyE": {
            first: new Uint8Array([9, 10, 11, 12]),
            second: new Uint8Array([9, 10, 11, 12])
          }
        }
      }
    }
    
    // Example client extension outputs from navigator.credentials.get():
    {
      prf: {
        results: {
          first: new Uint8Array([0xc4, 0x17, 0x2e, 0x98, 0x2e, 0x90, 0x97, 0xc3, 0x9a, 0x6c, 0x0c, 0xb7, 0x20, 0xcb, 0x37, 0x5b, 0x92, 0xe3, 0xfc, 0xad, 0x15, 0x4a, 0x63, 0xe4, 0x3a, 0x93, 0xf1, 0x09, 0x6b, 0x1e, 0x19, 0x73]),
          second: new Uint32Array([0x982e17c4, 0xc397902e, 0xb70c6c9a, 0x5b37cb20, 0xadfce392, 0xe4634a15, 0x09f1933a, 0x73191e6b]),
        }
      }
    }
    

이 섹션에서 사용된 의사 난수 값은 다음과 같이 생성되었습니다:

  • "e02eZ9lPp0UdkF4vGRO4-NxlhWBkL1FCmsmb1tTfRyE" = Base64Url(SHA-256(UTF-8("WebAuthn PRF test vectors") || 0x00))

  • h'c4172e982e9097c39a6c0cb720cb375b92e3fcad154a63e43a93f1096b1e1973' = SHA-256(UTF-8("WebAuthn PRF test vectors") || 0x01)

16.17.1.2. CTAP2 hmac-secret 확장

다음 예시는 WebAuthn 클라이언트 구현들이 prf 확장이 [FIDO-CTAP]hmac-secret 확장을 어떻게 사용하는지를 테스트하는 데 사용할 수 있습니다. 예시는 CDDL [RFC8610] 표기법으로 제시됩니다. 예시들은 포괄적이지 않습니다.

  • 다음에 나오는 공유 정의들은 이후 모든 예시에서 사용됩니다:

    ; Given input parameters:
    platform_key_agreement_private_key = 0x0971bc7fb1be48270adcd3d9a5fc15d5fb0f335b3071ff36a54c007fa6c76514
    authenticator_key_agreement_public_key = {
        1: 2,
        3: -25,
        -1: 1,
        -2: h'a30522c2de402b561965c3cf949a1cab020c6f6ea36fcf7e911ac1a0f1515300',
        -3: h'9961a929abdb2f42e6566771887d41484d889e735e3248518a53112d2b915f00',
    }
    authenticator_cred_random = h'437e065e723a98b2f08f39d8baf7c53ecb3c363c5e5104bdaaf5d5ca2e028154'
    

    firstsecond 입력은 예시에서 각각 prf_eval_firstprf_eval_second로 매핑됩니다. 예시의 prf_results_firstprf_results_second 값들은 각각 results.firstresults.second 출력으로 매핑됩니다.

  • PIN 프로토콜 2를 사용하는 단일 입력 사례:

    ; Inputs from Relying Party:
    prf_eval_first = h'576562417574686e20505246207465737420766563746f727302'
    
    ; Client computes:
    shared_secret = h'0c63083de8170101d38bcf8bd72309568ddb4550867e23404b35d85712f7c20d8bc911ee23c06034cbc14290b9669bec07739053c5a416e313ef905c79955876'
    salt1 = h'527413ebb48293772df30f031c5ac4650c7de14bf9498671ae163447b6a772b3'
    salt_enc = h'23dde5e3462daf36559b85c4ac5f9656aa9bfd81c1dc2bf8533c8b9f3882854786b4f500e25b4e3d81f7fc7c74236229'
    
    ; Authenticator computes:
    output1 = h'3c33e07d202c3b029cc21f1722767021bf27d595933b3d2b6a1b9d5dddc77fae'
    output_enc = h'3bfaa48f7952330d63e35ff8cd5bca48d2a12823828915749287256ab146272f9fb437bf65691243c3f504bd7ea6d5e6'
    
    ; Client decrypts:
    prf_results_first = h'3c33e07d202c3b029cc21f1722767021bf27d595933b3d2b6a1b9d5dddc77fae'
    
  • PIN 프로토콜 2를 사용하는 두 입력 사례:

    ; Inputs from Relying Party:
    prf_eval_first = h'576562417574686e20505246207465737420766563746f727302'
    prf_eval_second = h'576562417574686e20505246207465737420766563746f727303'
    
    ; Client computes:
    shared_secret = h'0c63083de8170101d38bcf8bd72309568ddb4550867e23404b35d85712f7c20d8bc911ee23c06034cbc14290b9669bec07739053c5a416e313ef905c79955876'
    salt1 = h'527413ebb48293772df30f031c5ac4650c7de14bf9498671ae163447b6a772b3'
    salt2 = h'd68ac03329a10ee5e0ec834492bb9a96a0e547baf563bf78ccbe8789b22e776b'
    salt_enc = h'd9f4236403e0fe843a8e4e5be764d120904c198ad6e77b089876a3391961f183b0008b4ca66b91cd72aa35b6151ff981f6e5649f3c040e6615ad7dd8ae96ef23b229a5c97c3f0dcd8605eee166ce163a'
    
    ; Authenticator computes:
    output1 = h'3c33e07d202c3b029cc21f1722767021bf27d595933b3d2b6a1b9d5dddc77fae'
    output2 = h'a62a8773b19cda90d7ed4ef72a80a804320dbd3997e2f663805ad1fd3293d50b'
    output_enc = h'90ee52f739043bc17b3488a74306d7801debb5b61f18662c648a25b5b5678ede482cdaff99a537a44f064fcb10ce6e04dfd27619dc96a0daff8507e499296b1eecf0981f7c8518b277a7a3018f5ec6fb'
    
    ; Client decrypts:
    prf_results_first = h'3c33e07d202c3b029cc21f1722767021bf27d595933b3d2b6a1b9d5dddc77fae'
    prf_results_second = h'a62a8773b19cda90d7ed4ef72a80a804320dbd3997e2f663805ad1fd3293d50b'
    
  • PIN 프로토콜 1을 사용하는 단일 입력 사례:

    ; Inputs from Relying Party:
    prf_eval_first = h'576562417574686e20505246207465737420766563746f727302'
    
    ; Client computes:
    shared_secret = h'23e5ed7157c25892b77732fb9c8a107e3518800db2af4142f9f4adfacb771d39'
    salt1 = h'527413ebb48293772df30f031c5ac4650c7de14bf9498671ae163447b6a772b3'
    salt_enc = h'ab8c878bb05d04700f077ed91845ec9c503c925cb12b327ddbeb4243c397f913'
    
    ; Authenticator computes:
    output1 = h'3c33e07d202c3b029cc21f1722767021bf27d595933b3d2b6a1b9d5dddc77fae'
    output_enc = h'15d4e4f3f04109b492b575c1b38c28585b6719cf8d61304215108d939f37ccfb'
    
    ; Client decrypts:
    prf_results_first = h'3c33e07d202c3b029cc21f1722767021bf27d595933b3d2b6a1b9d5dddc77fae'
    

이 섹션에서 사용된 입력값과 의사 난수 값들은 다음과 같이 생성되었습니다:

  • seed = UTF-8("WebAuthn PRF test vectors")

  • prf_eval_first = seed || 0x02

  • prf_eval_second = seed || 0x03

  • platform_key_agreement_private_key = SHA-256(seed || 0x04)

  • authenticator_key_agreement_public_key = P256-Public-Key(sk) where sk = SHA-256(seed || 0x05)

  • authenticator_cred_random = SHA-256(seed || 0x06)

  • iv in single-input salt_enc with PIN protocol 2: Truncated SHA-256(seed || 0x07)

  • iv in two-input salt_enc with PIN protocol 2: Truncated SHA-256(seed || 0x08)

  • iv in single-input output_enc with PIN protocol 2: Truncated SHA-256(seed || 0x09)

  • iv in two-input output_enc with PIN protocol 2: Truncated SHA-256(seed || 0x0a)

17. 감사의 글

이 명세서의 검토와 기여에 대해 다음 분들께 감사드립니다: Yuriy Ackermann, James Barclay, Richard Barnes, Dominic Battré, Julien Cayzac, Domenic Denicola, Rahul Ghosh, Brad Hill, Nidhi Jaju, Jing Jin, Wally Jones, Ian Kilpatrick, Axel Nennker, Zack Newman, Yoshikazu Nojima, Kimberly Paulhamus, Adam Powers, Yaron Sheffer, Anne van Kesteren, Johan Verrept, 그리고 Boris Zbarsky.

전체 등록(registration) 및 인증(authentication) 흐름도(도 1 및 도 2)를 만들어 주신 Adam Powers에게 감사드립니다.

다음 분들(웹 인증 작업 그룹 공동 의장으로서)의 기여에 감사드립니다: Anthony Nadalin, John Fontana, 그리고 Richard Barnes.

또한 우리 W3C 팀 연락 담당으로 기여해 주신 Simone Onofri, Philippe Le Hégaret, Wendy Seltzer, Samuel Weiler, 및 Harry Halpin 에게 감사드립니다.

18. 개정 이력

이 섹션은 규범적이지 않습니다.

이 섹션은 본 명세서에 시간이 흐르며 이루어진 주요 변경 사항들을 요약합니다.

18.1. Web Authentication 레벨 2 이후의 변경 사항 [webauthn-2-20210408]

18.1.1. 주요 변경 사항

다음 변경 사항들이 웹 인증 API 및 그 동작 방식에 적용되었습니다.

변경 사항:

사용 중단(권고):

새로운 기능:

18.1.2. 편집적 변경 사항

문서의 명확성, 가독성, 탐색성 등과 같은 측면을 개선하기 위해 다음 변경이 이루어졌습니다.

목차

이 명세에서 정의된 용어

참조에 의해 정의된 용어

참고 문헌

규범적 참고 문헌

[CREDENTIAL-MANAGEMENT-1]
Nina Satragno; Marcos Caceres. Credential Management Level 1. 2025년 10월 28일. WD. URL: https://www.w3.org/TR/credential-management-1/
[CSP2]
Mike West; Adam Barth; Daniel Veditz. Content Security Policy Level 2. 2016년 12월 15일. REC. URL: https://www.w3.org/TR/CSP2/
[DOM4]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMAScript]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[ENCODING]
Anne van Kesteren. Encoding Standard. Living Standard. URL: https://encoding.spec.whatwg.org/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[FIDO-APPID]
D. Balfanz; et al. FIDO AppID and Facet Specification. 2018년 2월 27일. FIDO Alliance Implementation Draft. URL: https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-appid-and-facets-v2.0-id-20180227.html
[FIDO-CLIENT-TO-AUTHENTICATOR-PROTOCOL-V2.1]
Client to Authenticator Protocol (CTAP). 편집자 초안. URL: https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-errata-20220621.html
[FIDO-CTAP]
J. Bradley; et al. Client to Authenticator Protocol (CTAP). 2022년 6월 21일. FIDO Alliance 제안 표준. URL: https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-errata-20220621.html
[FIDO-Privacy-Principles]
FIDO Alliance. FIDO Privacy Principles. FIDO Alliance 백서. URL: https://fidoalliance.org/wp-content/uploads/2014/12/FIDO_Alliance_Whitepaper_Privacy_Principles.pdf
[FIDO-Registry]
R. Lindemann; D. Baghdasaryan; B. Hill. FIDO Registry of Predefined Values. 2019년 12월 17일. FIDO Alliance 제안 표준. URL: https://fidoalliance.org/specs/common-specs/fido-registry-v2.1-ps-20191217.html
[FIDO-U2F-Message-Formats]
D. Balfanz; J. Ehrensvard; J. Lang. FIDO U2F Raw Message Formats. FIDO Alliance Implementation Draft. URL: https://fidoalliance.org/specs/fido-u2f-v1.1-id-20160915/fido-u2f-raw-message-formats-v1.1-id-20160915.html
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[I18N-GLOSSARY]
Richard Ishida; Addison Phillips. Internationalization Glossary. 2024년 10월 17일. 참고(NOTE). URL: https://www.w3.org/TR/i18n-glossary/
[IANA-COSE-ALGS-REG]
IANA CBOR Object Signing and Encryption (COSE) Algorithms Registry. URL: https://www.iana.org/assignments/cose/cose.xhtml#algorithms
[IANA-WebAuthn-Registries]
IANA. Web Authentication (WebAuthn) registries. URL: https://www.iana.org/assignments/webauthn/
[IANA-Well-Known-URIs]
IANA. Well-Known URIs. URL: https://www.iana.org/assignments/well-known-uris/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[Permissions-Policy]
Ian Clelland. Permissions Policy. 2025년 10월 6일. WD. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997년 3월. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC3986]
T. Berners-Lee; R. Fielding; L. Masinter. Uniform Resource Identifier (URI): Generic Syntax. 2005년 1월. 인터넷 표준. URL: https://www.rfc-editor.org/rfc/rfc3986
[RFC4648]
S. Josefsson. The Base16, Base32, and Base64 Data Encodings. 2006년 10월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc4648
[RFC4949]
R. Shirey. Internet Security Glossary, Version 2. 2007년 8월. 정보 제공 문서(Informational). URL: https://www.rfc-editor.org/rfc/rfc4949
[RFC5234]
D. Crocker, Ed.; P. Overell. Augmented BNF for Syntax Specifications: ABNF. 2008년 1월. 인터넷 표준. URL: https://www.rfc-editor.org/rfc/rfc5234
[RFC5280]
D. Cooper; et al. Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile. 2008년 5월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc5280
[RFC5890]
J. Klensin. Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework. 2010년 8월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc5890
[RFC6454]
A. Barth. The Web Origin Concept. 2011년 12월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc6454
[RFC7515]
M. Jones; J. Bradley; N. Sakimura. JSON Web Signature (JWS). 2015년 5월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc7515
[RFC8152]
J. Schaad. CBOR Object Signing and Encryption (COSE). 2017년 7월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc8152
[RFC8174]
B. Leiba. Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. 2017년 5월. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[RFC8230]
M. Jones. Using RSA Algorithms with CBOR Object Signing and Encryption (COSE) Messages. 2017년 9월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc8230
[RFC8264]
P. Saint-Andre; M. Blanchet. PRECIS Framework: Preparation, Enforcement, and Comparison of Internationalized Strings in Application Protocols. 2017년 10월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc8264
[RFC8265]
P. Saint-Andre; A. Melnikov. Preparation, Enforcement, and Comparison of Internationalized Strings Representing Usernames and Passwords. 2017년 10월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc8265
[RFC8266]
P. Saint-Andre. Preparation, Enforcement, and Comparison of Internationalized Strings Representing Nicknames. 2017년 10월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc8266
[RFC8610]
H. Birkholz; C. Vigano; C. Bormann. Concise Data Definition Language (CDDL): A Notational Convention to Express Concise Binary Object Representation (CBOR) and JSON Data Structures. 2019년 6월. IETF 제안 표준. URL: https://tools.ietf.org/html/rfc8610
[RFC8615]
M. Nottingham. Well-Known Uniform Resource Identifiers (URIs). 2019년 5월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc8615
[RFC8809]
Jeff Hodges; Giridhar Mandyam; Michael B. Jones. Registries for Web Authentication (WebAuthn). 2020년 8월. IETF 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc8809
[RFC8949]
C. Bormann; P. Hoffman. Concise Binary Object Representation (CBOR). 2020년 12월. 인터넷 표준. URL: https://www.rfc-editor.org/rfc/rfc8949
[RFC9052]
J. Schaad. CBOR Object Signing and Encryption (COSE): Structures and Process. 2022년 8월. 인터넷 표준. URL: https://www.rfc-editor.org/rfc/rfc9052
[RFC9053]
J. Schaad. CBOR Object Signing and Encryption (COSE): Initial Algorithms. 2022년 8월. 정보 제공 문서(Informational). URL: https://www.rfc-editor.org/rfc/rfc9053
[SEC1]
SEC1: Elliptic Curve Cryptography, Version 2.0. URL: http://www.secg.org/sec1-v2.pdf
[SP800-800-63r3]
Paul A. Grassi; Michael E. Garcia; James L. Fenton. NIST Special Publication 800-63: Digital Identity Guidelines. 2017년 6월. URL: https://pages.nist.gov/800-63-3/sp800-63-3.html
[TCG-CMCProfile-AIKCertEnroll]
Scott Kelly; et al. TCG Infrastructure Working Group: A CMC Profile for AIK Certificate Enrollment. 2011년 3월 24일. 게시됨. URL: https://trustedcomputinggroup.org/wp-content/uploads/IWG_CMC_Profile_Cert_Enrollment_v1_r7.pdf
[TokenBinding]
A. Popov; et al. The Token Binding Protocol Version 1.0. 2018년 10월. IETF 제안 표준. URL: https://tools.ietf.org/html/rfc8471
[TPMv2-EK-Profile]
TCG EK Credential Profile for TPM Family 2.0. URL: https://trustedcomputinggroup.org/wp-content/uploads/TCG-EK-Credential-Profile-V-2.5-R2_published.pdf
[TPMv2-Part1]
Trusted Platform Module Library, Part 1: Architecture. URL: https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-1-Architecture-01.38.pdf
[TPMv2-Part2]
Trusted Platform Module Library, Part 2: Structures. URL: https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-2-Structures-01.38.pdf
[TPMv2-Part3]
Trusted Platform Module Library, Part 3: Commands. URL: https://www.trustedcomputinggroup.org/wp-content/uploads/TPM-Rev-2.0-Part-3-Commands-01.38.pdf
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WCAG21]
Michael Cooper; et al. Web Content Accessibility Guidelines (WCAG) 2.1. 2025년 5월 6일. REC. URL: https://www.w3.org/TR/WCAG21/
[WEBAUTHN-2-20210408]
Jeff Hodges; et al. Web Authentication: An API for accessing Public Key Credentials - Level 2. 2021년 4월 8일. REC. URL: https://www.w3.org/TR/2021/REC-webauthn-2-20210408/
[WEBAUTHN-3-20250127]
Tim Cappalli; et al. Web Authentication: An API for accessing Public Key Credentials - Level 3. 2025년 1월 27일. WD. URL: https://www.w3.org/TR/2025/WD-webauthn-3-20250127/
[WebDriver]
Simon Stewart; David Burns. WebDriver. 2018년 6월 5일. REC. URL: https://www.w3.org/TR/webdriver1/
[WEBDRIVER2]
Simon Stewart; David Burns. WebDriver. 2025년 10월 28일. WD. URL: https://www.w3.org/TR/webdriver2/
[WebIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

참고용 참고 문헌

[Ceremony]
Carl Ellison. 행사 설계 및 분석. 2007. URL: https://eprint.iacr.org/2007/399.pdf
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal. CSS 오버플로 모듈 레벨 3. 2025년 10월 7일. WD. URL: https://www.w3.org/TR/css-overflow-3/
[EduPersonObjectClassSpec]
EduPerson. 진행 중. URL: https://refeds.org/eduperson
[FIDO-Transports-Ext]
FIDO Alliance. FIDO U2F 인증기 전송 확장. FIDO Alliance 제안 표준. URL: https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-authenticator-transports-extension-v1.2-ps-20170411.html
[FIDO-UAF-AUTHNR-CMDS]
R. Lindemann; J. Kemp. FIDO UAF 인증기 명령. FIDO Alliance Implementation Draft. URL: https://fidoalliance.org/specs/fido-uaf-v1.1-id-20170202/fido-uaf-authnr-cmds-v1.1-id-20170202.html
[FIDOAuthnrSecReqs]
D. Biggs; et al. FIDO 인증기 보안 요구사항. FIDO Alliance 최종 문서. URL: https://fidoalliance.org/specs/fido-security-requirements-v1.0-fd-20170524/
[FIDOMetadataService]
R. Lindemann; B. Hill; D. Baghdasaryan. FIDO 메타데이터 서비스. 2018년 2월 27일. FIDO Alliance Implementation Draft. URL: https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-metadata-service-v2.0-id-20180227.html
[FIDOSecRef]
R. Lindemann; et al. FIDO 보안 참조. 2018년 2월 27일. FIDO Alliance Implementation Draft. URL: https://fidoalliance.org/specs/fido-v2.0-id-20180227/fido-security-ref-v2.0-id-20180227.html
[FIDOU2FJavaScriptAPI]
D. Balfanz; A. Birgisson; J. Lang. FIDO U2F 자바스크립트 API. FIDO Alliance 제안 표준. URL: https://fidoalliance.org/specs/fido-u2f-v1.2-ps-20170411/fido-u2f-javascript-api-v1.2-ps-20170411.html
[ISOBiometricVocabulary]
ISO/IEC JTC1/SC37. 정보 기술 — 용어집 — 생체 인식. 2012년 12월 15일. 국제 표준: ISO/IEC 2382-37:2012(E) 제1판. URL: http://standards.iso.org/ittf/PubliclyAvailableStandards/c055194_ISOIEC_2382-37_2012.zip
[RFC3279]
L. Bassham; W. Polk; R. Housley. 인터넷 X.509 공개 키 인프라 인증서 및 인증서 폐기 목록(CRL) 프로필을 위한 알고리즘 및 식별자. 2002년 4월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc3279
[RFC5869]
H. Krawczyk; P. Eronen. HMAC 기반 추출-확장 키 도출 함수 (HKDF). 2010년 5월. 정보 제공 문서(Informational). URL: https://www.rfc-editor.org/rfc/rfc5869
[RFC5958]
S. Turner. 비대칭 키 패키지. 2010년 8월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc5958
[RFC6265]
A. Barth. HTTP 상태 관리 메커니즘. 2011년 4월. 제안 표준. URL: https://httpwg.org/specs/rfc6265.html
[RFC6979]
T. Pornin. 디지털 서명 알고리즘(DSA) 및 타원 곡선 디지털 서명 알고리즘(ECDSA)의 결정적 사용. 2013년 8월. 정보 제공 문서(Informational). URL: https://www.rfc-editor.org/rfc/rfc6979
[RFC8017]
K. Moriarty, Ed.; et al. PKCS #1: RSA 암호 사양 버전 2.2. 2016년 11월. 정보 제공 문서(Informational). URL: https://www.rfc-editor.org/rfc/rfc8017
[RFC9864]
M.B. Jones; O. Steele. JOSE와 COSE의 JSON 객체 서명 및 암호화(JOSE)와 CBOR 객체 서명 및 암호화(COSE)를 위한 완전 명세 알고리즘. 2025년 10월. 제안 표준. URL: https://www.rfc-editor.org/rfc/rfc9864
[UAFProtocol]
R. Lindemann; et al. FIDO UAF 프로토콜 사양 v1.0. FIDO Alliance 제안 표준. URL: https://fidoalliance.org/specs/fido-uaf-v1.0-ps-20141208/fido-uaf-protocol-v1.0-ps-20141208.html
[UAX29]
유니코드 텍스트 분절. URL: http://www.unicode.org/reports/tr29/
[WebAuthn-1]
Dirk Balfanz; et al. 웹 인증: 공개 키 자격증명 액세스용 API — 레벨 1. 2019년 3월 4일. REC. URL: https://www.w3.org/TR/webauthn-1/
[WebAuthnAPIGuide]
웹 인증 API 가이드. 실험적(Experimental). URL: https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API

IDL Index

[SecureContext, Exposed=Window]
interface PublicKeyCredential : Credential {
    [SameObject] readonly attribute ArrayBuffer              rawId;
    [SameObject] readonly attribute AuthenticatorResponse    response;
    readonly attribute DOMString?                            authenticatorAttachment;
    AuthenticationExtensionsClientOutputs getClientExtensionResults();
    static Promise<boolean> isConditionalMediationAvailable();
    PublicKeyCredentialJSON toJSON();
};

typedef DOMString Base64URLString;
// The structure of this object will be either
// RegistrationResponseJSON or AuthenticationResponseJSON
typedef object PublicKeyCredentialJSON;

dictionary RegistrationResponseJSON {
    required DOMString id;
    required Base64URLString rawId;
    required AuthenticatorAttestationResponseJSON response;
    DOMString authenticatorAttachment;
    required AuthenticationExtensionsClientOutputsJSON clientExtensionResults;
    required DOMString type;
};

dictionary AuthenticatorAttestationResponseJSON {
    required Base64URLString clientDataJSON;
    required Base64URLString authenticatorData;
    required sequence<DOMString> transports;
    // The publicKey field will be missing if pubKeyCredParams was used to
    // negotiate a public-key algorithm that the user agent doesn't
    // understand. (See section “Easily accessing credential data” for a
    // list of which algorithms user agents must support.) If using such an
    // algorithm then the public key must be parsed directly from
    // attestationObject or authenticatorData.
    Base64URLString publicKey;
    required COSEAlgorithmIdentifier publicKeyAlgorithm;
    // This value contains copies of some of the fields above. See
    // section “Easily accessing credential data”.
    required Base64URLString attestationObject;
};

dictionary AuthenticationResponseJSON {
    required DOMString id;
    required Base64URLString rawId;
    required AuthenticatorAssertionResponseJSON response;
    DOMString authenticatorAttachment;
    required AuthenticationExtensionsClientOutputsJSON clientExtensionResults;
    required DOMString type;
};

dictionary AuthenticatorAssertionResponseJSON {
    required Base64URLString clientDataJSON;
    required Base64URLString authenticatorData;
    required Base64URLString signature;
    Base64URLString userHandle;
};

dictionary AuthenticationExtensionsClientOutputsJSON {
};

partial dictionary CredentialCreationOptions {
    PublicKeyCredentialCreationOptions      publicKey;
};

partial dictionary CredentialRequestOptions {
    PublicKeyCredentialRequestOptions      publicKey;
};

partial interface PublicKeyCredential {
    static Promise<boolean> isUserVerifyingPlatformAuthenticatorAvailable();
};

partial interface PublicKeyCredential {
    static Promise<PublicKeyCredentialClientCapabilities> getClientCapabilities();
};

typedef record<DOMString, boolean> PublicKeyCredentialClientCapabilities;

partial interface PublicKeyCredential {
    static PublicKeyCredentialCreationOptions parseCreationOptionsFromJSON(PublicKeyCredentialCreationOptionsJSON options);
};

dictionary PublicKeyCredentialCreationOptionsJSON {
    required PublicKeyCredentialRpEntity                    rp;
    required PublicKeyCredentialUserEntityJSON              user;
    required Base64URLString                                challenge;
    required sequence<PublicKeyCredentialParameters>        pubKeyCredParams;
    unsigned long                                           timeout;
    sequence<PublicKeyCredentialDescriptorJSON>             excludeCredentials = [];
    AuthenticatorSelectionCriteria                          authenticatorSelection;
    sequence<DOMString>                                     hints = [];
    DOMString                                               attestation = "none";
    sequence<DOMString>                                     attestationFormats = [];
    AuthenticationExtensionsClientInputsJSON                extensions;
};

dictionary PublicKeyCredentialUserEntityJSON {
    required Base64URLString        id;
    required DOMString              name;
    required DOMString              displayName;
};

dictionary PublicKeyCredentialDescriptorJSON {
    required DOMString              type;
    required Base64URLString        id;
    sequence<DOMString>             transports;
};

dictionary AuthenticationExtensionsClientInputsJSON {
};

partial interface PublicKeyCredential {
    static PublicKeyCredentialRequestOptions parseRequestOptionsFromJSON(PublicKeyCredentialRequestOptionsJSON options);
};

dictionary PublicKeyCredentialRequestOptionsJSON {
    required Base64URLString                                challenge;
    unsigned long                                           timeout;
    DOMString                                               rpId;
    sequence<PublicKeyCredentialDescriptorJSON>             allowCredentials = [];
    DOMString                                               userVerification = "preferred";
    sequence<DOMString>                                     hints = [];
    AuthenticationExtensionsClientInputsJSON                extensions;
};

partial interface PublicKeyCredential {
    static Promise<undefined> signalUnknownCredential(UnknownCredentialOptions options);
    static Promise<undefined> signalAllAcceptedCredentials(AllAcceptedCredentialsOptions options);
    static Promise<undefined> signalCurrentUserDetails(CurrentUserDetailsOptions options);
};

dictionary UnknownCredentialOptions {
    required DOMString                     rpId;
    required Base64URLString               credentialId;
};

dictionary AllAcceptedCredentialsOptions {
    required DOMString                     rpId;
    required Base64URLString               userId;
    required sequence<Base64URLString>     allAcceptedCredentialIds;
};

dictionary CurrentUserDetailsOptions {
    required DOMString                     rpId;
    required Base64URLString               userId;
    required DOMString                     name;
    required DOMString                     displayName;
};

[SecureContext, Exposed=Window]
interface AuthenticatorResponse {
    [SameObject] readonly attribute ArrayBuffer      clientDataJSON;
};

[SecureContext, Exposed=Window]
interface AuthenticatorAttestationResponse : AuthenticatorResponse {
    [SameObject] readonly attribute ArrayBuffer      attestationObject;
    sequence<DOMString>                              getTransports();
    ArrayBuffer                                      getAuthenticatorData();
    ArrayBuffer?                                     getPublicKey();
    COSEAlgorithmIdentifier                          getPublicKeyAlgorithm();
};

[SecureContext, Exposed=Window]
interface AuthenticatorAssertionResponse : AuthenticatorResponse {
    [SameObject] readonly attribute ArrayBuffer      authenticatorData;
    [SameObject] readonly attribute ArrayBuffer      signature;
    [SameObject] readonly attribute ArrayBuffer?     userHandle;
};

dictionary PublicKeyCredentialParameters {
    required DOMString                    type;
    required COSEAlgorithmIdentifier      alg;
};

dictionary PublicKeyCredentialCreationOptions {
    required PublicKeyCredentialRpEntity         rp;
    required PublicKeyCredentialUserEntity       user;

    required BufferSource                             challenge;
    required sequence<PublicKeyCredentialParameters>  pubKeyCredParams;

    unsigned long                                timeout;
    sequence<PublicKeyCredentialDescriptor>      excludeCredentials = [];
    AuthenticatorSelectionCriteria               authenticatorSelection;
    sequence<DOMString>                          hints = [];
    DOMString                                    attestation = "none";
    sequence<DOMString>                          attestationFormats = [];
    AuthenticationExtensionsClientInputs         extensions;
};

dictionary PublicKeyCredentialEntity {
    required DOMString    name;
};

dictionary PublicKeyCredentialRpEntity : PublicKeyCredentialEntity {
    DOMString      id;
};

dictionary PublicKeyCredentialUserEntity : PublicKeyCredentialEntity {
    required BufferSource   id;
    required DOMString      displayName;
};

dictionary AuthenticatorSelectionCriteria {
    DOMString                    authenticatorAttachment;
    DOMString                    residentKey;
    boolean                      requireResidentKey = false;
    DOMString                    userVerification = "preferred";
};

enum AuthenticatorAttachment {
    "platform",
    "cross-platform"
};

enum ResidentKeyRequirement {
    "discouraged",
    "preferred",
    "required"
};

enum AttestationConveyancePreference {
    "none",
    "indirect",
    "direct",
    "enterprise"
};

dictionary PublicKeyCredentialRequestOptions {
    required BufferSource                challenge;
    unsigned long                        timeout;
    DOMString                            rpId;
    sequence<PublicKeyCredentialDescriptor> allowCredentials = [];
    DOMString                            userVerification = "preferred";
    sequence<DOMString>                  hints = [];
    AuthenticationExtensionsClientInputs extensions;
};

dictionary AuthenticationExtensionsClientInputs {
};

dictionary AuthenticationExtensionsClientOutputs {
};

dictionary CollectedClientData {
    required DOMString           type;
    required DOMString           challenge;
    required DOMString           origin;
    boolean                      crossOrigin;
    DOMString                    topOrigin;
};

dictionary TokenBinding {
    required DOMString status;
    DOMString id;
};

enum TokenBindingStatus { "present", "supported" };

enum PublicKeyCredentialType {
    "public-key"
};

dictionary PublicKeyCredentialDescriptor {
    required DOMString                    type;
    required BufferSource                 id;
    sequence<DOMString>                   transports;
};

enum AuthenticatorTransport {
    "usb",
    "nfc",
    "ble",
    "smart-card",
    "hybrid",
    "internal"
};

typedef long COSEAlgorithmIdentifier;

enum UserVerificationRequirement {
    "required",
    "preferred",
    "discouraged"
};

enum ClientCapability {
    "conditionalCreate",
    "conditionalGet",
    "hybridTransport",
    "passkeyPlatformAuthenticator",
    "userVerifyingPlatformAuthenticator",
    "relatedOrigins",
    "signalAllAcceptedCredentials",
    "signalCurrentUserDetails",
    "signalUnknownCredential"
};

enum PublicKeyCredentialHint {
    "security-key",
    "client-device",
    "hybrid",
};

partial dictionary AuthenticationExtensionsClientInputs {
  DOMString appid;
};
partial dictionary AuthenticationExtensionsClientInputsJSON {
  DOMString appid;
};

partial dictionary AuthenticationExtensionsClientOutputs {
  boolean appid;
};
partial dictionary AuthenticationExtensionsClientOutputsJSON {
  boolean appid;
};

partial dictionary AuthenticationExtensionsClientInputs {
  DOMString appidExclude;
};
partial dictionary AuthenticationExtensionsClientInputsJSON {
  DOMString appidExclude;
};

partial dictionary AuthenticationExtensionsClientOutputs {
  boolean appidExclude;
};
partial dictionary AuthenticationExtensionsClientOutputsJSON {
  boolean appidExclude;
};

partial dictionary AuthenticationExtensionsClientInputs {
    boolean credProps;
};
partial dictionary AuthenticationExtensionsClientInputsJSON {
    boolean credProps;
};

dictionary CredentialPropertiesOutput {
    boolean rk;
};

partial dictionary AuthenticationExtensionsClientOutputs {
    CredentialPropertiesOutput credProps;
};
partial dictionary AuthenticationExtensionsClientOutputsJSON {
    CredentialPropertiesOutput credProps;
};

dictionary AuthenticationExtensionsPRFValues {
    required BufferSource first;
    BufferSource second;
};
dictionary AuthenticationExtensionsPRFValuesJSON {
    required Base64URLString first;
    Base64URLString second;
};

dictionary AuthenticationExtensionsPRFInputs {
    AuthenticationExtensionsPRFValues eval;
    record<DOMString, AuthenticationExtensionsPRFValues> evalByCredential;
};
dictionary AuthenticationExtensionsPRFInputsJSON {
    AuthenticationExtensionsPRFValuesJSON eval;
    record<DOMString, AuthenticationExtensionsPRFValuesJSON> evalByCredential;
};

partial dictionary AuthenticationExtensionsClientInputs {
    AuthenticationExtensionsPRFInputs prf;
};
partial dictionary AuthenticationExtensionsClientInputsJSON {
    AuthenticationExtensionsPRFInputsJSON prf;
};

dictionary AuthenticationExtensionsPRFOutputs {
    boolean enabled;
    AuthenticationExtensionsPRFValues results;
};
dictionary AuthenticationExtensionsPRFOutputsJSON {
    boolean enabled;
    AuthenticationExtensionsPRFValuesJSON results;
};

partial dictionary AuthenticationExtensionsClientOutputs {
    AuthenticationExtensionsPRFOutputs prf;
};
partial dictionary AuthenticationExtensionsClientOutputsJSON {
    AuthenticationExtensionsPRFOutputsJSON prf;
};

partial dictionary AuthenticationExtensionsClientInputs {
    AuthenticationExtensionsLargeBlobInputs largeBlob;
};
partial dictionary AuthenticationExtensionsClientInputsJSON {
    AuthenticationExtensionsLargeBlobInputsJSON largeBlob;
};

enum LargeBlobSupport {
  "required",
  "preferred",
};

dictionary AuthenticationExtensionsLargeBlobInputs {
    DOMString support;
    boolean read;
    BufferSource write;
};
dictionary AuthenticationExtensionsLargeBlobInputsJSON {
    DOMString support;
    boolean read;
    Base64URLString write;
};

partial dictionary AuthenticationExtensionsClientOutputs {
    AuthenticationExtensionsLargeBlobOutputs largeBlob;
};
partial dictionary AuthenticationExtensionsClientOutputsJSON {
    AuthenticationExtensionsLargeBlobOutputsJSON largeBlob;
};

dictionary AuthenticationExtensionsLargeBlobOutputs {
    boolean supported;
    ArrayBuffer blob;
    boolean written;
};
dictionary AuthenticationExtensionsLargeBlobOutputsJSON {
    boolean supported;
    Base64URLString blob;
    boolean written;
};

MDN

AuthenticatorAssertionResponse/authenticatorData

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile48+
MDN

AuthenticatorAssertionResponse/signature

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile48+
MDN

AuthenticatorAssertionResponse/userHandle

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile48+
MDN

AuthenticatorAssertionResponse

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile48+
MDN

AuthenticatorAttestationResponse/attestationObject

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile48+
MDN

AuthenticatorAttestationResponse/getTransports

FirefoxNoneSafari16+Chrome74+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebViewNoneSamsung Internet?Opera Mobile?
MDN

AuthenticatorAttestationResponse

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile48+
MDN

AuthenticatorResponse/clientDataJSON

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile48+
MDN

AuthenticatorResponse

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile48+
MDN

PublicKeyCredential/getClientExtensionResults

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile?
MDN

PublicKeyCredential/isUserVerifyingPlatformAuthenticatorAvailable_static

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile?
MDN

PublicKeyCredential/rawId

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile?
MDN

PublicKeyCredential/response

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile?
MDN

PublicKeyCredential

In all current engines.

Firefox60+Safari13+Chrome67+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android92+iOS Safari?Chrome for Android70+Android WebViewNoneSamsung Internet?Opera Mobile?
MDN

Headers/Feature-Policy/publickey-credentials-get

In only one current engine.

FirefoxNoneSafariNoneChrome84+
OperaNoneEdge84+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera MobileNone

Headers/Permissions-Policy/publickey-credentials-create

In only one current engine.

FirefoxNoneSafariNoneChrome88+
OperaNoneEdge88+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera MobileNone

Headers/Permissions-Policy/publickey-credentials-get

In only one current engine.

FirefoxNoneSafariNoneChrome88+
OperaNoneEdge88+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera MobileNone