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

W3C 작업 초안,

이 문서에 대한 자세한 정보
이 버전:
https://www.w3.org/TR/2025/WD-webauthn-3-20250127/
최신 게시 버전:
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 기술 보고서 색인 https://www.w3.org/TR/ 에서 확인할 수 있습니다.

이 문서는 Web Authentication Working Group에 의해 권고안(Recommendation track)을 사용하여 작업 초안(Working Draft)으로 게시되었습니다. 이 문서는 W3C 권고안이 되는 것을 목표로 합니다. 이 명세서에 대한 피드백과 의견을 환영합니다. Github issues를 이용해 주세요. 논의는 또한 public-webauthn@w3.org 아카이브에서도 확인할 수 있습니다.

작업 초안으로의 게시가 W3C 및 그 구성원의 지지를 의미하지는 않습니다. 이 문서는 초안 문서이며 언제든지 업데이트, 교체 또는 다른 문서에 의해 대체될 수 있습니다. 이 문서를 진행 중인 작업 이외의 것으로 인용하는 것은 부적절합니다.

이 문서는 W3C 특허 정책 하에서 운영되는 그룹에 의해 작성되었습니다. W3C는 그룹 산출물과 관련하여 이루어진 모든 특허 공개의 공개 목록을 유지하며; 해당 페이지에는 특허 공개 방법에 대한 안내도 포함되어 있습니다. 개인이 자신이 알고 있는 특허가 필수 청구항(엔셀이셜한 청구항)을 포함한다고 믿는 경우, 해당 정보는 W3C 특허 정책의 섹션 6에 따라 공개해야 합니다.

이 문서는 2023년 11월 03일 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) { /* Client not capable. Handle error. */ }

var publicKey = {
  // The challenge is produced by the server; see the Security Considerations
  challenge: new Uint8Array([21,31,105 /* 29 more random bytes generated by the server */]),

  // Relying Party:
  rp: {
    name: "ACME Corporation"
  },

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

  // This Relying Party will accept either an ES256 or RS256 credential, but
  // prefers an ES256 credential.
  pubKeyCredParams: [{
      type: "public-key",>
      alg: -7 // "ES256" as registered in the IANA COSE Algorithms registry
    },
    {
      type: "public-key",>
      alg: -257 // Value registered by this specification for "RS256"
    }
  ],

  authenticatorSelection: {
    // Try to use UV if possible. This is also the default.
    userVerification: "preferred"
  },

  timeout: 300000,  // 5 minutes
  excludeCredentials: [// Don't re-register any authenticator that has one of these credentials
    {"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"}
  ],

  // Make excludeCredentials check backwards compatible with credentials registered with U2F
  extensions: {"appidExclude": "https://acme.example.com"}
};

// Note: The following call will cause the authenticator to display UI.
navigator.credentials.create({ publicKey })
  .then(function (newCredentialInfo) {
    // Send new credential info to server for verification and registration.
  }).catch(function (err) {
    // No acceptable authenticator or user refused consent. Handle appropriately.
  });

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 == "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 항목과 함께 저장하면 의존 당사자가 나중에 증명 서명을 재검증할 수 있게 됩니다.

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

공개 키 자격 증명 소스범위가 지정된 신뢰 당사자 식별자(Relying Party Identifier)입니다. 이는 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)로, 사용자와 신뢰 당사자, 사용자 클라이언트 플랫폼(하나 이상의 인증자를 포함/연결)이 협력하여 공개 키 자격 증명을 생성하여 사용자 계정에 연결합니다. 이것은 사용자 존재 테스트(test of user presence)사용자 검증(user verification)을 반드시 포함합니다. 등록 절차(registration ceremony)가 성공하면 사용자는 인증 절차(authentication ceremony)를 통해 인증할 수 있습니다.

WebAuthn 등록 절차§ 7.1 새 자격 증명 등록에 정의되어 있으며, 신뢰 당사자 navigator.credentials.create() publicKey 인자로 호출함으로써 시작됩니다. § 5 Web Authentication 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로부터 상속되지만, PublicKeyCredential 은 Credential의 getter를 재정의하여 객체의 [[identifier]] 내부 슬롯에 포함된 데이터의 base64url 인코딩을 대신 반환합니다.

rawId

이 속성은 ArrayBuffer 형태로 [[identifier]] 내부 슬롯에 포함된 값을 반환합니다.

response, of type AuthenticatorResponse, readonly

이 속성은 새 공개 키 자격 증명을 생성하거나 인증 어설션을 생성하라는 클라이언트의 요청에 대한 인증기의 응답을 포함합니다. 만약 PublicKeyCredentialcreate()에 대한 응답으로 생성되었다면, 이 속성의 값은 AuthenticatorAttestationResponse가 될 것이고, 그렇지 않다면 이 PublicKeyCredentialget()에 대한 응답으로 생성되었으며 이 속성의 값은 AuthenticatorAssertionResponse가 됩니다.

authenticatorAttachment, of type DOMString, readonly, nullable

이 속성은 authenticator attachment modality를 보고하며, navigator.credentials.create() 또는 navigator.credentials.get() 호출이 성공적으로 완료되었을 때 적용된 값을 나타냅니다. 이 속성의 값은 AuthenticatorAttachment의 멤버여야 합니다. Relying Parties는 알 수 없는 값을 null로 처리해야 합니다.

Note: 만약 등록 절차 또는 인증 절차의 결과로 authenticatorAttachment의 값이 "cross-platform"이고 동시에 isUserVerifyingPlatformAuthenticatorAvailabletrue를 반환한다면, 사용자는 그 절차에서 로밍 인증기를 사용했고 동시에 사용 가능한 플랫폼 인증기가 있다는 뜻입니다. 따라서 Relying Party는 사용자가 사용 가능한 플랫폼 인증기를 등록하도록 유도할 기회를 가집니다. 이는 보다 원활한 사용자 경험을 가능하게 할 수 있습니다.

인증기의 attachment modality는 시간이 지남에 따라 변경될 수 있습니다. 예를 들어, 휴대전화는 한 시점에서는 플랫폼 부착(platform attachment)만 지원할 수 있지만 이후 업데이트를 통해 크로스-플랫폼 부착(cross-platform attachment)도 지원하게 될 수 있습니다.

getClientExtensionResults()

이 연산은 [[clientExtensionsResults]]의 값을 반환합니다. 이 값은 확장의 클라이언트 확장 출력을 생성한 확장 식별자 → 출력 간의 항목들을 포함하는 입니다.

isConditionalMediationAvailable()

PublicKeyCredential 은 이 메서드를 재정의하여 conditional 중재가 navigator.credentials.get() 동안 사용 가능한지를 나타냅니다. WebAuthn Relying Partiesoptions.mediationconditional로 설정하기 전에 사용 가능 여부를 확인하는 것이 권장됩니다.

이 메서드를 호출하면, true로 해석되는 경우 conditional 사용자 중재(user mediation)가 사용 가능함을 나타내며 그렇지 않으면 false로 해결되는 약속(Promise)이 반환됩니다.

이 메서드는 인수를 받지 않으며 불리언 값을 반환하는 약속을 반환합니다.

클라이언트 기능인 conditionalGet은 이 약속이 true로 해결되는 것과 동등합니다.

Note: 만약 이 메서드가 존재하지 않는다면, conditional 사용자 중재는 navigator.credentials.get()에 대해 사용 불가능한 것으로 간주됩니다.

Note: 이 메서드는 conditional 사용자 중재가 navigator.credentials.create()에 대해 사용 가능한지를 나타내지는 않습니다. 이 경우에는 conditionalCreate 기능을 getClientCapabilities()에서 확인해야 합니다.

toJSON()

이 연산은 RegistrationResponseJSON 또는 AuthenticationResponseJSON를 반환합니다. 이는 PublicKeyCredential을 반영하는 JSON 타입 표현으로, Relying Party 서버에 application/json 페이로드로 제출하기에 적합합니다. 클라이언트는 일반적인 방식으로 값을 JSON 타입으로 직렬화할 책임이 있지만, 먼저 모든 ArrayBuffer 값을 DOMString 값으로 변환하기 위해 base64url 인코딩을 반드시 수행해야 합니다.

RegistrationResponseJSON.clientExtensionResults 또는 AuthenticationResponseJSON.clientExtensionResults 멤버는 getClientExtensionResults()의 출력을 설정해야 하며, 이때 ArrayBuffer 값들은 base64url 인코딩을 사용해 DOMString 값으로 인코딩되어야 합니다. 이에는 IANA "WebAuthn Extension Identifiers" 레지스트리에 등록되어 있지만 § 9 WebAuthn Extensions에 정의되지 않은 확장으로부터의 ArrayBuffer 값이 포함될 수 있습니다.

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"입니다.

Note: 이는 type 속성 getter를 통해 반영됩니다 (Credential로부터 상속됨).

[[discovery]]

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

[[identifier]]

이 내부 슬롯은 인증기가 선택한 자격 증명 ID를 포함합니다. 자격 증명 ID는 자격 증명을 조회하는 데 사용되며, 동일 유형의 모든 자격 증명과 모든 인증기에서 높은 확률로 전역적으로 유일할 것으로 기대됩니다.

이 API는 이 식별자의 형식을 제약하지 않지만, 그 길이는 1023 바이트를 초과해서는 안 되며 인증기가 키를 고유하게 선택할 수 있을 만큼 충분해야 합니다. 예를 들어, 온보드 저장소가 없는 인증기는 대칭 키로 감싼 자격 증명 개인 키를 포함하는 식별자를 생성할 수 있습니다(해당 대칭 키는 인증기에 내장됨).

[[clientExtensionsResults]]

이 내부 슬롯은 내부 슬롯로, Relying Partynavigator.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()를 통해 어설션을 얻는 것을 지원하기 위해, 이 문서는 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() 를 호출하여 새로운 공개키 크리덴셜 소스를 요청할 수 있으며, 이 크리덴셜은 바인딩된 인증기와 연결됩니다.

다음과 같이 설정함으로써 options.mediationconditional로 하면, Relying Parties는 사용자가 이미 자격 증명 생성을 허용한 경우 눈에 띄는 모달 UI 없이 자격 증명을 등록하길 원함을 표시할 수 있습니다. Relying Party는 이 기능이 사용 가능한지 확인하기 위해 먼저 getClientCapabilities()를 사용하여 clientconditionalCreate 기능을 지원하는지 확인해야 하며, 그렇지 않으면 사용자에게 눈에 보이는 오류가 발생할 수 있습니다.

클라이언트는 options.mediationconditional로 설정된 경우, 의식적으로 의식적으로 의식을 수행하지 않는 한 requireUserPresencerequireUserVerification를 모두 FALSE로 설정해야 합니다.

모든 navigator.credentials.create() 작업은 AbortController를 사용하여 중단할 수 있습니다; 자세한 지침은 DOM § 3.3 Using AbortController and AbortSignal objects in APIs를 참조하세요.

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

origin

이 인수는 호출하는 create() 구현에 의해 결정된 relevant settings objectorigin입니다.

options

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

sameOriginWithAncestors

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

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

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

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

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

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

  2. 만약 sameOriginWithAncestorsfalse이면:

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

      1. NotAllowedError" DOMException을 던집니다.

    2. 만약 호출하는 create() 구현에 의해 결정된 relevant global objecttransient activation을 가지고 있지 않다면:

      1. NotAllowedError" DOMException을 던집니다.

    3. relevant global object의 사용자 활성화를 소비합니다.

    4. 만약 자격 증명을 생성하는 origin이 사용자가 주소 표시줄에서 보는 최상위 기원의 top-level origin과 다르다면, client는 이 사실을 사용자에게 명확히 알려야 합니다.

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

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

    권장 범위 및 기본값에 대한 지침은 recommended range and default for a WebAuthn ceremony timeout를 참조하세요.

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

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

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

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

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

  8. 만약 pkOptions.rp.id

    존재하는 경우

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

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

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

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

    "SecurityError" DOMException을 던집니다.

    존재하지 않는 경우

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

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

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

  10. 만약 pkOptions.pubKeyCredParams크기

    0인 경우

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

    0이 아닌 경우

    각각의 current에 대해 pkOptions.pubKeyCredParams를 반복합니다:

    1. 만약 current.type 에 이 구현이 지원하지 않는 PublicKeyCredentialType 가 포함되어 있으면 계속합니다.

    2. algcurrent.alg로 둡니다.

    3. credTypesAndPubKeyAlgs에 추가합니다: current.typealg.

    만약 credTypesAndPubKeyAlgs가 비어 있으면 "NotSupportedError" DOMException을 던집니다.

  11. clientExtensions를 새 map으로 하고, authenticatorExtensions를 새 map으로 둡니다.

  12. 만약 pkOptions.extensions 가 존재하면, 각각의 extensionIdclientExtensionInput에 대해:
    1. 만약 extensionId가 이 client platform에서 지원되지 않거나 등록 확장(registration extension)이 아니면 계속합니다.

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

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

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

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

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

    type

    문자열 "webauthn.create".

    challenge

    pkOptions.challengebase64url 인코딩.

    origin

    callerOrigin직렬화.

    crossOrigin

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

    topOrigin

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

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

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

  16. 만약 options.signal 이 존재하고 aborted 상태라면, options.signalabort reason을 throw 하십시오.

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

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

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

  19. 만약 options.mediation 이 존재하고 값이 conditional이면:

    1. 만약 사용자 에이전트가 최근에 인증을 중재하지 않았거나, 그 인증의 기원이 callerOrigin이 아니거나, 사용자가 이 유형의 자격 증명 생성을 동의하지 않으면 "NotAllowedError" DOMException을 던집니다.

      어떤 시점에서 사용자 에이전트가 인증 절차가 완료되었다고 믿을지는 사용자 에이전트에 달려 있습니다. 그 인증 절차는 Web Authentication API 이외의 다른 수단으로 수행될 수 있습니다.

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

  21. lifetimeTimer를 시작합니다.

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

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

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

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

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

    authenticator에 대해 issuedRequests에 있는 항목을 대상으로, authenticatorCancel 작업을 authenticator에 호출하고 제거 authenticatorissuedRequests에서 합니다. 그런 다음 options.signal중단 사유(abort reason)를 throw합니다.

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

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

    1. authenticator는 이제 candidate authenticator가 됩니다.

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

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

      2. 만약 pkOptions.authenticatorSelection.residentKey

        존재하고 required로 설정된 경우

        만약 authenticatorclient-side discoverable public key credential source를 저장할 수 없으면 계속합니다.

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

        영향 없음.

        존재하지 않는 경우

        만약 pkOptions.authenticatorSelection.requireResidentKeytrue로 설정되어 있고 authenticatorclient-side discoverable public key credential source를 저장할 수 없으면 계속합니다.

      3. 만약 pkOptions.authenticatorSelection.userVerificationrequired로 설정되어 있고 이 authenticatoruser verification을 수행할 수 없으면 계속합니다.

    3. requireResidentKey자격 증명 생성에 대한 유효 상주 키 요구 사항(effective resident key requirement for credential creation) Boolean 값으로 정의한다. 정의 방법은 다음과 같다:

      pkOptions.authenticatorSelection.residentKey

      존재하며 required로 설정된 경우

      requireResidentKeytrue로 한다.

      존재하며 preferred로 설정된 경우

      만약 authenticator

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

      requireResidentKeytrue로 한다.

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

      requireResidentKeyfalse로 한다.

      존재하며 discouraged로 설정된 경우

      requireResidentKeyfalse로 한다.

      존재하지 않는 경우

      requireResidentKeypkOptions.authenticatorSelection.requireResidentKey 값으로 한다.

    4. userVerification자격 증명 생성에 대한 유효 사용자 검증 요구사항(effective user verification requirement for credential creation) Boolean 값으로 정의한다. 정의는 다음과 같다. pkOptions.authenticatorSelection.userVerification

      required로 설정된 경우
      1. options.mediation 값이 conditional이고, 본 절차에서 사용자 검증(user verification)을 획득할 수 없는 경우, ConstraintError DOMException을 throw한다.

      2. userVerificationtrue로 한다.

      preferred로 설정된 경우

      만약 authenticator

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

      userVerificationtrue로 한다.

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

      userVerificationfalse로 한다.

      discouraged로 설정된 경우

      userVerificationfalse로 한다.

    5. enterpriseAttestationPossible를 Boolean 값으로 둡니다. 만약 pkOptions.attestation

      설정이 enterprise인 경우

      만약 사용자 에이전트가 pkOptions.rp.id에 대해 enterprise attestation을 지원하기 원하면 enterpriseAttestationPossibletrue로 합니다. 그렇지 않으면 false로 합니다.

      그 외

      enterpriseAttestationPossiblefalse로 설정합니다.

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

    7. 만약 pkOptions.attestation

      설정이 none인 경우

      attestationFormats를 단일 요소 리스트 ["none"]로 설정합니다.

    8. excludeCredentialDescriptorList를 새 list로 둡니다.

    9. 각각의 C에 대해 pkOptions.excludeCredentials의 credential descriptor:

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

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

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

    10. authenticator에서 authenticatorMakeCredential 연산을 호출합니다. 인수로는 clientDataHash, pkOptions.rp, pkOptions.user, requireResidentKey, userVerification, credTypesAndPubKeyAlgs, excludeCredentialDescriptorList, enterpriseAttestationPossible, attestationFormats, 및 authenticatorExtensions.
    11. Append authenticatorissuedRequests에 추가합니다.

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

    Remove authenticatorissuedRequests에서 제거합니다.

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

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

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

    만약 어떤 authenticator가 "InvalidStateError"에 해당하는 오류 상태를 반환하면,
    1. Remove 해당 authenticatorissuedRequests에서 제거합니다.

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

    3. "InvalidStateError" DOMException을 던집니다.

    참고: 이 오류 상태는 excludeCredentialDescriptorList가 해당 authenticator에 바인드된 자격 증명을 식별하고 사용자가 작업에 동의한 경우에만 인증기가 반환하기 때문에 별도로 처리됩니다. 이 명시적 동의를 고려하면 이 경우가 Relying Party에 대해 구별 가능한 것이 허용됩니다.

    만약 어떤 authenticator가 "InvalidStateError"이 아닌 오류 상태를 반환하면,

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

    참고: 이 경우는 작업에 대한 사용자 동의를 의미하지 않으므로, 오류에 대한 세부 정보는 잠재적으로 식별 가능한 정보를 유출하지 않기 위해 Relying Party로부터 숨겨집니다. 자세한 내용은 § 14.5.1 Registration Ceremony Privacy를 참조하세요.

    만약 어떤 authenticator가 성공을 표시하면,
    1. Remove 해당 authenticatorissuedRequests에서 제거합니다. 이 인증기는 이제 selected authenticator가 됩니다.

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

      attestationObjectResult

      성공한 authenticatorMakeCredential 연산으로부터 반환된 바이트입니다.

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

      clientDataJSONResult

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

      attestationConveyancePreferenceOption

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

      clientExtensionResults

      그 값은 각 확장에 대해 client extension processing 알고리즘을 실행하여 생성된 client extension output 항목들을 포함하는 AuthenticationExtensionsClientOutputs 객체입니다.

    3. constructCredentialAlg을 다음과 같은 알고리즘으로 둡니다: 이 알고리즘은 전역 객체 global을 인수로 받고 다음 단계를 수행합니다:

      1. 만약 credentialCreationData.attestationConveyancePreferenceOption의 값이

        none

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

        1. 만약 aaguid가 16 바이트 0이고, attested credential data 내에서, 그리고 credentialCreationData.attestationObjectResult.fmt이 "packed"이며 "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

        클라이언트는 더 프라이버시 친화적이거나 검증하기 쉬운 버전(예: Anonymization CA를 사용하는 방식)으로 aaguidattestation statement를 대체할 수 있습니다.

        direct 또는 enterprise

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

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

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

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

        [[identifier]]

        id

        authenticatorAttachment

        현재 authenticatorauthenticator attachment modality와 일치하는 AuthenticatorAttachment 값입니다.

        response

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

        clientDataJSON

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

        attestationObject

        attestationObject

        [[transports]]

        사전식(lexicographical) 순서로 정렬된 0개 이상의 고유한 DOMString들의 시퀀스로, 해당 authenticator가 지원하는 것으로 여겨지는 전송 방식들입니다. 이 값들은 AuthenticatorTransport의 멤버여야 하지만, client platforms는 알 수 없는 값을 무시해야 합니다.

        만약 사용자 에이전트가 이 정보를 드러내고 싶지 않으면, 프라이버시를 보존하기 위한 임의의 시퀀스를 대신 반환할 수 있습니다. 이 시퀀스는 여전히 유효해야 합니다(사전식 정렬 및 중복 없음). 예를 들면 빈 시퀀스를 사용할 수 있습니다. 이 경우 Relying Party 동작이 최적이 아닐 수 있습니다.

        만약 사용자 에이전트가 전송 정보가 없다면, 이 필드를 빈 시퀀스로 설정하는 것이 권장됩니다.

        참고: 특정 authenticator가 지원하는 전송을 사용자 에이전트가 어떻게 발견하는지는 본 명세의 범위를 벗어나지만, attestation certificate, CTAP2와 같은 인증기 프로토콜의 메타데이터, 혹은 플랫폼 인증기에 대한 특수 지식 등에서 정보를 얻을 수 있습니다.

        [[clientExtensionsResults]]

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

      5. pubKeyCred를 반환합니다.

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

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

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

위 과정 동안 사용자 에이전트는 인증기 선택 및 승인 과정을 안내하기 위해 사용자에게 일부 UI를 보여주는 것이 권장됩니다. 만약 options.mediationconditional로 설정되어 있으면, 이전에 사용자 에이전트가 결정한 수단으로 자격 증명 생성이 미리 동의되지 않은 경우를 제외하고 눈에 띄는 모달 UI를 표시해서는 안 됩니다.

5.1.3.1. 생성 요청 예외

이 절은 규범적이지 않습니다.

WebAuthn Relying Partiesnavigator.credentials.create() 호출에서 여러 예외를 마주칠 수 있습니다. 일부 예외는 발생 원인이 여러 가지일 수 있어, WebAuthn Relying Parties가 WebAuthn 사용 상황을 바탕으로 실제 원인을 추론해야 할 수 있습니다.

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

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

AbortError

절차가 AbortController에 의해 취소되었습니다. 자세한 내용은 § 5.6 Abort Operations with AbortSignal§ 1.3.4 Aborting Authentication Operations를 참조하세요.

ConstraintError

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

InvalidStateError

인증 과정에서 사용된 인증기가 사용자가 동의한 후에 excludeCredentials 목록에 있는 항목을 인식했을 때 발생합니다.

NotSupportedError

pubKeyCredParams 에 있는 항목 중 어떤 것도 typepublic-key 이 아니었거나, authenticatorpubKeyCredParams 에 명시된 서명 알고리즘 중 어느 것도 지원하지 않는 경우입니다.

SecurityError

effective domain이 유효한 domain이 아니거나, 또는 rp.ideffective domain과 같거나 그 등록 가능한 도메인 접미사가 아닌 경우입니다. 후자의 경우, 클라이언트는 related origin requests를 지원하지 않거나 related origins validation procedure가 실패한 것입니다.

NotAllowedError

사용자가 절차를 취소하는 등 다양한 가능한 원인을 포괄하는 포괄적 오류입니다. 이러한 원인 중 일부는 이 명세 전반에 문서화되어 있으며, 다른 것들은 클라이언트 특유의 원인일 수 있습니다.

다음의 단순 예외(simple exceptions)들도 발생할 수 있습니다:

TypeError

options 인수가 유효한 CredentialCreationOptions 값이 아니거나, user.id 의 값이 비어 있거나 64 바이트보다 긴 경우입니다.

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

WebAuthn Relying Partiesnavigator.credentials.get({publicKey:..., ...}) 를 호출하여 기존의 public key credential을 검색하고 사용자 동의(user’s consent)를 얻어 사용합니다. Relying Party 스크립트는 선택적으로 어떤 public key credential sources가 허용되는지에 대한 기준을 지정할 수 있습니다. client platform은 지정된 기준에 맞는 public key credential sources를 찾아 사용자가 스크립트가 사용하도록 허용할 자격 증명을 선택하도록 안내합니다. 예를 들어 사용자는 프라이버시를 유지하기 위해 전체 상호작용을 거부할 수 있습니다. 사용자가 public key credential source를 선택하면, 사용자 에이전트는 § 6.3.3 The authenticatorGetAssertion Operation을 사용하여 Relying Party가 제공한 challenge와 다른 수집된 데이터를 서명해 authentication assertion을 생성하고, 이를 credential로 사용합니다.

navigator.credentials.get() 구현은 [CREDENTIAL-MANAGEMENT-1]에 따라 PublicKeyCredential.[[CollectFromCredentialStore]]() 를 호출하여 사용자 중재 없이 사용 가능해야 할 credentials을 수집합니다(대략적으로 이 명세의 authorization gesture). 만약 정확히 하나가 발견되지 않으면, PublicKeyCredential.[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 를 호출하여 사용자가 public key credential source를 선택하도록 합니다.

이 명세는 어떤 authorization gesture이든 간에 어설션을 생성하려면 필요하므로, PublicKeyCredential[[CollectFromCredentialStore]](origin, options, sameOriginWithAncestors) 의 기본 동작(빈 집합 반환)을 상속합니다. PublicKeyCredential[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 구현은 다음 섹션에서 명세됩니다.

일반적으로 사용자 에이전트는 인증기 선택 및 승인 과정을 사용자에게 안내하기 위해 일부 UI를 표시해야 합니다. options.mediationconditional 로 설정하면, Relying Parties는 자격 증명이 발견되지 않는 한 눈에 띄는 모달 UI를 표시하지 않도록 요청할 수 있습니다. Relying Party는 이 기능이 사용 가능한지 확인하기 위해 먼저 isConditionalMediationAvailable() 또는 getClientCapabilities() 를 사용하여 clientconditionalGet 기능을 지원하는지 확인해야 합니다. 그렇지 않으면 사용자에게 보이는 오류가 발생할 수 있습니다.

모든 navigator.credentials.get() 작업은 AbortController 를 사용하여 중단될 수 있습니다; 자세한 지침은 DOM § 3.3 Using AbortController and AbortSignal objects in APIs를 참조하세요.

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 Relying Partiesnavigator.credentials.get() 호출에서 여러 예외를 만날 수 있습니다. 일부 예외는 발생 원인이 여러 개인 경우가 있어, WebAuthn Relying Parties가 WebAuthn 사용 상황을 바탕으로 실제 원인을 추론해야 할 수 있습니다.

Note: 이 명세 외부에서 정의된 것을 포함하여 모든 WebAuthn Extensions의 처리 중 발생할 수 있는 예외는 여기에는 나열되지 않습니다.

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

AbortError

절차가 AbortController에 의해 취소되었습니다. 자세한 내용은 § 5.6 Abort Operations with AbortSignal§ 1.3.4 Aborting Authentication Operations를 참조하세요.

SecurityError

effective domain이 유효한 domain이 아니거나, 또는 rp.ideffective domain과 같거나 그 등록 가능한 도메인 접미사가 아닌 경우입니다. 후자의 경우, 클라이언트는 related origin requests를 지원하지 않거나 related origins validation procedure가 실패한 것입니다.

NotAllowedError

사용자가 절차를 취소하는 등 다양한 가능한 원인을 포괄하는 포괄적 오류입니다. 이러한 원인들 중 일부는 이 명세 전반에 문서화되어 있으며, 다른 것들은 클라이언트 특유의 원인일 수 있습니다.

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

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();
};

Note: 이 메서드를 browsing context에서 호출했을 때 해당 컨텍스트가 Web Authentication API에 대해 "사용 금지(disabled)"로 판단되면(예: allowed to use 알고리즘에 의해), 프라미스는 이름이 "NotAllowedError"인 DOMException으로 거절됩니다. 자세한 내용은 § 5.9 Permissions Policy integration을 참조하세요.

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는 인증기에서 그 확장의 처리가 수행될 것이라고 가정해서는 안 됩니다.

Note: 이 메서드를 browsing context에서 호출했을 때 해당 컨텍스트가 Web Authentication API에 대해 "사용 금지(disabled)"로 판단되면(예: allowed to use 알고리즘에 의해), 프라미스는 이름이 "NotAllowedError"인 DOMException으로 거절됩니다. 자세한 내용은 § 5.9 Permissions Policy integration을 참조하세요.

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

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

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

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

만약 client가 JSON 타입 표현을 파싱하는 중에 문제가 발생하면, 호환되지 않는 값에 대한 설명을 포함한 "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. effectiveDomainrelevant settings objectorigineffective domain으로 둡니다. 만약 effectiveDomain이 유효한 domain이 아니면 "SecurityError" DOMException로 거절된 프라미스를 반환합니다.

  2. 만약 rpIdeffectiveDomain의 registrable domain suffix이거나 같다면, undefined로 해결된 프라미스를 반환합니다.

  3. 만약 클라이언트가 related origin requests를 지원하지 않으면 "SecurityError" DOMException로 거절된 프라미스를 반환합니다.

  4. p를 새 프라미스로 둡니다.

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

    1. 만약 related origins validation procedurecallerOriginrpId로 실행한 결과가 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포함하지 않는다면, credentialcredentials map에서 제거하거나 인증기별 절차를 사용해 이후 인증 절차에서 숨깁니다.

  6. 그렇지 않고, 만약 credential이 인증기별 절차로 이미 숨겨져 있다면, 그 조치를 되돌려 credential이 이후의 인증 절차에서 나타나도록 합니다.

사용자는 두 개의 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 멤버는 자격 증명이 RP ID에 범위(scope)되어야 함을 지정합니다. 생략하면 해당 값은 CredentialsContainer 객체의 relevant settings objectorigineffective domain이 됩니다. 자세한 내용은 § 5.4.2 Relying Party Parameters for Credential Generation (dictionary PublicKeyCredentialRpEntity)를 참조하세요.

user, of type PublicKeyCredentialUserEntity

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

값의 name, displayNameid 멤버는 필수입니다. id는 향후 인증 절차에서 userHandle로 반환될 수 있으며, 동일한 rp.iduser.id를 가진 discoverable credentials를 덮어쓰는 데 사용됩니다. namedisplayName는 인증기 및 클라이언트가 향후 인증 절차에서 사용자를 도울 목적으로 사용할 수 있으나, 향후 인증 절차의 결과로 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

이 멤버는 새로 생성된 자격 증명에 대한 authenticator가 다른 데이터와 함께 서명하는 challenge를 지정합니다. 보안 고려 사항에 대해서는 § 13.4.3 Cryptographic Challenges를 참조하세요.

pubKeyCredParams, of type sequence<PublicKeyCredentialParameters>

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

다양한 인증기를 지원하려는 Relying Parties는 적어도 다음 COSEAlgorithmIdentifier 값을 포함하는 것이 권장됩니다:

  • -8 (Ed25519)

  • -7 (ES256)

  • -257 (RS256)

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

timeout, of type unsigned long

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

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

Relying Party는 이 선택적 멤버를 사용하여 해당 credentials 중 사용자의 계정(user.id)에 매핑된 기존 자격 증명을 나열해야 합니다. 이는 새 자격 증명이 이미 해당 자격 증명을 포함하는 인증기에서 생성되지 않도록 하기 위함입니다. 만약 그렇다면 클라이언트는 대신 사용자가 다른 인증기를 사용하도록 안내하거나, 실패할 경우 오류를 반환하도록 요청받습니다.

authenticatorSelection, of type AuthenticatorSelectionCriteria

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

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

이 선택적 멤버는 사용자 에이전트가 사용자와 상호작용할 때 안내하기 위한 PublicKeyCredentialHint의 0개 이상의 요소를 포함합니다. 요소의 타입은 DOMString입니다. 자세한 내용은 § 2.1.1 Enumerations as DOMString types를 참조하세요.

attestation, of type DOMString, defaulting to "none"

Relying Party는 이 선택적 멤버를 사용하여 attestation conveyance에 관한 선호를 지정할 수 있습니다. 값은 AttestationConveyancePreference의 멤버여야 하는 것이 권장됩니다. Client platforms는 알 수 없는 값을 무시하고, 해당 멤버가 존재하지 않는 것처럼 처리해야 합니다.

기본값은 none입니다.

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

Relying Party는 이 선택적 멤버를 사용하여 인증기가 사용할 attestation statement 형식에 대한 선호를 지정할 수 있습니다. 값은 IANA "WebAuthn Attestation Statement Format Identifiers" 레지스트리에서 가져온 것이어야 하며, 값들은 가장 선호하는 것에서 덜 선호하는 것 순으로 정렬됩니다. 중복은 허용되지만 사실상 무시됩니다. 이 매개변수는 자문의 성격을 가지며 인증기는 이 매개변수에 열거되지 않은 attestation statement를 사용할 수 있습니다.

기본값은 기본 목록(빈 목록)으로, 선호가 없음을 나타냅니다.

extensions, of type AuthenticationExtensionsClientInputs

Relying Party는 이 선택적 멤버를 사용하여 클라이언트 및 인증기가 추가 처리를 수행하도록 요청하는 client extension inputs을 제공할 수 있습니다. 예를 들어, Relying Party는 클라이언트가 생성된 credential에 관한 추가 정보를 반환하도록 요청할 수 있습니다.

확장 프레임워크는 § 9 WebAuthn Extensions에 정의되어 있습니다. 일부 확장은 § 10 Defined Extensions에 정의되어 있으니, 최신 등록 확장 목록은 IANA "WebAuthn Extension Identifiers" 레지스트리를 참조하세요.

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

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

dictionary PublicKeyCredentialEntity {
    required DOMString    name;
};
name, 유형 DOMString

엔터티의 사용자 친화적 이름입니다. 이 기능은 PublicKeyCredentialEntity 가 나타내는 대상에 따라 다릅니다:

클라이언트, 클라이언트 플랫폼 또는 인증기name 값 표시 시, 항상 UI 엘리먼트를 사용하여 해당 값의 경계를 명확하게 하고, 다른 요소로 넘침이 발생하지 않도록 해야 합니다 [css-overflow-3].

name 멤버 값을 저장할 때, § 6.4.1 문자열 잘림에서 설명한 대로 최소 64바이트 이상의 크기 제한을 이용해 잘릴 수 있습니다.

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

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

dictionary PublicKeyCredentialRpEntity : PublicKeyCredentialEntity {
    DOMString      id;
};
id, 유형 DOMString

Relying Party 엔터티의 고유 식별자로, RP ID를 설정합니다.

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

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

dictionary PublicKeyCredentialUserEntity : PublicKeyCredentialEntity {
    required BufferSource   id;
    required DOMString      displayName;
};
id, 유형 BufferSource

사용자 핸들로, 사용자 계정의 식별자입니다. 사용자 핸들은 최대 64바이트 크기의 불투명 바이트 시퀀스이고, 사용자에게 표시되지 않습니다.

안전한 동작을 보장하기 위해, 인증 및 권한 결정은 반드시 이 id 멤버를 기반으로 해야 하며, displayName이나 name 멤버는 사용하지 않아야 합니다. 자세한 내용은 [RFC8266] 6.1절 참고.

사용자 핸들에는 사용자에 관한 개인정보(사용자 이름, 이메일 등)가 포함되어서는 안 됩니다; 상세 내용은 § 14.6.1 사용자 핸들 구성 참고. 사용자 핸들은 비어 있을 수 없습니다.

사용자 핸들은 서로 다른 사용자 계정 간에 고정 값이어선 안 되며, 일부 인증기는 항상 탐색 가능한 자격 증명을 생성하므로, 일정한 사용자 핸들은 한 인증기로 두 개 이상의 계정을 사용할 수 없게 합니다.

displayName, 유형 DOMString

사용자 계정사용자 친화적 이름으로, 오직 표시 용도로만 사용됩니다. Relying Party는 사용자가 직접 선택하도록 해야 하며, 필요 이상으로 선택을 제한해서는 안 됩니다. 적합하거나 사용자 친화적 이름이 없다면, 비어있는 문자열로 설정해야 합니다.

예시: "Alex Müller", "Alex Müller (ACME Co.)" 또는 "田中倫" 등.

클라이언트, 클라이언트 플랫폼 또는 인증기displayName 값 표시 시 항상 UI 엘리먼트를 사용하여 해당 값의 경계를 명확히 구분하고, 다른 요소로의 오버플로우가 없도록 해야 합니다 [css-overflow-3].

displayName 멤버 값을 저장할 때, § 6.4.1 문자열 잘림에서 설명한 대로 최소 64바이트 이상의 크기 제한으로 잘릴 수 있습니다.

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

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

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

이 멤버가 존재하면, 적격 인증기는 지정된 인증기 연결 방식 (§ 6.2.1 인증기 연결 방식 참고)으로만 필터링됩니다. 존재하지 않으면 어떤 연결 방식이라도 허용됩니다. 값은 AuthenticatorAttachment 의 멤버여야 하며, 클라이언트 플랫폼은 알 수 없는 값을 무시하고, 해당 멤버가 존재하지 않는 것처럼 처리해야 합니다.

또한 authenticatorAttachment 멤버( PublicKeyCredential)에서 어떤 인증기 연결 방식이 사용되었는지 알 수 있습니다. ( create() 또는 get() 작업 성공시)

residentKey, 유형 DOMString

Relying Party클라이언트 측에서 탐색 가능한 자격 증명 생성을 얼마나 원하는지 지정합니다. 과거 명칭에서 유래된 “resident” 용어를 그대로 사용합니다. 값은 ResidentKeyRequirement 의 멤버여야 하며, 클라이언트 플랫폼은 알 수 없는 값은 무시하고 해당 멤버 미존재로 취급해야 합니다. 값이 없으면, requireResidentKeytrue인 경우에는 required , false 또는 미존재인 경우에는 discouraged 입니다.

ResidentKeyRequirement 참조 – residentKey 값의 의미 및 설명.

requireResidentKey, 유형 boolean, 기본값 false

이 멤버는 WebAuthn Level 1부터의 이전 호환을 위해 남아 있으며, 탐색 가능한 자격 증명에 대해 “resident” 용어를 계속 사용합니다. Relying PartiesresidentKeyrequired 로 설정한 경우에만 true로 설정해야 합니다.

userVerification, 유형 DOMString, 기본값 "preferred"

이 멤버는 Relying Partycreate() 작업에서 사용자 검증 에 대해 요구하는 사항을 지정합니다. 값은 UserVerificationRequirement 의 멤버여야 하며, 클라이언트 플랫폼은 알 수 없는 값을 무시하고 해당 멤버 미존재로 취급해야 합니다.

UserVerificationRequirement 참조 – userVerification 값의 의미 및 설명.

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

이 열거형의 값들은 인증기연결 방식을 설명합니다. Relying Parties연결 방식 선호도를 navigator.credentials.create() 를 호출하여 자격 증명 생성할 때 지정할 수 있고, 클라이언트연결 방식을 등록 또는 등록이나 인증 절차 완료 시 보고합니다.

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

참고: AuthenticatorAttachment 열거형은 의도적으로 참조되지 않습니다. § 2.1.1 DOMString으로서의 열거형 참고.

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 DOMString으로서의 열거형 참고.

이 열거형의 값들은 클라이언트 측에서 탐색 가능한 자격 증명(이전에는 리던트 자격 증명 또는 리던트 키로 알려짐)에 대해 Relying Party의 요구사항을 설명합니다:

discouraged

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

참고: Relying Party는 생성된 자격 증명이 서버 측 자격 증명임을 강제할 수 없습니다. Credential Properties Extensionrk 속성에 값이 반환되지 않을 수도 있습니다. 이 때문에, 실제로 해당 자격 증명이 서버 측 자격 증명인지 여부를 알지 못해, 동일 사용자 핸들로 두 번째 자격 증명을 만들면 첫 번째 자격 증명이 삭제되는지 알 수 없습니다.

preferred

Relying Party클라이언트 측에서 탐색 가능한 자격 증명 생성을 강하게 선호하지만, 서버 측 자격 증명도 허용합니다. 클라이언트인증기는 가능하면 탐색 가능한 자격 증명을 생성해야 합니다. 예를 들어, 클라이언트사용자 검증 절차 안내를 통해 탐색 가능한 자격 증명을 생성하도록 안내해야 합니다. 이 옵션은 userVerification 값보다 우선합니다.

required

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

참고: Relying Party는 인증기가 클라이언트 측에서 탐색 가능한 자격 증명을 생성했는지 여부를 resident key credential property (Credential Properties Extension)로 확인할 수 있습니다. 이는 discouraged 또는 preferredoptions.authenticatorSelection.residentKey 에 사용된 경우, 해당 시점의 인증기클라이언트 측 탐색 가능 자격 증명이든 서버 측 자격 증명이든 생성 가능성이 있기 때문입니다.

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

WebAuthn Relying Parties는 자격 증명 생성 중 attestation conveyance에 대해 선호를 지정하기 위해 AttestationConveyancePreference를 사용할 수 있습니다.

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

참고: AttestationConveyancePreference 열거형은 의도적으로 참조되지 않았으며, § 2.1.1 DOMString 타입의 열거형을 참고하세요.

none

Relying Party인증기 attestation에 관심이 없습니다. 예를 들어, 사용자 동의를 받고 식별 정보를 Relying Party로 전달해야 하는 상황을 피하거나, Attestation CA 또는 Anonymization CA와의 추가 roundtrip을 줄이기 위해 사용할 수 있습니다. 인증기self attestation이 아닌 attestation statement를 생성하는 경우, 클라이언트는 해당 값을 None attestation statement로 대체합니다.

이 값이 기본값이며, 알 수 없는 값도 이 값의 동작으로 돌아갑니다.

indirect

Relying Party는 검증 가능한 attestation statement를 받고자 하지만, 이러한 attestation statement를 어떻게 획득할지에 대해 클라이언트가 결정하도록 허용합니다. 클라이언트는 인증기에서 생성된 attestation statement를 사용자의 프라이버시를 보호하거나, 또는 이기종 생태계에서 Relying Party의 attestation 검증을 돕기 위해 익명화 CA(Anonymization CA)가 생성한 것으로 대체할 수 있습니다.

참고: 이 경우 반드시 Relying Party가 검증 가능한 attestation statement를 얻는다는 보장은 없습니다. 예를 들어, 인증기가 self attestation을 사용하고 클라이언트가 해당 statement를 그대로 전달하는 경우입니다.

direct

Relying Party인증기가 생성한 attestation statement 그 자체를 받길 원합니다.

enterprise

Relying Party는 비즈니스용 attestation, 즉 인증기를 고유하게 식별하는 정보가 포함될 수 있는 attestation statement를 받길 원합니다. 이는 기업 내에서 등록을 특정 인증기에 연결하고자 하는 통제된 배포용입니다. 사용자 에이전트는 해당 RP ID용으로 사용자 에이전트 혹은 인증기 설정이 허용하지 않는 이상, 이러한 attestation을 제공해서는 안 됩니다.

허용되는 경우, 사용자 에이전트는 인증기에게 비즈니스용 attestation 요청 신호를 보내고(호출 시점), 결과로 나온 AAGUIDattestation statement를 수정 없이 Relying Party로 전달해야 합니다.

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, 유형 BufferSource

이 멤버는 인증기authentication assertion을 생성할 때 다른 데이터와 함께 서명하는 챌린지를 지정합니다. 자세한 보안 고려사항은 § 13.4.3 암호화 챌린지를 참고하세요.

timeout, 유형 unsigned long

이 선택적 멤버는 Relying Party가 호출 완료 대기 가능 시간(밀리초)을 지정합니다. 이 값은 힌트로 취급되며, 클라이언트가 재정의할 수 있습니다.

rpId, 유형 DOMString

이 선택적 멤버는 Relying Party가 주장하는 RP ID를 지정합니다. 클라이언트Relying Partyorigin이 이 RP IDscope와 일치하는지 반드시 확인해야 합니다. 인증기는 인증에 사용할 자격 증명rpId와 이 RP ID가 정확히 일치하는지도 반드시 확인해야 합니다.

지정하지 않은 경우 CredentialsContainer 객체의 relevant settings objectorigineffective domain이 값으로 사용됩니다.

allowCredentials, 유형 sequence<PublicKeyCredentialDescriptor>, 기본값 []

이 선택적 멤버는 클라이언트가 이 인증 과정에 적합한 인증기를 찾을 때 사용됩니다. 사용 예시는 두 가지입니다:

비워두지 않은 경우, 목록 내 어떤 자격 증명도 사용할 수 없다면 클라이언트는 오류를 반환해야 합니다.

목록은 선호도 순으로 내림차순 정렬되어 있습니다. 즉, 첫 번째 항목이 가장 선호되고, 마지막이 덜 선호됩니다.

userVerification, 유형 DOMString, 기본값 "preferred"

이 선택적 멤버는 get() 동작에서 Relying Partyuser verification 요구사항을 지정합니다. 값은 UserVerificationRequirement의 멤버여야 하며, 클라이언트 플랫폼은 알 수 없는 값을 무시하고 해당 멤버가 없는 것처럼 취급해야 합니다. 적합한 인증기는 오직 이 요구조건을 충족하는 것만 필터링됩니다.

UserVerificationRequirement에서 userVerification 값과 의미를 참고하세요.

hints, 유형 sequence<DOMString>, 기본값 []

이 선택적 멤버는 PublicKeyCredentialHint 에서 가져온 하나 이상의 요소로, 사용자 에이전트가 사용자와 상호작용할 때 지침으로 사용됩니다. 값이 나열형에서 유래했지만 실질 타입은 DOMString임에 주의. (§ 2.1.1 DOMString 타입의 열거형 참고)

extensions, 유형 AuthenticationExtensionsClientInputs

Relying Party는 이 선택적 멤버로 클라이언트 확장 입력값을 제공해 클라이언트인증기에게 추가 처리를 요청할 수 있습니다.

확장 프레임워크는 § 9 WebAuthn 확장에서 정의되어 있습니다. 일부 확장은 § 10 정의된 확장에 서술되어 있습니다. 등록된 최신 WebAuthn 확장 목록은 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)도 동일합니다.

Window 객체의 visibilityfocus 상태는 [[Create]](origin, options, sameOriginWithAncestors)[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 동작의 진행 여부를 결정합니다. Document와 연관된 Window 객체가 포커스를 잃으면, 위 작업들은 중단되어야 합니다.

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] 상태에 대한 정보를 포함합니다. 값이 없으면 클라이언트가 토큰 바인딩을 지원하지 않음을 의미합니다.

참고: 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여야 합니다(통신에 사용된 값).

참고: 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, 유형 DOMString

이 멤버는 참조하는 공개 키 자격 증명의 타입을 담고 있습니다. 값은 PublicKeyCredentialType 의 멤버여야 하지만 클라이언트 플랫폼은 알 수 없는 PublicKeyCredentialDescriptortype을 무시해야 합니다. 단, 모든 요소가 알 수 없는 type 때문에 무시된다면, 빈 allowCredentials 과는 의미적으로 다르므로 오류로 처리해야 합니다.

이 값은 type 항목 값을 반영해야 하며, 이는 자격 증명 기록이 나타내는 공개 키 자격 증명 소스의 값입니다. type 필드와도 대응합니다.

id, 유형 BufferSource

이 멤버는 참조하는 공개 키 자격 증명자격 증명 ID를 담고 있습니다.

이 값은 id 항목 값을 반영해야 하며, 이는 자격 증명 기록이 나타내는 공개 키 자격 증명 소스의 값입니다. rawId 필드와도 대응합니다.

transports, 유형 sequence<DOMString>

이 선택적 멤버는 참조하는 공개 키 자격 증명관리 인증기와 클라이언트가 어떻게 통신할지에 대한 힌트입니다. 이 값들은 AuthenticatorTransport 의 멤버여야 하지만, 클라이언트 플랫폼은 알 수 없는 값은 무시해야 합니다.

이 값은 transports 항목 값을 반영해야 하며, 이는 자격 증명 기록이 나타내는 공개 키 자격 증명 소스의 값입니다. response.getTransports() 메소드와도 동일합니다. PublicKeyCredential 구조의 create() 작업에서 생성됩니다.

5.8.4. 인증기 전송 방식 열거형(enum AuthenticatorTransport)

enum AuthenticatorTransport {
    "usb",
    "nfc",
    "ble",
    "smart-card",
    "hybrid",
    "internal"
};

참고: AuthenticatorTransport 열거형은 의도적으로 참조되지 않았으며, § 2.1.1 DOMString 타입의 열거형을 참고하세요.

인증기여러 전송 방식을 구현할 수 있습니다. 클라이언트가 특정 자격 증명에 대해 인증기로부터 어설션을 얻으려면 인증기와 클라이언트가 어떻게 통신하는지에 대한 힌트로 이 열거형을 사용할 수 있습니다. 이 힌트는 WebAuthn Relying Party가 인증기에 접근하는 최선의 추정입니다. Relying Party공개 키 자격 증명의 지원 전송 방식을 getTransports() 를 이용해 알게 됩니다.
usb

해당 인증기가 탈착 USB를 통해 연결될 수 있음을 나타냅니다.

nfc

해당 인증기가 근거리 무선 통신(NFC)으로 연결될 수 있음을 나타냅니다.

ble

해당 인증기가 블루투스 스마트(Bluetooth Low Energy / BLE)로 연결될 수 있음을 나타냅니다.

smart-card

해당 인증기가 ISO/IEC 7816 스마트카드(접점식)로 연결될 수 있음을 나타냅니다.

hybrid

해당 인증기가 데이터 전송과 근접 메커니즘을 조합해 연결될 수 있음을 나타냅니다. 예로 스마트폰을 사용해 데스크톱 컴퓨터에서 인증할 때 활용 가능합니다.

internal

해당 인증기클라이언트 디바이스의 특수 전송 방식으로 접근됨을 의미하며, 즉 플랫폼 인증기입니다. 이러한 인증기는 클라이언트 디바이스에서 분리할 수 없습니다.

5.8.5. 암호 알고리즘 식별자 (typedef COSEAlgorithmIdentifier)

typedef long COSEAlgorithmIdentifier;
COSEAlgorithmIdentifier 값은 암호 알고리즘을 식별하는 숫자입니다. 알고리즘 식별자는 IANA COSE Algorithms registry [IANA-COSE-ALGS-REG]에 등록된 값이어야 하며, 예시로 "ES256"은 -7, "RS256"은 -257 등입니다.

COSE 알고리즘 레지스트리는 COSE 키에서 추가 매개변수로 자유도를 남깁니다. 상호운용성을 위해, 본 명세는 credential public key에 대해 다음을 보증합니다.

  1. 알고리즘 ES256(-7) 키는 crv 매개변수를 반드시 P-256(1)로 지정하고, 압축 점 형식을 사용해서는 안 됩니다.

  2. 알고리즘 ES384(-35) 키는 반드시 P-384(2)를 crv 매개변수로 지정하고, 압축 점 형식을 쓰면 안 됩니다.

  3. 알고리즘 ES512(-36) 키는 반드시 P-521(3)을 crv 매개변수로 지정하고, 압축 점 형식을 허용하지 않습니다.

  4. 알고리즘 EdDSA(-8) 키는 반드시 Ed25519(6)을 crv 매개변수로 지정해야 합니다. (COSE에서 항상 압축 형태를 사용.)

이러한 제한은 RFC9053의 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는 이 열거를 통해 user-agent가 요청을 최적으로 완료할 수 있도록 힌트를 전달할 수 있습니다. 이러한 힌트는 필수가 아니며 user-agent를 강제하지 않지만, Relying Party가 요청에 대해 가지고 있는 상황 정보를 활용하여 최상의 경험을 제공할 수 있도록 user-agent를 안내할 수 있습니다. 힌트들은 우선순위가 높은 순서대로 제공되며, 두 힌트가 상충할 경우 앞선 힌트가 우선합니다. 힌트는 또한 중첩될 수 있습니다: 더 구체적인 힌트가 정의된 경우, Relying Party는 더 구체적이지 않은 힌트도, 일부 user-agent가 더 구체적인 힌트를 인식하지 못할 수 있다는 점을 고려하여 함께 전송할 수 있습니다. 이 경우 가장 구체적인 힌트를 먼저, 덜 구체적인 힌트를 나중에 보내야 합니다. 동일한 힌트가 두 번 이상 나타나는 경우, 두 번째 이후로 나타나는 항목은 무시됩니다.

힌트는 credential의 transportsauthenticatorAttachment에 포함된 정보와 모순될 수 있습니다. 이 경우 힌트가 우선합니다. (transports 값은 discoverable credentials를 사용할 때는 제공되지 않으므로, 이러한 요청의 일부 측면을 표현하는 유일한 방법으로 힌트가 사용될 수 있습니다.)

security-key

Relying Party가 사용자가 실제 보안 키로 이 요청을 충족하리라 판단한다는 점을 나타냅니다. 예를 들어, 엔터프라이즈 Relying Party가 직원들에게 보안 키를 배포했으며, 해당 키만을 authenticator등록인증에 허용하고자 할 때 이 힌트를 설정할 수 있습니다.

구버전 user agent와의 호환성을 위해, 이 힌트가 PublicKeyCredentialCreationOptions 내에서 사용될 경우 authenticatorAttachment 값을 cross-platform 으로 지정해야 합니다.

client-device

Relying Party가 사용자가 클라이언트 디바이스에 연결된 플랫폼 인증기로 이 요청을 충족하리라 판단한다는 점을 나타냅니다.

구버전 user agent와의 호환성을 위해, 이 힌트가 PublicKeyCredentialCreationOptions 내에서 사용될 경우 authenticatorAttachment 값을 platform으로 지정해야 합니다.

hybrid

Relying Party가 사용자가 스마트폰과 같은 범용 인증기로 이 요청을 충족하리라 판단한다는 점을 나타냅니다. 예를 들어, 소비자 Relying Party가 전용 보안 키를 가진 고객의 비율이 매우 적다고 판단하는 경우입니다. 이 옵션은 또한 로컬 플랫폼 인증기가 UI에 표시되지 않아야 함을 의미합니다.

구버전 user agent와의 호환성을 위해, 이 힌트가 PublicKeyCredentialCreationOptions 내에서 사용될 경우 authenticatorAttachment 값을 cross-platform으로 지정해야 합니다.

5.9. Permissions Policy 통합

이 명세는 "publickey-credentials-create" 와 "publickey-credentials-get" 으로 식별되는 두 가지 정책 제어 기능을 정의합니다. 이들의 기본 허용 목록은 모두 'self' 입니다. [Permissions-Policy]

Documentpermissions policy는 해당 문서 내의 모든 콘텐츠가 성공적으로 사용 할 수 있는지, 즉 Web Authentication API (navigator.credentials.create({publicKey:..., ...}) 또는 navigator.credentials.get({publicKey:..., ...})) 를 호출할 수 있는지를 결정합니다. 만약 비활성화되어 있다면, 해당 문서의 콘텐츠는 위의 메서드를 사용할 수 없으며, 시도할 경우 오류를 반환합니다.

Note: [CREDENTIAL-MANAGEMENT-1]에 지정된 알고리즘이 실제 permissions policy 평가를 수행합니다. 이러한 정책 평가는 current settings object에 접근할 수 있을 때 발생해야 하기 때문입니다. [[Create]](origin, options, sameOriginWithAncestors)[[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 내부 메서드는 위와 같이 병렬로 호출되기 때문에 접근할 수 없습니다. CredentialsContainerCreate a CredentialRequest a Credential 추상 연산에서 처리됩니다.

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 feature-identifier 토큰을 각각 allow 속성 값에 포함시켜야 합니다.

Relying Party가 WebAuthn API를 임베디드 컨텍스트에서 사용하는 경우 § 13.4.2 임베디드 사용의 가시성 고려사항에서 UI 변조 및 이에 대한 가능한 완화책에 대해 검토해야 합니다.

기본적으로 Web Authentication은 RP IDorigineffective domain과 같거나, 등록 가능한 도메인 접미사여야 합니다.

이로 인해 여러 국가별 도메인(example.com, example.co.uk, example.sg 등)이나 대체/브랜드 도메인(myexampletravel.com, examplecruises.com 등), 또는 플랫폼 서비스 제공업체를 사용하는 대규모 환경에서 배포가 어려울 수 있습니다.

WebAuthn Relying Parties는 관련 WebAuthn Clients가 여러 origin에 걸쳐 credential을 생성/사용할 수 있도록 선택적으로 허용할 수 있습니다. 이러한 Relying Party는 모든 origin에서 공통된 RP ID를 사용해야 합니다.

JSON 문서는 해당 webauthn well-known URL [RFC8615]에, RP ID에 대해 HTTPS로 반드시 제공되어야 하며, 응답은 아래와 같아야 합니다:

예를 들어, 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 라벨을 지원해야 합니다. 클라이언트 정책에 따라 상한선을 규정할 수 있습니다.

이 well-known endpoint에 대한 WebAuthn Client의 요청은 credentials 없이, referrer 없이, https: 스킴으로 해야 합니다. 리디렉트가 발생하면, WebAuthn Client는 모든 리디렉트가 https: 스킴을 사용할 것을 명확히 요구해야 합니다.

WebAuthn Client가 이 기능을 지원한다면 getClientCapabilities()에 대한 응답에 relatedOrigins 를 반드시 포함해야 합니다.

5.11.1. 관련 origin 검증

관련 origin 검증 절차callerOriginrpIdRequested를 인자로 아래와 같이 동작합니다:

  1. maxLabels를 클라이언트 정책에서 허용하는 등록 가능한 origin 라벨 최대 수로 합니다.

  2. RP ID rpIdRequested에 대해 webauthn well-known URL [RFC8615] (https://rpIdRequested/.well-known/webauthn)을 credentials 없이, referrer 없이, https: 스킴으로 가져옵니다.

    1. 가져오기에 실패하거나 응답의 콘텐츠 타입이 application/json이 아니거나 리디렉트 이후 최종 상태 코드가 200이 아니면, "SecurityError" DOMException을 throw합니다.

    2. 리소스 본문이 올바른 JSON 객체가 아니면, "SecurityError" DOMException을 throw합니다.

    3. JSON 객체의 origins 속성이 없거나 문자열 배열이 아니면, "SecurityError" DOMException을 throw합니다.

  3. labelsSeen을 새로운 빈 집합(set)으로 생성합니다.

  4. originItem에 대해 다음을 수행합니다:

    1. urlURL 파서originItem을 입력값으로 실행한 결과로 합니다. 실패 시 continue 합니다.

    2. domaineffective domain of url로 합니다. null이면 continue 합니다.

    3. label등록 가능한 origin 라벨 of domain으로 합니다.

    4. label이 비어있거나 null이면 continue 합니다.

    5. labelsSeen크기maxLabels 이상이고 labelsSeenlabel이 없으면 continue 합니다.

    6. callerOriginurl동일 origin인 경우, true를 반환합니다.

    7. labelsSeen크기maxLabels 미만이면, labellabelsSeen에 추가합니다.

  5. false를 반환합니다.

6. WebAuthn 인증기 모델

Web Authentication APIWebAuthn 인증기의 구체적인 추상 동작 모델을 내포하고 있습니다. 본 절에서는 인증기 모델을 설명합니다.

클라이언트 플랫폼은 이 추상 모델을 자유롭게 구현하거나 노출할 수 있습니다. 단, 해당 플랫폼이 지원하는 인증기에서 동작하는 Web Authentication API의 동작은 § 5 Web Authentication API에 명시된 동작과 구별 불가능해야 합니다.

Note: [FIDO-CTAP]은 본 모델의 구체적 실체화 예시이지만, 반환 데이터가 WebAuthn API의 알고리즘에서 기대하는 것과 차이가 있습니다. CTAP2 응답 메시지는 문자열 키 대신 정수 키로 CBOR 맵을 구성합니다. 클라이언트가 이러한 데이터 변환을 담당합니다. [FIDO-CTAP] 명세의 §6. Authenticator API에 CTAP2 정수 키와 WebAuthn 문자열 키 매핑이 명시되어 있습니다.

인증기의 경우, 본 모델은 지원해야 할 논리 연산과 클라이언트 및 WebAuthn Relying Party에 노출해야 할 데이터 형식을 정의합니다. 단, 클라이언트 디바이스와의 통신 방법은 상호운용성에 꼭 필요한 부분이 아니라면 정의하지 않습니다. 예를 들어, USB, NFC 등 전송 방식에 대한 프로토콜은 정의하지 않습니다. 또한, 구체적인 오류 코드 유형이나 반환 방법을 정의하지 않지만, 클라이언트가 요구하는 수준에서 오류 동작을 정의합니다. 따라서, 특정 오류 코드가 본문에 언급되더라도, 구현 상 서로 구별(또는 구별하지 않아도 됨)을 보장해야 합니다.

Relying Party는 필요시 다양한 인증기 특성을 지정하여 credentials 생성이나 assertion 생성 시 인증기 선택에 영향을 줄 수 있습니다. 해당 과정은 자격 증명 생성 옵션 또는 assertion 옵션을 통해 이루어집니다. 이런 옵션은 WebAuthn API의 알고리즘이 마샬링하여 아래 정의된 인증기 연산에 전달됩니다.

이 추상 모델에서 인증기는 키 관리와 암호학적 서명을 담당합니다. 인증기는 WebAuthn 클라이언트에 내장될 수도 있고, 별도의 디바이스에 완전히 분리될 수도 있습니다. 인증기 자체는 종종 고신뢰 하드웨어 모듈(예: TPM)을 포함할 수도 있습니다. 특히 인증기가 WebAuthn 클라이언트에 내장된 경우 이 암호 모듈은 나머지 인증기보다 신뢰도가 더 높을 수 있습니다.

각 인증기는 (rpId, userHandle) 쌍에서 public key credential source로의 credentials map (ordered map)을 저장합니다.

또한 각 인증기는 인증기의 종류(제조사, 모델 등)를 나타내는 128비트 식별자인 Authenticator Attestation Globally Unique Identifier 또는 AAGUID를 가집니다. AAGUID는 제조사가 실질적으로 같은 모든 인증기에서 반드시 동일해야 하며, 다른 종류의 인증기와는 (매우 높은 확률로) 달라야 합니다. 각 인증기 종류의 AAGUID는 무작위로 생성하는 것이 바람직합니다. Relying Party는 인증기의 AAGUID를 통해 인증 수준이나 키 보호 강도 등 속성을 다른 출처 정보를 활용하여 추론할 수 있습니다. Relying Partyattestation을 요청·검증하지 않고도 인증기 제조사가 누구인지 AAGUID로 추정할 수 있으나, attestation이 없는 한 AAGUID는 증명력이 없습니다.

인증기의 주요 기능은 다양한 컨텍스트 데이터에 바인딩된 WebAuthn 서명을 제공하는 것입니다. 이 데이터들은 서버에서 인증기로 서명 요청이 전달되는 과정 중 스택의 여러 수준에서 관찰·추가됩니다. 서버는 서명 검증 과정에서 해당 바인딩이 예상값과 일치하는지를 확인합니다. 이러한 컨텍스트 바인딩은 Relying Party 또는 클라이언트가 추가하는 클라이언트 데이터와, 인증기가 추가하는 인증기 데이터로 구분됩니다. 인증기는 클라이언트 데이터 전체가 아닌 그 해시값만 서명에 사용하고, 인증기 데이터를 조합해 전체에 서명합니다. (이는 인증기의 대역폭과 처리 요구사항을 최소화하기 위한 것입니다.)

이 설계의 목표는 다음과 같이 요약할 수 있습니다.

인증기는 암호학적 서명을 두 가지 목적으로 생성합니다:

  1. Attestation signature(인증 서명)public key credentialauthenticatorMakeCredential로 생성될 때 생성됩니다. 인증 서명은 인증기(그의 AAGUID로 표기)와 자격 증명(credential public key 등)의 특정 특성을 증명합니다. 인증 서명은 필요한 경우 attestation private key로 서명되며, attestation 유형에 따라 키 선택이 달라집니다. Attestation에 대한 자세한 내용은 § 6.5 Attestation을 참고하십시오.

  2. Assertion signature(주장 서명)authenticatorGetAssertion이 호출될 때 생성됩니다. 이것은 인증기가 사용자가 특정 트랜잭션(예: 로그인, 결제)에 명시적 동의했음을 확언(주장)하는 서명입니다. 즉, assertion signature는 특정 credential private key를 가진 인증기가 해당 트랜잭션을 요청하는 사용자가 그 credential 생성을 동의한 것과 동일인임을 (최선의 노력으로) 보장합니다. 또한 클라이언트 데이터 등 추가 정보를 제공하며, 사용자 동의 방식 및 인증기가 표시한 프롬프트 등도 포함할 수 있습니다. assertion signature의 형식은 아래 Figure 4를 참고하십시오.

WebAuthn signature라는 용어는 인증 서명주장 서명 모두를 지칭합니다. 이 서명들의 형식 및 생성 절차는 아래서 명시합니다.

6.1. 인증기 데이터

인증기 데이터 구조는 인증기가 만든 컨텍스트적 바인딩을 인코딩합니다. 이 바인딩은 인증기 자체에서 제어하며, 인증기의 보안 특성에 대한 WebAuthn Relying Party의 평가에 따라 신뢰도가 결정됩니다. 경우에 따라 인증기가 클라이언트에 내장되어 있을 수 있고, 그 바인딩의 신뢰도는 클라이언트 데이터와 다를 바 없을 수 있습니다. 반대로, 인증기가 독립된 고보안 하드웨어와 소프트웨어를 갖춘 장치로, 클라이언트와 안전한 채널로 연결될 수도 있습니다. 두 경우 모두 Relying Party는 같은 형식의 인증기 데이터를 받아, 그 인증기에 대한 지식으로 신뢰 판단을 내립니다.

인증기 데이터는 간결하지만 확장 가능한 인코딩을 가지고 있습니다. 이는 인증기가 단순한 소프트웨어 스택과 낮은 전력 소비 등 매우 제한적인 기능의 장치일 수 있기 때문에 필요합니다. 클라이언트 플랫폼보다 훨씬 단순할 수 있습니다.

인증기 데이터 구조는 37 바이트 이상의 바이트 배열이며, 와 같이 구성됩니다.

이름 길이 (바이트) 설명
rpIdHash 32 RP ID의 SHA-256 해시 값. 해당 자격 증명스코프되는 RP ID 입니다.
flags 1 플래그 (0번 비트가 가장 하위 비트):
signCount 4 서명 카운터, 32비트 부호 없는 빅엔디언 정수.
attestedCredentialData 가변형 (존재하는 경우) Attested credential data (존재할 때). 자세한 사항은 § 6.5.1 Attested Credential Data를 참고하세요. 길이는 credential IDcredential public key의 크기에 따라 달라집니다.
extensions 가변형 (존재하는 경우) 확장에서 정의한 인증기 데이터. 이는 CBOR [RFC8949] 맵이며, 확장 식별자를 키로, authenticator extension output을 값으로 가지고 있습니다. 자세한 내용은 § 9 WebAuthn Extensions 참고.
인증기 데이터 레이아웃. 이름 열에 표시된 명칭은 본 문서 내에서만 참조용으로 사용되며, 실제 인증기 데이터 표현에는 포함되지 않습니다.

RP ID는 자격 증명 생성 시 클라이언트로부터 수신되며, 어설션이 생성될 때도 다시 전달됩니다. 하지만 아래와 같은 중요한 면에서 클라이언트 데이터와 다룹니다. 첫째, 클라이언트 데이터와 달리, 자격 증명의 RP ID는 연산 사이에 바뀌지 않으며 자격 증명의 수명 동안 동일하게 유지됩니다. 둘째, 인증기는 authenticatorGetAssertion 동작에서, 요청된 자격 증명스코프RP ID클라이언트가 제공한 RP ID가 정확히 일치하는지 확인하여 이것을 검증합니다.

인증기다음 절차로 인증기 데이터 구조를 생성합니다:

그림 인증기 데이터 구조의 시각적 표현입니다.

인증기 데이터 레이아웃.
Note: 인증기 데이터는 자체적으로 길이를 설명합니다: ATED 플래그가 설정되어 있지 않다면, 항상 37바이트입니다. Attested credential data (단 AT 플래그가 설정되어 있을 때만 존재)은 자체적으로 길이를 가집니다. ED 플래그가 설정되면 전체 길이는 37바이트에 attested credential data의 길이(AT 플래그 설정 시), 그 뒤에 오는 확장(extensions)의 길이(CBOR 맵)를 더한 값이 됩니다.

Attested credential data의 길이 결정은, credentialPublicKeycredentialId 길이 뒤에 어디서 시작하는지 결정하고, credentialPublicKey의 길이를 구하는 과정이 필요합니다 (자세한 내용은 Section 7 of [RFC9052] 참고).

6.1.1. 서명 카운터 관련 사항

인증기는 서명 카운터 기능을 구현하는 것이 권장됩니다. 이 카운터들은 개념적으로 인증기의 각 자격 증명 단위 또는 인증기 전체에서 저장됩니다. 각 자격 증명의 서명 카운터의 초기 값은 authenticator datasignCount 값으로 지정됩니다. 서명 카운터authenticatorGetAssertion 연산이 성공할 때마다 0 이상의 값만큼 증가하며, 그 이후 값들이 다시 WebAuthn Relying Partyauthenticator data로 반환됩니다. 서명 카운터의 목적은 Relying Party가 복제된 인증기를 탐지할 수 있도록 돕는 것입니다. 복제 탐지는 보호 조치가 약한 인증기일수록 더 중요합니다.

서명 카운터 기능을 구현하지 않는 인증기의 경우 authenticator datasignCount는 항상 0으로 고정됩니다.

Relying PartyauthenticatorGetAssertion 작업의 가장 최근 서명 카운터를 저장합니다. (또는 해당 자격 증명에 대해 아직 authenticatorGetAssertion이 수행된 적이 없다면 authenticatorMakeCredential 연산 결과의 카운터를 저장.) 이후 authenticatorGetAssertion 작업에서 Relying Party는 저장된 서명 카운터 값과 이번 어설션에서 반환된 signCount 값을 비교합니다. 둘 중 하나라도 0이 아니면서 새로운 signCount가 저장된 값 이하일 경우, 인증기가 복제되었거나, 인증기에 문제가 있거나, 어설션이 생성된 순서와 다르게 RP에서 처리되어 경쟁 상태가 발생한 것일 수 있습니다.

서명 카운터 불일치 탐지 시, 현재 연산이 복제 인증기로 수행된 것인지, 원본 인증기에서 수행된 것인지는 알 수 없습니다. Relying Party는 자사 위험 허용치 및 운영 요인을 고려하여 이런 상황을 적절히 처리해야 합니다.

인증기 권장 사항:

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 Party는 향후 평가를 위해 최신 플래그 값을 사용자 계정과 함께 저장하는 것이 권장됩니다.

아래는 Relying Party가 이러한 플래그를 활용하는 비한정 리스트입니다:

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 명칭에 대한 정의.

second-factor platform authenticator는 동일한 client device의 재인증에 편리하며, 새 세션을 시작하거나 기존 세션을 재개할 때 추가적인 보안 계층을 제공하는 데 사용할 수 있습니다. second-factor roaming authenticator는 특정 client device에서 처음 인증하거나, 여러 사용자가 공유하는 client device에서 사용하는 경우에 더 자주 사용될 것입니다.

Passkey platform authenticatorspasskey roaming authenticators는 비밀번호 없는 multi-factor 인증을 가능하게 합니다. credential private key의 소유 증명에 더해, 이러한 인증기들은 일반적으로 PIN 또는 biometric recognition과 같은 두번째 authentication factor로서 user verification을 지원합니다. 따라서 authenticator는 두 종류의 authentication factor로 동작할 수 있어, 비밀번호를 Relying Party와 공유할 필요 없이 multi-factor 인증을 가능하게 합니다. 이러한 인증기들은 또한 discoverable credentials(일명 passkeys)를 지원하므로, 사용자명 입력이 필요 없는 인증 흐름도 지원합니다.

user-verifying platform authenticator 클래스는 주로 passkey platform authenticator 클래스에 의해 대체되었지만, 이 정의는 isUserVerifyingPlatformAuthenticatorAvailable 메서드에서 여전히 사용됩니다.

에 명시되지 않은 조합들은 사용 사례가 덜 분명합니다:

다음 하위 절들에서는 authenticator attachment modality, credential storage modalityauthentication factor capability의 측면을 더 자세히 정의합니다.

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라고 부릅니다.

일부 platform authenticators는 상황에 따라 roaming authenticators로 동작할 수도 있습니다. 예를 들어, 모바일 기기에 통합된 platform authenticator는 Bluetooth를 통해 스스로를 roaming authenticator로 제공할 수 있습니다. 이 경우 모바일 기기에서 실행되는 clients는 해당 인증기를 platform authenticator로 인식하는 반면, 다른 clients가 다른 client device에서 동일한 인증기와 Bluetooth로 통신할 때에는 이를 roaming authenticator로 인식하게 됩니다.

platform authenticators의 주요 사용 사례는 특정 client device를 "신뢰된 장치"로 등록하는 것입니다. 즉 client device 자체가 향후 something you have authentication factor로 동작하도록 하는 것입니다. 이렇게 하면 사용자는 향후 authentication 절차에서 roaming authenticator를 찾을 필요가 없으므로 편리합니다(예: 주머니에서 키 고리나 휴대전화를 꺼낼 필요가 없음).

로밍 인증기의 사용 사례에는 다음이 포함됩니다: 새로운 클라이언트 장치에서 처음으로 인증을 할 때, 거의 사용하지 않는 클라이언트 장치에서 사용할 때, 여러 사용자가 공유하는 클라이언트 장치에서 사용할 때, 또는 플랫폼 인증기가 포함되지 않은 클라이언트 장치에서 사용할 때가 있습니다. 또한 정책이나 사용자 선호에 따라 인증기를 사용하는 클라이언트 장치와 분리하여 보관해야 할 때도 해당됩니다. 로밍 인증기는 다른 인증기를 분실한 경우를 대비해 백업 크리덴셜을 보관하는 용도로도 사용할 수 있습니다.

6.2.2. Credential Storage Modality

authenticatorpublic key credential source를 두 가지 방식 중 하나로 저장할 수 있습니다:

  1. authenticator, client 또는 client device에 내장된 영구 저장소에 저장하는 방식(예: secure element). 이 방식은 client-side discoverable public key credential source의 기술적 요구사항입니다.

  2. public key credential source를 암호화(랩핑)하여 오직 이 authenticator만이 복호화(언랩핑)할 수 있게 하고, 그 결과 생성된 암호문을 credential ID로 두는 방법. 이 credential IDRelying Party에 의해 저장되며, authenticator에게 allowCredentials 옵션으로 반환됩니다(참조: get()). 이를 통해 authenticator가 해당 public key credential source를 복호화하고 사용할 수 있습니다.

    이 방식은 암호화된 public key credential sourcesRelying Party에 의해 저장되므로, authenticator의 저장 용량이 사실상 무제한이 될 수 있게 합니다 — 하지만 이러한 방식으로 저장된 credentialRelying Party로부터 먼저 검색되어야만 authenticator가 이를 사용할 수 있습니다.

어떤 저장 전략을 지원하는지에 따라 authenticatorcredential storage modality가 다음과 같이 정의됩니다:

참고로 discoverable credential capableauthenticator는 두 가지 저장 전략을 모두 지원할 수 있습니다. 이 경우 authenticator는 자의 재량으로 서로 다른 credentials에 대해 서로 다른 저장 전략을 사용할 수 있지만, 이는 residentKeyrequireResidentKey 옵션을 포함한 create()의 제약을 따릅니다.

6.2.3. Authentication Factor Capability

인증식(authentication ceremony) 동안 신원을 증명하는 데 사용할 수 있는 세 가지 넓은 범주의 authentication factors가 있습니다: something you have, something you knowsomething you are입니다. 예로는 각각 물리적 키, 비밀번호, 지문 등이 있습니다.

모든 WebAuthn Authenticatorssomething you have 범주에 속하지만, authenticatoruser verification을 지원하면 추가로 하나 또는 두 가지 다른 유형의 authentication factor로도 동작할 수 있습니다. 예를 들어, authenticator가 PIN을 검증할 수 있다면, 그 PIN은 something you know이고, biometric authenticatorsomething you are을 검증할 수 있습니다. 따라서 authenticatoruser verification을 지원하면, 이를 multi-factor capable라고 합니다. 반대로 authenticatormulti-factor capable이 아니면 single-factor capable입니다. 단일 multi-factor capable 인증기는 여러 모드의 user verification을 지원할 수 있으므로, 세 가지 종류의 authentication factor를 모두 수행할 수 있습니다.

user verificationauthenticator에서 로컬로 수행되며 Relying Party에 의해 수행되지 않지만, authenticator는 서명된 응답에서 UV flag를 설정하여 user verification이 수행되었는지를 표시합니다. 따라서 Relying PartyUV flag를 사용하여 등록(registration) 또는 인증식(authentication ceremony)에서 추가적인 authentication factors가 사용되었는지를 확인할 수 있습니다. UV flag의 진위는 다시 authenticatorattestation statement를 검사하여 평가할 수 있습니다.

6.3. Authenticator Operations

WebAuthn Client는 해당 인증기의 어떠한 작업도 호출하기 위해 반드시 인증기와 연결해야 합니다. 이 연결은 authenticator session을 정의합니다. 인증기는 세션 간의 격리를 유지해야 합니다. 이는 한 번에 하나의 세션만 허용하거나 더 복잡한 세션 관리를 제공함으로써 달성할 수 있습니다.

다음 작업들은 클라이언트가 authenticator session에서 호출할 수 있습니다.

6.3.1. Lookup Credential Source by Credential ID Algorithm

credential id를 조회(looking up)한 결과로서 credential id credentialIdauthenticator authenticator에서 찾는 결과는 다음 알고리즘의 결과입니다:

  1. 만약 authenticatorcredentialId를 복호화하여 public key credential source credSource로 만들 수 있다면:

    1. credSource.idcredentialId로 설정합니다.

    2. credSource를 반환합니다.

  2. 각각(For each) public key credential source credSource에 대하여, 이것이 authenticatorcredentials map에 포함되어 있으면:

    1. 만약 credSource.idcredentialId이면, credSource를 반환합니다.

  3. null을 반환합니다.

6.3.2. The authenticatorMakeCredential Operation

이 작업을 호출하기 전에, 클라이언트는 반드시 authenticatorCancel 작업을 호출하여 authenticator session에서 진행 중인 다른 모든 작업을 중단해야 합니다.

이 작업은 다음 입력 매개변수를 받습니다:

hash

클라이언트가 제공한 직렬화된 client data의 해시.

rpEntity

Relying PartyPublicKeyCredentialRpEntity.

userEntity

user accountPublicKeyCredentialUserEntity, 여기에는 user handle가 포함됩니다.

requireResidentKey

credential 생성에 대한 유효한 resident key 요구로, client에 의해 결정되는 Boolean 값입니다.

requireUserPresence

상수 Boolean 값 true 또는 FALSE (만약 options.mediationconditional로 설정되고 사용자 에이전트가 이전에 사용자 동의를 수집한 경우).

requireUserVerification

credential 생성에 대한 유효한 user verification 요구로, client에 의해 결정되는 Boolean 값입니다.

credTypesAndPubKeyAlgs

PublicKeyCredentialType와 공개키 알고리즘(COSEAlgorithmIdentifier)의 쌍으로 이루어진 시퀀스이며, 이는 Relying Party가 요청한 것입니다. 이 시퀀스는 선호도 순으로 정렬되어 있으며, authenticator는 지원 가능한 가장 선호되는 credential을 만들기 위해 최선을 다합니다.

excludeCredentialDescriptorList

선택적(OPTIONAL)으로 제공되는 PublicKeyCredentialDescriptor 객체의 목록으로, Relying Party가 이들 중 어떤 것이 인증기에서 알려져 있다면 새 credential을 생성하지 않도록 의도한 것입니다. excludeCredentialDescriptorList는 알려진 credential들의 목록을 포함합니다.

enterpriseAttestationPossible

개별 식별 가능한 attestation이 인증기에 의해 반환될 수 있음을 나타내는 Boolean 값.

attestationFormats

Relying Party의 attestation statement 형식 선호도를 가장 선호하는 것부터 덜 선호하는 것 순으로 표현한 문자열 시퀀스입니다. 만약 authenticatorattestation을 반환하면, 지원하는 가장 선호되는 형식을 사용하려고 최선을 다합니다.

extensions

CBOR map으로, extension identifiers를 키로 하고 해당 authenticator extension inputs을 값으로 가지며, 클라이언트가 Relying Party가 요청한 확장에 기반하여 생성합니다(있다면).

이 작업이 호출되면, authenticator는 다음 절차를 반드시 수행해야 합니다:

  1. 제공된 모든 매개변수가 문법적으로 올바르고 길이가 적절한지 확인합니다. 그렇지 않으면 "UnknownError"와 동등한 오류 코드를 반환하고 작업을 종료합니다.

  2. PublicKeyCredentialTypecredTypesAndPubKeyAlgs에 있는 암호학적 매개변수들의 조합 중 적어도 하나가 지원되는지 확인합니다. 지원되지 않으면 "NotSupportedError"와 동등한 오류 코드를 반환하고 작업을 종료합니다.

  3. descriptor에 대해 excludeCredentialDescriptorList:

    1. 만약 이 인증기에서 looking up을 수행한 결과 descriptor.id가 null이 아니고, 반환된 항목의 itemRP IDtyperpEntity.idexcludeCredentialDescriptorList.type와 각각 일치하면, 새 credential 생성에 대한 사용자 동의를 확인하는 authorization gesture을 수집합니다. 이 authorization gesture에는 반드시 test of user presence가 포함되어야 합니다. 사용자가

      새 credential 생성에 동의하면

      "InvalidStateError"와 동등한 오류 코드를 반환하고 작업을 종료합니다.

      새 credential 생성에 동의하지 않으면

      "NotAllowedError"와 동등한 오류 코드를 반환하고 작업을 종료합니다.

      Note:authorization gesture의 목적은 credential을 생성하는 것이 아니라, 프라이버시상의 이유로 descriptor.id가 이 authenticator에 바인딩되어 있다는 사실의 공개를 허용하는 것입니다. 만약 사용자가 동의하면, clientRelying Party는 이를 감지하고 사용자가 다른 authenticator를 사용하도록 안내할 수 있습니다. 사용자가 동의하지 않으면, authenticatordescriptor.id가 자신에게 바인딩되어 있다는 사실을 드러내지 않으며, 단순히 사용자가 credential 생성 동의를 거부한 것처럼 응답합니다.

  4. 만약 requireResidentKeytrue이고 인증기가 client-side discoverable public key credential source를 저장할 수 없다면, "ConstraintError"와 동등한 오류 코드를 반환하고 작업을 종료합니다.

  5. 만약 requireUserVerificationtrue이고 인증기가 user verification을 수행할 수 없다면, "ConstraintError"와 동등한 오류 코드를 반환하고 작업을 종료합니다.

  6. authorization gesture이 완료되어 user consent가 얻어진 후, 새 credential 객체를 생성합니다:

    1. (publicKey, privateKey)를 이 인증기가 지원하는 PublicKeyCredentialTypecredTypesAndPubKeyAlgs의 첫 번째 지원 가능한 항목에서 표현된 암호 매개변수의 조합을 사용하여 생성된 새로운 암호 키 쌍으로 둡니다.

    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. 새 credential 객체를 생성하는 동안 오류가 발생하면 "UnknownError"와 동등한 오류 코드를 반환하고 작업을 종료합니다.

  8. processedExtensionsauthenticator extension processing의 결과로 둡니다(지원되는 각 extension identifierauthenticator extension input에 대해) 및 extensions에서 수행합니다.

  9. 만약 authenticator가:

    U2F 장치인 경우

    새 credential에 대한 signature counter 값을 0으로 둡니다. (U2F 장치는 signature counter를 지원할 수 있지만 credential 생성 시 카운터를 반환하지 않습니다. 자세한 내용은 [FIDO-U2F-Message-Formats] 참조.)

    글로벌 signature counter를 지원하는 경우

    authenticator data를 생성할 때 글로벌 signature counter의 실제 값을 사용합니다.

    credential별 signature counter를 지원하는 경우

    카운터를 할당하여 새 credential과 연관시키고 카운터 값을 0으로 초기화합니다.

    signature counter를 지원하지 않는 경우

    새 credential에 대한 signature counter 값을 항상 0으로 둡니다.

  10. attestedCredentialDatacredentialIdpublicKey를 포함하는 attested credential data 바이트 배열로 둡니다.

  11. attestationFormatattestationFormats에서 enterpriseAttestationPossible를 고려하여 지원되는 첫 번째 attestation statement format identifier로 둡니다. 만약 attestationFormats에 지원되는 값이 없다면, attestationFormat을 이 인증기가 가장 선호하는 attestation statement format identifier로 둡니다.

  12. authenticatorData§ 6.1 Authenticator Data에 지정된 바이트 배열로 둡니다. 여기에는 attestedCredentialDataattestedCredentialData로 포함되고, 있으면 processedExtensionsextensions로 포함됩니다.

  13. 새 credential을 위한 attestation object§ 6.5.4 Generating an Attestation Object에 명시된 절차, attestation statement format attestationFormat 및 값 authenticatorDatahash를 사용하여 생성합니다. 또한 enterpriseAttestationPossible 값을 고려합니다. attestation에 대한 자세한 내용은 § 6.5 Attestation을 참조하십시오.

이 작업이 성공적으로 완료되면, 인증기는 attestation object를 클라이언트에 반환합니다.

6.3.3. authenticatorGetAssertion 작업

이 작업을 호출하기 전에, 클라이언트는 authenticatorCancel 작업을 호출하여 authenticator session 내에서 진행 중인 모든 다른 작업을 중단해야 한다.

이 작업은 다음 입력 매개변수를 가진다:

rpId

사용자의 RP ID, 사용자 에이전트와 클라이언트에 의해 결정된다.

hash

클라이언트가 제공하는 직렬화된 클라이언트 데이터의 해시이다.

allowCredentialDescriptorList

리스트이며, PublicKeyCredentialDescriptor의 객체들의 OPTIONAL 리스트로 Relying Party가 허용하는 인증 정보를 (클라이언트에 의해 필터링되어 있을 수 있음) 설명한다. 제공되는 경우에 한함.

requireUserPresence

불리언 상수 값 true이다. 이는 WebAuthn에서는 필수가 아니더라도 구현에서 사용자 존재 확인을 선택적으로 적용할 수 있도록 하기 위하여 유사-매개변수로 포함되어 있다.

requireUserVerification

assertion에 대한 효과적인 사용자 검증 요건을 나타내는 불리언 값으로, 클라이언트가 제공한다.

extensions

클라이언트가 Relying Party가 요청한 확장자에 따라 작성한 CBOR map으로, extension identifier를 그에 상응하는 authenticator extension input에 매핑한다.

이 메소드가 호출되면, authenticator는 다음 절차를 수행해야 한다:

  1. 제공된 모든 매개변수가 문법적으로 올바르고 길이가 적절한지 확인한다. 그렇지 않으면 "UnknownError"에 해당하는 오류 코드를 반환하고 작업을 종료한다.

  2. credentialOptions를 새로운 빈 set으로 생성한다. 이 set에는 공개키 자격 증명 소스가 포함된다.

  3. allowCredentialDescriptorList가 제공된 경우, allowCredentialDescriptorListdescriptor에 대해:

    1. credSourcecredential id 찾아보기에 따라 이 인증장치에서 descriptor.id로 얻는다.

    2. credSourcenull이 아니면, credentialOptions에 추가한다.

  4. 그렇지 않은 경우 (allowCredentialDescriptorList가 제공되지 않았다면), 이 인증장치의 credentials mapkeycredSource에 대해, credentialOptions에 추가한다.

  5. credentialOptions에서 rpIdrpId와 일치하지 않는 항목을 모두 제거한다.

  6. credentialOptions가 비어있으면, "NotAllowedError"에 해당하는 오류 코드를 반환하고 작업을 종료한다.

  7. 사용자에게 공개키 자격 증명 소스 selectedCredentialcredentialOptions에서 선택하도록 안내한다. authorization gesture를 수집하여 사용자 동의를 획득한다. authorization gesture에 대한 안내창은 인증장치에 출력 기능이 있으면 인증장치에서, 그렇지 않으면 사용자 에이전트에서 표시될 수 있다.

    만약 requireUserVerificationtrue라면, authorization gesture 안에 사용자 검증이 포함되어야 한다.

    requireUserPresencetrue라면, authorization gesture사용자 존재 테스트가 반드시 포함되어야 한다.

    만약 사용자가 동의하지 않으면 "NotAllowedError"에 해당하는 오류 코드를 반환하고 작업을 종료한다.

  8. processedExtensionsauthenticator extension 처리 결과로 한다. 지원하는 extension identifierauthenticator extension input각각 extensions에 대해 실행한다.

  9. 서명 카운터 또는 글로벌 서명 카운터 값을 인증장치의 구현 방식에 따라 양의 값만큼 증가시킨다. 만약 authenticator서명 카운터를 구현하지 않는다면, 카운터 값은 0으로 유지된다.

  10. authenticatorData다음 절차로 생성한 바이트 배열로 한다. § 6.1 Authenticator Data에 명시되어 있으며, processedExtensions가 있다면 그것을 extensions로 포함한다. attestedCredentialData는 포함하지 않는다.

  11. signatureassertion signature로, authenticatorData || hash의 연결에 대해 selectedCredential의 privateKey로 생성한다. 아래 그림 참고. 단순하고 구분 기호 없는 연결(concatenation)은 authenticator data가 자신의 길이를 기술하기 때문에 사용해도 안전하다. 직렬화된 클라이언트 데이터의 해시는 항상 마지막 요소가 된다.

    assertion signature 생성 과정.
  12. assertion signature 생성 중 오류가 발생하면 "UnknownError"에 해당하는 오류 코드를 반환하고 작업을 종료한다.

  13. 사용자 에이전트에 반환:
    • selectedCredential.id — 2개 이상의 인증 정보(즉, allowCredentialDescriptorList)가 제공되었거나, 해당 리스트가 제공되지 않은 경우 반환한다.

      참고: allowCredentialDescriptorList에 클라이언트가 정확히 하나의 인증 정보를 제공했고, 성공적으로 사용된 경우 해당 credential ID는 이미 클라이언트가 알고 있으므로 반환하지 않는다. 흔한 경우에 불필요한 바이트 전달을 절감할 수 있다.

    • authenticatorData

    • signature

    • selectedCredential.userHandle

      참고: allowCredentialDescriptorList가 제공된 경우, 반환된 userHandle 값은 null일 수 있다. 자세한 내용은 userHandleResult 참고.

authenticator가 지정된 Relying Party에 해당하고 지정된 기준에 부합하는 credential을 찾지 못하면 작업을 종료하고 오류를 반환한다.

6.3.4. authenticatorCancel 작업

이 작업은 입력 매개변수가 없으며 반환값도 없다.

클라이언트가 authenticator session에서 이 작업을 호출하면, 해당 인증장치 세션 내에서 현재 진행 중인 authenticatorMakeCredential 또는 authenticatorGetAssertion 작업을 종료시킨다. 인증장치는 취소된 작업에 대해 사용자 입력을 더 이상 요청하거나 받지 않는다. 클라이언트는 취소된 작업에 대해 인증장치로부터의 이후 응답을 무시한다.

authenticator session에서 authenticatorMakeCredential 또는 authenticatorGetAssertion 작업이 진행 중이지 않다면, 이 작업은 무시된다.

6.3.5. silentCredentialDiscovery 작업

이는 인증장치가 conditional 사용자 중재를 지원하도록 하는 OPTIONAL 작업이다.

다음 입력 매개변수를 가진다:

rpId

호출자의 RP ID로, 클라이언트에 의해 결정된다.

이 작업이 호출되면, authenticator는 다음 절차를 따라야 한다:

  1. collectedDiscoverableCredentialMetadata를 새 리스트로 지정한다. 이 리스트의 항목은 다음 DiscoverableCredentialMetadata 구조체이다. 각 구조체의 항목은 다음과 같다:

    type

    PublicKeyCredentialType.

    id

    Credential ID이다.

    rpId

    Relying Party Identifier이다.

    userHandle

    사용자 핸들이다.

    otherUI

    authenticator가 UI에 표시할 기타 정보이다.

  2. 공개키 자격 증명 소스 credSource에 대해 authenticatorcredentials map을 순회한다:

    1. credSource클라이언트 측 탐색 가능한 자격 증명이 아니면 continue 한다.

    2. credSource.rpIdrpId와 다르면 continue 한다.

    3. discoveredCredentialMetadata를 새 DiscoverableCredentialMetadata 구조체로, credSourcetype, id, rpId, userHandle, otherUI를 복사하여 생성한다.

    4. discoveredCredentialMetadatacollectedDiscoverableCredentialMetadata에 추가한다.

  3. collectedDiscoverableCredentialMetadata를 반환한다.

6.4. 문자열 처리

인증기는 Relying Party가 선택한 임의의 문자열을 저장해야 할 수도 있습니다. 예를 들어, namedisplayNamePublicKeyCredentialUserEntity 안에 있습니다. 이 절에서는 사람이 볼 수도 있는 임의 문자열을 처리할 때 발생할 수 있는 실제 문제점들에 대해 설명합니다.

6.4.1. 문자열 잘림

API의 각 임의 문자열은 인증기가 사용할 수 있는 자원이 제한적일 수 있음을 고려해야 합니다. 잘림(truncation) 처리를 선택할 경우, 문자열 값이 손상되지 않도록 주의해야 합니다.

예를 들어, 유니코드 코드 포인트 기준으로만 잘라내면 그래프림 클러스터가 잘릴 수 있습니다. 이렇게 되면 글리프 전체가 지워지는 대신 잘린 클러스터가 다른 모양의 글리프로 표시될 수 있어 문자열의 의미가 변경될 수도 있습니다. 예를 들어, 그림 은 인코딩이 65바이트인 UTF-8 문자열의 끝을 보여줍니다. 만약 64바이트로 제한한다면 마지막 0x88 바이트가 우선 제거됩니다. 이로 인해 UTF-8 코드 포인트의 일부만 남게 되면, 그 나머지도 제거해야 합니다. 그래도 남은 부분이 그래프림 클러스터의 일부라면, 역시 해당 클러스터 전체가 제거되어야 합니다.

UTF-8로 인코딩된 문자열 끝 부분에서 다양한 잘림 경계들의 위치를 보여줍니다.

이러한 처리를 담당하는 주체는 주로 클라이언트여야 하며, 인증기가 문자 인코딩 및 유니코드 문자 속성을 이해해야 하는 부담을 덜어주는 것이 바람직합니다. 아래 절에서는 클라이언트와 인증기가 각각 문자열 잘림을 수행할 때의 요구사항을 정의합니다.

6.4.1.1. 클라이언트의 문자열 잘림

WebAuthn 클라이언트가 문자열을 자를 때, Relying Party가 관찰할 수 있는 잘림 동작은 반드시 다음 요구사항을 만족해야 합니다:

지정된 최소 지원 길이보다 크거나 같은 크기 제한을 선택합니다. UTF-8 문자 인코딩에서 문자열의 바이트 길이가 그 제한에 맞도록 잘릴 수 있습니다. 이 잘림은 반드시 UTF-8 코드 포인트 경계를 지켜야 하며, 그래프림 클러스터 경계까지 지키는 것이 바람직합니다 [UAX29]. 잘린 값은 선택한 크기 제한보다 짧을 수 있지만, 반드시 해당 제한을 만족하면서 그래프림 클러스터 경계에서 끝나는 가장 긴 접두사 부분 문자열보다는 짧지 않아야 합니다.

클라이언트는 인증기가 위 요구사항을 충족한다면, 잘림 처리를 인증기에 맡길 수 있습니다. 그렇지 않은 경우 클라이언트가 인증기에 문자열을 전달하기 전 직접 잘림 처리를 해야 합니다.

또한 위 조건 외에, 단순히 바이트 경계에서만 자르면 사용자 에이전트가 알아야 할 문제가 있습니다. 인증기가 [FIDO-CTAP]를 사용하는 경우 인증기로부터 이후에 받는 메시지에서 값을 CBOR 문자열로 표현해야 하므로 유효한 UTF-8이어야 합니다. 따라서 인증기를 다룰 때, 사용자 에이전트는 다음을 권장합니다:

  1. 인증기로 보내는 문자열이 유효하게 인코딩되어 있는지 확인합니다.

  2. 문자열을 잘라낸 결과 인코딩이 깨진 경우를 처리합니다. 예를 들어, 끝에 남은 코드 포인트 조각은 삭제하거나 U+FFFD로 대체할 수 있습니다.

6.4.1.2. 인증기의 문자열 잘림

WebAuthn 인증기는 리소스가 제한적인 환경에서 동작할 수 있으므로, 인증기에 대한 요구사항은 클라이언트에 비해 더 완화되어 있습니다.

WebAuthn 인증기가 문자열을 자를 때, 반드시 다음 요구조건을 만족해야 합니다:

지정된 최소 지원 길이보다 크거나 같은 크기 제한을 선택합니다. UTF-8 문자 인코딩에서 문자열의 바이트 길이가 그 제한에 맞도록 잘릴 수 있습니다. 이 잘림은 UTF-8 코드 포인트 경계를 지키는 것이 바람직하며, 그래프림 클러스터 경계를 지킬 수도 있습니다 [UAX29]. 잘린 값은 제한보다 짧을 수 있으나, 해당 제한을 만족하고 그래프림 클러스터 경계에서 끝나는 가장 긴 접두사 부분 문자열보다는 짧지 않아야 합니다.

6.4.2. 언어 및 방향성 인코딩

문자열이 올바른 맥락에서 표시되기 위해서는 언어 및 기준 방향 정보가 필요할 수 있습니다. 이 API의 문자열은 고정기능 인증기에 기록한 뒤 나중에 다른 플랫폼에서 읽어서 표시할 수 있으므로, 문자열 자체에 언어/방향 메타데이터를 인코딩하여 원자적으로 전달되도록 합니다.

문서상 허용된 문자열에 언어/방향 메타데이터를 인코딩하려면, 코드포인트 뒤에 두 개의 시퀀스를 추가합니다:

첫 번째 시퀀스는 언어 태그를 인코딩하며, U+E0001 코드 포인트와 이어진 언어 태그 각 ASCII 값을 U+E0000만큼 올린 코드포인트로 표현합니다. 예를 들어, 언어 태그 “en-US”는 U+E0001, U+E0065, U+E006E, U+E002D, U+E0055, U+E0053이 됩니다.

두 번째 시퀀스는 U+200E(“LEFT-TO-RIGHT MARK”), U+200F(“RIGHT-TO-LEFT MARK”), U+E007F(“CANCEL TAG”) 중 하나의 코드포인트로 이뤄집니다. 앞 두 값은 방향성 표시용이나, 필요한 경우에만 사용해야 합니다(예: RTL 문자열이 LTR-강한 문자로 시작할 때). U+E007F 값은 언어 태그가 끝났음을 나타내는 방향성 중립 마킹입니다.

즉, 문자열 “حبیب الرحمان”은 언어를 인코딩할지에 따라 둘 중 하나의 DOMString 값을 가질 수 있습니다. (이 예에서는 방향이 명확하므로 방향 표시가 필요없음)

언어 및 방향 정보가 인코딩될 수 있는 문자열을 사용하는 쪽은 잘림으로 인해 언어 태그가 다른(그러나 여전히 유효한) 언어로 잘릴 수 있음을 인지해야 합니다. 최종 방향성 마커 또는 CANCEL TAG 코드포인트는 잘림되었음을 명확히 나타냅니다.

6.5. Attestation(인증서명)

인증기는 가능하다면 인증서명(attestation) 형태 또한 제공해야 합니다. 인증기가 이런 기능을 제공한다면, 기본 요구사항은 인증기가 각 공개키 자격증명에 대해, 인증서명 문장을 생성할 수 있어야 하며, 그 문장은 WebAuthn Relying Party가 검증할 수 있어야 합니다. 일반적으로 이 인증서명 문장attestation private keycredential public key와 챌린지에 서명하고, attestation public key의 출처 정보를 제공하는 인증서나 유사 데이터를 담습니다. 이를 통해 Relying Party가 신뢰 여부를 판단할 수 있습니다. 그러나, attestation key pair가 없다면, 인증기는 self attestation 또는, credential private keyno attestation을 할 수도 있습니다. 이러한 모든 정보는 인증기가 새로운 공개키 자격증명을 생성할 때 마다 반환되며, 전체적으로 attestation object라는 형태가 됩니다. attestation objectauthenticator data (이 안에 attested credential data가 들어있음) 그리고 attestation statement의 관계는 아래 그림 에 나와 있습니다.

인증기self attestation 또는 no attestation을 하는 경우, Relying Party가 신뢰 여부를 판단할 정보(출처)가 제공되지 않습니다. 이 때 인증기Relying Party에 대해 아무런 보장도 하지 않습니다.

Attestation object의 레이아웃을 보여줍니다. 여기엔 authenticator data (이 안에 attested credential data 포함), attestation statement가 있습니다.
Note: 이 그림은 packed attestation statement format만을 보여줍니다. 여러 추가 형식§ 8 Defined Attestation Statement Formats에 정의되어 있습니다.

attestation object의 중요한 구성 요소는 attestation statement입니다. 이는 서명이 된 데이터 오브젝트로 공개키 자격증명 자체 및 이를 생성한 인증기에 대한 진술을 포함합니다. attestation signature는 보통 인증기관의 키로 서명되어 있습니다(단, self attestation의 경우 credential private key로 서명). attestation statement를 바르게 해석하기 위해 Relying Party는 다음 두 측면을 이해해야 합니다:

  1. Attestation statement format은 시그니처가 어떻게 표현되는지, 그리고 여러 컨텍스트 바인딩이 인증기에 의해 어떻게 attestation statement에 포함되는지를 정의합니다. 즉, 이 포맷은 문장(statement)의 문법(syntax)를 정의합니다. TPM, Android OS 등 다양한 기존 요소들은 각자 attestation statement format을 정의한 바 있습니다. 본 명세서는 이러한 여러 포맷을 § 6.5.2 Attestation Statement Formats에서 확장 가능하게 지원합니다. 각 포맷은 § 8.1에서 설명하는 문자열 식별자로 구분합니다.

  2. Attestation typeattestation statement의 의미와 신뢰 모델을 정의합니다. 구체적으로, Relying Party가 해당 statement가 암호학적으로 유효함을 검증한 뒤 신뢰를 어떻게 쌓을지 정의합니다. 명세서는 § 6.5.3 Attestation Types에서 여러 attestation type을 지원합니다.

일반적으로 attestation statement formatattestation type간에 단순 매핑은 없습니다. 예를 들면, "packed" 형식§ 8.2 Packed Attestation Statement Format에서 설명되어 있으며, 모든 attestation type과 조합될 수 있습니다. 다른 형식과 타입은 보다 제한적일 수 있습니다.

Attestation의 프라이버시, 보안, 운영 특성은 다음에 따라 달라집니다:

Attestation typeattestation statement format인증기가 선택하며, Relying PartyattestationattestationFormats 파라미터로 요청만 할 수 있습니다.

대부분의 인증기는 소수의 attestation typeattestation statement format만 지원할 것으로 예상되며, Relying Party는 정책에 따라 수용할 수 있는 attestation type을 결정하게 됩니다. Relying Party는 또한 신뢰하려는 인증기 특징도 사전에 알아야 하며, 예를 들어 FIDO Metadata Service [FIDOMetadataService]가 참고가 될 수 있습니다.

6.5.1. Attested Credential Data

인증된 자격 증명 데이터는 자격 증명에 대한 attestation object를 생성할 때 authenticator data에 추가되는 가변 길이의 바이트 배열입니다. 이 형식은 에 나와 있습니다.

이름 길이 (바이트) 설명
aaguid 16 인증기의 AAGUID
credentialIdLength 2 credentialId의 바이트 길이 L, 16비트 부호 없는 빅엔디안 정수, 값은 반드시 1023 이하여야 합니다.
credentialId L 자격 증명 ID
credentialPublicKey 가변 자격 증명 공개키가 COSE_Key 포맷으로 인코딩된 값.
구체적인 규격은 RFC9052 7장CTAP2 정규 CBOR 인코딩 규칙을 따릅니다.
COSE_Key로 인코딩된 공개키에는 "alg" 파라미터가 반드시 포함되어야 하며, 다른 선택적 파라미터는 포함되어선 안 됩니다.
"alg" 파라미터에는 반드시 COSEAlgorithmIdentifier 값을 넣어야 합니다.
인코딩된 공개키에는 해당 key type과 알고리즘에 따른 추가 필수 파라미터도 반드시 들어가야 합니다(예: "kty", "alg"가 필수, 자세한 내용은 RFC9053 2장 참조).
인증된 자격 증명 데이터의 구성. 이름 열의 이름은 문서 내에서만 참고용이며 실제 데이터에는 나타나지 않습니다.
6.5.1.1. credentialPublicKey 값을 COSE_Key 포맷으로 인코딩한 예시

이 절에서는 ES256, PS256, RS256 서명 알고리즘에 대한 COSE_Key 인코딩된 타원 곡선 및 RSA 공개키 예시를 제공합니다. 이 예시는 위의 credentialPublicKey 값 규칙을 따르며, 가독성을 위해 CDDL [RFC8610] 형식으로 제시됩니다.

모든 COSE_Key 인코딩 키의 일반 구조는 RFC9052 7장에 명시되어 있습니다. 각 알고리즘별 키 타입은 [RFC9053] 및 기타 규격에 정의되어 있습니다.

아래는 EC2 포맷으로 인코딩된 COSE_Key 타원 곡선 공개키 예시입니다(RFC9053 7.1장 참조).
P-256 곡선(ECDSA w/ SHA-256, ES256 알고리즘) 사용:

{
  1:   2,  ; kty: EC2 key type
  3:  -7,  ; alg: ES256 signature algorithm
 -1:   1,  ; crv: P-256 curve
 -2:   x,  ; x좌표, 32바이트 바이트열
           ; 예시(16진): 65eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d
 -3:   y   ; y좌표, 32바이트 바이트열
           ; 예시(16진): 1e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c
}

위 타원 곡선 공개키를 CTAP2 표준 CBOR 인코딩으로 인코딩한 예시(가독성을 위해 공백/줄바꿈 포함):

A5
   01  02

   03  26

   20  01

   21  58 20   65eda5a12577c2bae829437fe338701a10aaa375e1bb5b5de108de439c08551d

   22  58 20   1e52ed75701163f7f9e40ddf9f341b3dc9ba860af7e0ca7ca7e9eecd0084d19c

아래는 COSE_Key로 인코딩된 2048비트 RSA 공개키 예시입니다([RFC8230] 4장 참조).
PS256 서명 알고리즘(RSASSA-PSS with SHA-256)용:

{
  1:   3,  ; kty: RSA key type
  3: -37,  ; alg: PS256
 -1:   n,  ; n:   RSA 모듈러스 n, 256바이트 바이트열
           ;      예시(중간 생략): DB5F651550...6DC6548ACC3
 -2:   e   ; e:   RSA 퍼블릭 지수 e, 3바이트 바이트열
           ;      예시: 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 모듈러스 n, 256바이트 바이트열
           ;      예시(중간 생략): DB5F651550...6DC6548ACC3
 -2:   e   ; e:   RSA 퍼블릭 지수 e, 3바이트 바이트열
           ;      예시: 010001
}

6.5.2. Attestation Statement Formats

위에서 설명한 것처럼, attestation statement formatauthenticator가 컨텍스트 결합 정보에 대해 암호 서명을 표현하는 데이터 형식입니다. 각각의 attestation statement format은 다음 템플릿으로 정의해야 합니다:

정의된 attestation statement format의 목록은 § 8 Defined Attestation Statement Formats에 있습니다.

6.5.3. Attestation Type 종류

WebAuthn은 여러 attestation type을 지원하며, 각각의 attestation statement 의미 및 신뢰 모델을 정의합니다.

참고: 본 명세에서는 authenticator가 사용하는 attestation type을 명시적으로 표현하는 데이터 구조를 정의하지 않습니다. Relying Partyattestation statement 검증을 할 때 (즉, navigator.credentials.create() 사용 시 attestation conveyancenone이 아니고 받은 attestation statement를 검증함)
검증의 일부로 사용된 attestation type을 결정하게 됩니다. 구체 절차 예시는 § 8 Attestation Statement Formats의 "Verification procedure" 절, 그리고 § 14.4.1 Attestation Privacy 참조.
이 절에서 정의한 Self, None을 제외한 모든 attestation type은 검증이 끝난 뒤 신뢰 경로를 루트 인증서와 매칭(7.1-23단계, § 7.1 자격 증명 등록)해야 함.
이러한 구분은 Relying Party 정책 내에서 attestation의 허용 여부 판단에 주로 활용됨.

Basic Attestation (Basic)

기본(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 keyattestation signature를 만듭니다. 실질적인 attestation private key 보호가 없는 인증기는 이 유형을 사용합니다.

Attestation CA (AttCA)

이 유형에서는 authenticator가 TPM(Trusted Platform Module) 기반이고, 사용자별 "endorsement key"(EK)를 보유합니다.
이 키로 신뢰받는 별도의 제3자 Attestation CA ([TCG-CMCProfile-AIKCertEnroll], 예전 이름 "Privacy CA")와 안전하게 통신 가능.
인증기는 여러 attestation identity key pair(AIK)를 생성해서 각각에 대해 Attestation CA로부터 AIK 인증서를 발급받을 수 있습니다. 이 방식은 EK(전역식별) 노출을 Attestation CA로 제한할 수 있습니다. 각 authenticator에서 생성된 public key credential마다 개별적으로 AIK를 요청 가능하며, Relying Party에게 attestation certificate로 제공할 수 있습니다.

참고: 이 모델은 여러 attestation 인증서를 만들며, 가장 최근에 요청한 것이 "active" 인증서입니다.

Anonymization CA (AnonCA)

이 유형에서는 authenticatorAnonymization CA를 사용하여 매 자격 증명마다 동적으로 attestation certificate를 발급합니다. 이 덕분에 attestation statementRelying Party에게 식별이 불가한 정보만 제공합니다(트래킹 방지).

참고: Attestation statementattestation type이 AttCA, AnonCA인 경우 내부 데이터 구조는 Basic type과 같으므로, 실제로는 attestation certificate의 외부적 해석 없이는 구분 불가.

검증 정보 없을 때 (None)

이 경우 attestation 정보가 없습니다. § 8.7 None Attestation Statement Format도 참고하세요.

6.5.4. Attestation Object 생성

attestation object를 생성하려면(예: 그림 6), 다음 입력이 있어야 함:

attestationFormat

attestation statement format 하나.

authData

authenticator data를 담은 바이트 배열.

hash

직렬화된 클라이언트 데이터 해시.

authenticator는 반드시 아래 절차를 따라야 합니다:

  1. attStmtattestationFormatsigning procedureauthData, hash를 전달해 생성함.

  2. fmtattestationFormatattestation statement format identifier임.

  3. 아래 문법에 따라 CBOR 맵으로 attestation object를 반환. 변수는 위 알고리즘으로 채움:

    attObj = {
        authData: bytes,
    
        ; 각 $$attStmtType마다 fmt 값과 attStmt 구조 정의
        $$attStmtType
    } .within attStmtTemplate
    
    attStmtTemplate = {
        authData: bytes,
        fmt: text,
        attStmt: (
          { * tstr => any } ; 각 구체적 attStmtType 별 맵
          //
          [ * any ]         ; attStmt가 배열일 수도 있음
        )
    }
    

6.5.5. Packed/FIDO U2F Attestation 및 Assertion Signature의 서명 포맷

새로 정의되는 attestation format은 ASN.1 인코딩 사용 없이, 내부 구조 없는 고정 길이 바이트 배열 방식으로 서명값을 나타내는 것이 권장됩니다([RFC9053], [RFC8230] 방식).

아래 서명 포맷 정의는 이 요구사항을 만족하며, 명시되지 않은 다른 서명 알고리즘의 동일 구조 도출 예시로 활용할 수 있습니다:

7. WebAuthn Relying Party 작업

등록 또는 인증 의식WebAuthn Relying Party가 각각 PublicKeyCredentialCreationOptions 또는 PublicKeyCredentialRequestOptions 객체를 생성함으로써 시작되며, 이는 ceremony를 위한 파라미터를 인코딩한다. Relying Party는 이 단계에서 민감한 정보가 누출되지 않도록 주의해야 한다; 자세한 사항은 § 14.6.2 사용자명 열거를 참조하라.

create() 또는 get() 이(가) 성공적으로 실행되면, Relying Party의 스크립트는 PublicKeyCredential 내에 클라이언트로부터 AuthenticatorAttestationResponse 또는 AuthenticatorAssertionResponse 구조체를 각각 받게 된다. 이 구조체의 내용을 Relying Party 서버로 전송해야 하며, 이 방법은 본 명세의 범위를 벗어난다. 본 절에서는 Relying Party가 이러한 구조체를 수신했을 때 수행해야 할 작업을 설명한다.

7.1. 새로운 자격 증명 등록하기

등록 의식을 수행하기 위해 Relying Party는 다음과 같이 진행해야 한다:

  1. optionsRelying Party의 ceremony 필요에 맞게 구성한 새로운 CredentialCreationOptions 구조체로 정한다. pkOptionsoptions.publicKey로 한다.

  2. navigator.credentials.create() 를 호출하고 options를 인자로 전달한다. credential을 성공적으로 해결된 프라미스의 결과로 설정한다. 프라미스가 거부될 경우, 사용자에게 보이는 오류로 ceremony를 중단하거나 거부된 프라미스의 컨텍스트에서 파악할 수 있는 방식대로 사용자 경험을 안내해야 한다. 예를 들어 프라미스가 "InvalidStateError"와 동등한 오류 코드로 거부될 경우, 사용자에게 다른 인증기 사용을 안내할 수 있다. 다양한 오류 컨텍스트와 그 사유에 대한 자세한 정보는 § 6.3.2 authenticatorMakeCredential 작업을 참고하라.

  3. responsecredential.response로 한다. responseAuthenticatorAttestationResponse의 인스턴스가 아니면, 사용자에게 보이는 오류로 ceremony를 중단한다.

  4. clientExtensionResultscredential.getClientExtensionResults() 호출 결과로 한다.

  5. JSONtextresponse.clientDataJSON 의 값을 UTF-8 디코드 처리한 결과로 한다.

    참고: UTF-8 디코드의 어떤 구현도 결과가 UTF-8 디코드 알고리즘과 동일하다면 사용 가능하다. 특히, 시작 BOM(Byte Order Mark)이 있다면 제거되어야 한다.

  6. 자격 증명 생성 중에 수집된 것으로 주장된 클라이언트 데이터 C를, JSONtext에 구현별 JSON 파서를 실행한 결과로 설정한다.

    참고: C는 이 알고리즘이 요구하는 대로 C의 구성요소에 참조할 수만 있으면 구현별 자료구조 표현일 수 있다.

  7. C.type 값이 webauthn.create인지 확인한다.

  8. C.challenge 값이 pkOptions.challenge 의 base64url 인코딩 값과 동일한지 확인한다.

  9. C.origin 값이 originRelying Party가 기대하는 값인지 검증한다. 관련 내용은 § 13.4.9 자격 증명의 origin 유효성 검사 참고.
  10. C.crossOrigin 이 존재하고 값이 true이면, 이 자격 증명이 Relying Party가 기대하는, 조상과 same-origin이 아닌 iframe 내에서 생성되었는지 검증한다.

  11. C.topOrigin 이 존재하면:

    1. Relying Party가 기대하는, 조상과 same-origin이 아닌 iframe 내에서 생성된 것인지 검증한다.

    2. C.topOrigin 값이 originRelying Party가 sub-frame으로 두기를 기대하는 페이지 origin과 일치하는지 검증한다. 추가 내용은 § 13.4.9 자격 증명의 origin 유효성 검사 참고.

  12. hashresponse.clientDataJSON 에 대해 SHA-256 해시를 계산한 결과로 설정한다.

  13. attestationObject 필드의 CBOR 디코딩을 수행하여 fmt (어테스테이션 형식), 인증기 데이터 authData 및 어테스테이션 서명 attStmt을 획득한다.

  14. rpIdHash 값이 RP ID의 SHA-256 해시와 일치하는지 검사한다. 이 RP ID는 Relying Party가 기대하는 값이어야 한다.

  15. options.mediationconditional이 아니면, UP 비트가 authDataflags 내에 설정되어 있는지 확인한다.

  16. 이 등록에 대해 Relying Party사용자 검증을 요구한다면, UV 비트가 authDataflags 내에 설정되어 있는지 확인한다.

  17. BE 비트가 authDataflags 내에 설정되어 있지 않으면, BS 비트도 설정되지 않아야 한다.

  18. Relying Party가 자격 증명의 백업 적합성을 사용해 사용자 경험이나 정책을 결정한다면, BE 비트를 authDataflags에서 확인한다.

  19. Relying Party가 자격 증명의 백업 상태를 사용해 사용자 경험이나 정책을 결정한다면, BS 비트를 authDataflags에서 확인한다.

  20. credential public key의 "alg" 파라미터가 authData 내에 존재하며, alg 속성이 pkOptions.pubKeyCredParams 에 포함된 항목 중 하나와 일치하는지 확인한다.

  21. 어테스테이션의 형식(fmt)을 지원되는 WebAuthn 어테스테이션 형식 식별자 값들과 USASCII 대/소문자 구분 일치로 확인한다. 현재 등록된 WebAuthn 어테스테이션 형식 식별자 목록은 IANA "WebAuthn Attestation Statement Format Identifiers" 레지스트리 [IANA-WebAuthn-Registries]에서 관리한다. 자세한 내용은 [RFC8809] 참고.

  22. attStmt가 올바른 어테스테이션 명세이고, 어테스테이션 서명이 유효한지, 어테스테이션 명세 형식 fmt검증 절차attStmt, authData, hash를 넣어 사용하여 검증한다.

    참고:어테스테이션 명세 형식은 고유의 검증 절차를 지정한다. 처음 정의된 형식들은 § 8 어테스테이션 명세 형식 정의를, 최신 목록은 [IANA-WebAuthn-Registries]를 참조할 것.

  23. 검증이 성공하면 해당 어테스테이션 타입 및 fmt에 대해 신뢰할 수 있는 트러스트 앵커(즉, 어테스테이션 루트 인증서) 목록을 신뢰할 수 있는 소스 혹은 정책에서 획득한다. 예를 들어, FIDO 메타데이터 서비스 [FIDOMetadataService]는 해당 정보를 얻는 하나의 방법을 제공하며, aaguidattestedCredentialData 내에 존재한다.
  24. 검증 절차의 결과를 이용해 어테스테이션 신뢰성을 평가한다(21단계):

    어테스테이션이 신뢰할 수 없는 것으로 간주되면, Relying Party등록 의식을 실패 처리해야 한다.

    참고: 그러나 정책상 허용된다면, Relying Party자격 증명 ID와 공개키를 등록하되, 해당 자격 증명을 셀프 어테스테이션으로 간주할 수도 있다(§ 6.5.3 어테스테이션 타입 참조). 이 경우 Relying Party는 특정 인증기 모델이 아닌, 공개키 자격 증명이 생성되었다는 것에 대하여 암호학적 증거가 없음을 인정한다. 자세한 내용은 [FIDOSecRef][UAFProtocol] 참고.

  25. credentialId 가 1023바이트 이하인지 검증한다. 이 크기를 초과하는 자격 증명 ID는 RP가 등록 의식을 실패 처리하게 해야 한다.

  26. credentialId 가 아직 어떤 사용자에게도 등록되지 않았는지 확인한다. credentialId 가 이미 알려진 경우, Relying Party등록 의식을 실패시켜야 한다.

    참고: Relying Party가 중복 자격 증명 ID를 거부하는 이유는 다음과 같다: 자격 증명 ID는 충분한 엔트로피를 보장하므로 우연 중복은 매우 희박하다. 그러나, 셀프 어테스테이션이 아닌 경우에는 개인키의 소유를 명확히 증명하는 서명이 포함되지 않는다. 이로 인해 공격자가 사용자의 자격 증명 ID공개키를 획득해 정상 등록을 시도하는 등의 사고를 방지할 수 있다. 피해자의 기존 자격 증명이 대체된다면 피해자가 다음 로그인 때 공격자의 계정으로 로그인될 수 있다.

  27. credentialRecord를 다음 내용으로 하는 새로운 자격 증명 기록으로 한다:
    type

    credential.type.

    id

    credential.id 또는 credential.rawId, 어느 쪽이든 Relying Party가 선호하는 형식을 사용한다.

    publicKey

    자격 증명 공개키authData에 존재한다.

    signCount

    authData.signCount.

    uvInitialized

    UV 플래그 값은 authData에 있다.

    transports

    response.getTransports() 호출 결과다.

    backupEligible

    BE 플래그 값은 authData에 있다.

    backupState

    BS 플래그 값은 authData에 있다.

    새로운 자격 증명 기록에는 다음의 선택적 내용도 포함될 수 있다:

    attestationObject

    response.attestationObject.

    attestationClientDataJSON

    response.clientDataJSON.

    Relying Party는 필요한 경우 추가 항목도 포함시킬 수 있다. 비규범적 예시로, Relying Party는 사용자가 계정 설정에서 상호작용 시 쉽게 기억할 수 있도록 자격 증명에 "별명"을 지정할 수 있다. 이 별명으로 어느 자격 증명이 어떤 인증기에 바인딩되어 있는지 식별할 수 있다.

  28. clientExtensionResults클라이언트 확장 출력authDataextensions인증기 확장 출력Relying Party 요구대로 처리한다. 각 확장에 따라 처리 방법이 명확히 규정되어 있을 수도 있고, Relying Party가 자유롭게 처리할 수도 있다. Relying Party는 어떤 확장 출력도 무시 가능하다.

    클라이언트는 추가 인증기 확장이나 클라이언트 확장을 설정하여, 인증기 확장 출력 또는 클라이언트 확장 출력Relying PartypkOptions.extensions 에서 요청하지 않은 값이 등장할 수 있다. 이 경우 Relying Party는 이를 무시하거나 어테스테이션을 거부할 수 있으며, 정책에 따라 결정한다.

    모든 확장은 클라이언트인증기 모두에서 선택사항이므로, Relying Party는 요청한 확장 중 일부 혹은 전부가 미처리되는 경우를 고려해야 한다.

  29. 위 모든 단계가 성공하면, credentialRecord사용자 계정에 저장하고, pkOptions.user 를 참조하여 등록 의식을 계속 진행한다. 그렇지 않으면 등록 의식을 실패시킨다.

    Relying Party가 이 경우에도 등록 의식을 실패 처리하지 않는다면, Relying Party는 특정 인증기 모델로 생성된 것이라는 암호학적 증거가 공개키 자격 증명에 대해 없다는 사실을 인정하는 것이다. Relying Party는 자격 증명을 어테스테이션 없음으로 간주해도 된다(§ 6.5.3 어테스테이션 타입 참조). 자세한 논의는 [FIDOSecRef][UAFProtocol] 참조.

    어테스테이션 객체 검증을 위해서는 위 22단계에서 허용 가능한 트러스트 앵커를 결정하는 신뢰할 수 있는 방법이 Relying Party에 있어야 한다. 또한, 인증서를 사용할 경우 Relying Party는 중간 CA 인증서의 상태 정보에 접근 가능해야 한다. Relying Party는 클라이언트가 어테스테이션 정보에 인증서 체인을 제공하지 않은 경우에도 체인을 구축할 수 있어야 한다.

7.2. 인증 어서션 검증

인증 의식을 수행하기 위해, Relying Party는 다음과 같이 수행해야 한다:

  1. optionsRelying Party의 필요에 따라 구성한 새로운 CredentialRequestOptions 구조체로 두고, pkOptionsoptions.publicKey로 둔다.

  2. navigator.credentials.get() 을 호출하고, options를 인자로 전달한다. credential 값을 성공적으로 resolve된 프라미스의 결과로 둔다. 만약 프라미스가 거부되면, 사용자에게 보이는 오류로 의식을 중단하거나, 거부된 프라미스의 컨텍스트에서 알 수 있는 방식으로 사용 경험을 안내해야 한다. 다양한 오류 상황과 그 원인에 대해서는 § 6.3.3 authenticatorGetAssertion 작업을 참고하라.

  3. responsecredential.response 값으로 둔다. responseAuthenticatorAssertionResponse의 인스턴스가 아니면, 사용자에게 보이는 오류로 의식을 중단한다.

  4. clientExtensionResultscredential.getClientExtensionResults() 호출 결과로 둔다.

  5. pkOptions.allowCredentials 가 비어 있지 않으면, credential.id공개 키 자격 증명pkOptions.allowCredentials 에 나열된 것 중 하나를 식별하는지 확인한다.

  6. 인증되는 사용자를 식별하고, credentialRecord를 해당 자격증명 기록으로 둔다:

    사용자가 인증 의식 시작 전에 예를 들어 사용자명이나 쿠키로 식별된 경우,

    식별된 사용자 계정자격증명 기록을 포함하는지, 이 때 그 idcredential.rawId 와 같은지 검증한다. credentialRecord를 해당 자격증명 기록으로 둔다. response.userHandle 이 있을 경우, 해당 값이 user handle과 같은지 검증한다.

    사용자가 인증 의식 시작 전에 식별되지 않은 경우,

    response.userHandle 이 존재하는지 검증한다. response.userHandle 이 가리키는 사용자 계정자격증명 기록을 포함하고, 이는 idcredential.rawId 와 같은지 검증한다. credentialRecord를 해당 자격증명 기록으로 둔다.

  7. cData, authData, sig를 각각 responseclientDataJSON, authenticatorData, signature 값으로 둔다.

  8. JSONtextcDataUTF-8 디코드를 수행한 결과로 둔다.

    참고: UTF-8 디코드의 구현은, UTF-8 디코드 알고리즘과 같은 결과를 내면 어떤 구현도 괜찮다. 특히, 앞쪽의 BOM(Byte Order Mark)은 반드시 제거되어야 한다.

  9. 서명에 사용된 클라이언트 데이터 C를, JSONtext에 구현별 JSON 파서를 돌린 결과로 둔다.

    참고: C는 이 알고리즘이 요구하는 대로 C의 구성 요소에 참조만 할 수 있다면, 구현별 자료구조일 수 있다.

  10. C.type 값이 webauthn.get 문자열인지 확인한다.

  11. C.challenge 값이 pkOptions.challenge 의 base64url 인코딩과 같은지 확인한다.

  12. C.origin 값이 originRelying 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 값이 originRelying Party가 sub-framed 페이지로 예상하는 origin과 일치하는지 검증한다. 자세한 지침은 § 13.4.9 자격 증명의 origin 유효성 검사 참고.

  15. authData 안의 rpIdHash 값이 RP ID의 SHA-256 해시이며, 이는 Relying Party가 기대하는 값인지 검증한다.

    참고: appid 확장을 사용할 경우 이 단계에 특별한 로직이 필요하다. 세부사항은 § 10.1.1 FIDO AppID Extension (appid) 참고.

  16. UP 비트가 authDataflags 내에 설정되어 있는지 확인한다.

  17. 이 어서션에 대해 사용자 검증이 필요한지 결정한다. 사용자 검증pkOptions.userVerificationrequired로 지정된 경우에만, 그리고 반드시 필요하도록 해야 한다.

    만약 사용자 검증이 필요하다면, UV 비트가 authDataflags 내에 설정되어 있는지 확인한다. 필요하지 않다면 UV flag 값은 무시한다.

  18. BE 비트가 authDataflags 에서 설정되어 있지 않으면, BS 비트가 설정되지 않았는지 확인한다.

  19. 자격 증명의 백업 상태Relying Party의 업무 로직이나 정책에서 쓰인다면, currentBecurrentBs를 각각 BE, BS 비트의 값으로 두고, credentialRecord.backupEligiblecredentialRecord.backupState 와 비교한다:

    1. credentialRecord.backupEligible 이 설정돼 있으면, currentBe가 설정돼 있는지 확인한다.

    2. credentialRecord.backupEligible 이 설정돼 있지 않으면, currentBe도 설정돼 있지 않은지 확인한다.

    3. Relying Party 정책이 있다면 적용한다.

    참고: § 6.1.3 자격 증명 백업 상태Relying PartyBS flag를 처리하는 예시가 있다.

  20. cData에 대해 SHA-256 해시를 계산한 결과를 hash로 둔다.

  21. credentialRecord.publicKey 를 사용하여, sigauthDatahash를 바이너리로 이어붙인 값에 대한 올바른 서명인지 검증한다.

    참고: 이 검증 단계는 FIDO U2F 인증기가 생성한 서명도 호환된다. § 6.1.2 FIDO U2F 서명 형식 호환성 참고.

  22. authData.signCount 가 0이 아니거나 credentialRecord.signCount 가 0이 아니면, 다음 하위 단계를 실행한다:

    • authData.signCount 값이

      크면 credentialRecord.signCount보다:
      서명 카운터가 유효하다.
      작거나 같으면 credentialRecord.signCount보다:
      이는 인증기가 복제(clone)되었을 수도 있다는 신호이나, 증거는 아니다. 예를 들어 다음과 같은 경우일 수 있다:
      • 두 개 이상의 자격 증명 개인키가 존재하며 동시에 사용되는 경우.

      • 인증기가 고장난 경우.

      • Relying Party가 인증기에서 생성된 순서와 다른 순서로 어서션 응답을 처리하는 경쟁 조건이 존재하는 경우.

      Relying Party는 스스로의 운영 특성에 따라 위험 평가에 이 정보를 반영해야 한다. 이 경우 Relying Party가 아래에서 credentialRecord.signCount 를 갱신할지, 인증 의식 authentication ceremony를 실패 처리할지 등은 Relying Party별로 다르다.

      서명 카운터에 관한 더 자세한 정보는 § 6.1.1 서명 카운터 관련 사항 참고.

  23. clientExtensionResults에 있는 클라이언트 확장 출력과, authDataextensions 에 있는 인증기 확장 출력Relying Party가 요구하는 대로 처리한다. 각 확장별로 명확하게 처리 단계가 규정되어 있을 수도 있고, Relying Party가 자유롭게 처리할 수도 있다. Relying Party는 부분 또는 전체 확장 출력을 무시할 수 있다.

    클라이언트는 추가 인증기 확장 또는 클라이언트 확장을 설정해 인증기 확장 출력 또는 클라이언트 확장 출력Relying PartypkOptions.extensions 에서 요청하지 않은 값이 담기게 할 수 있다. 이때 Relying Party는 해당 확장을 무시하거나 어서션을 거부할 수 있으며, 이 결정은 정책 및 사용 중인 확장에 따라 다르다.

    모든 확장은 클라이언트인증기 모두에서 선택 사항이므로, Relying Party는 요청한 확장 중 일부 또는 전부가 처리되지 않을 수 있음을 대비해야 한다.

  24. credentialRecord을(를) 새 상태 값으로 갱신한다:
    1. credentialRecord.signCount 값을 authData.signCount 값으로 갱신한다.

    2. credentialRecord.backupState 값을 currentBs 값으로 갱신한다.

    3. credentialRecord.uvInitializedfalse라면, authDataUV 비트 값을 반영해 갱신한다. 이 때 이 변경은 WebAuthn 사용자 검증과 동등한 인증 수단 추가 인증을 요구해야 하며, 인증이 안 된다면 이 단계는 건너뛴다.

    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

구문

Packed Attestation의 구문은 아래 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 형식으로 인코딩된 어테스테이션 인증서 값입니다.

서명 절차

이 어테스테이션 명세 형식의 서명 절차는 어설션 서명 생성 절차와 비슷합니다.

  1. authenticatorData어테스테이션을 위한 인증기 데이터로, clientDataHash직렬화된 클라이언트 데이터의 해시로 둡니다.

  2. Basic 또는 AttCA 어테스테이션이 사용될 경우, 인증기는 authenticatorDataclientDataHash를 연결해 sig를 만들고, 인증기에서 선택한 어테스테이션 개인키로 서명합니다. x5c에는 attestnCert 및 연관 인증서 체인(있을 경우)을 설정합니다. alg는 어테스테이션 개인키의 알고리즘으로 설정합니다.

  3. Self 어테스테이션이 사용될 경우, 인증기는 authenticatorDataclientDataHash를 연결해 sig를 만들고, 자격 증명 개인키로 서명합니다. alg는 자격 증명 개인키의 알고리즘으로 설정하고, 나머지 필드는 생략합니다.

검증 절차

검증 절차 입력값 attStmt, authenticatorData, clientDataHash가 주어지면, 검증 절차 는 아래와 같습니다:

  1. attStmt가 위에 정의된 구문대로 올바른 CBOR인지 검증하고, CBOR 디코딩으로 포함된 필드를 추출합니다.

  2. x5c가 있을 경우:

    • alg에 지정된 알고리즘을 사용해, attestnCert의 어테스테이션 공개키로 authenticatorDataclientDataHash를 연결한 값에 대한 sig가 올바른 서명인지 검증합니다.

    • 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 또는 불명확, 그리고 어테스테이션 트러스트 경로 x5c)를 반환합니다.

  3. x5c가 없으면, Self 어테스테이션이 사용 중입니다.

8.2.1. Packed 어테스테이션 명세의 인증서 요구사항

어테스테이션 인증서에는 다음 필드/확장이 반드시 포함되어야 합니다:

그 외에, Authority Information Access(AIA) 확장의 id-ad-ocsp 항목, 그리고 CRL Distribution Point 확장([RFC5280])은 선택적입니다. 이는 많은 어테스테이션 인증서의 상태가 인증기 메타데이터 서비스로도 제공되기 때문입니다. 예를 들어, FIDO Metadata Service [FIDOMetadataService] 참고.

특정 인증기 모델의 펌웨어 버전 구분을 위해 Extension OID 1.3.6.1.4.1.45724.1.1.5 (id-fido-gen-ce-fw-version)를 사용할 수 있습니다. 있을 경우, 이 속성 값은 0 이상의 정수(INTEGER)이며, 펌웨어 버전이 올라가면 증가됩니다. 이 확장은 critical로 지정하면 안 됩니다.

예를 들어, 다음은 위 확장 OID와 필드를 포함하는 어테스테이션 인증서입니다:

-----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                                 -- 펌웨어 버전: 42

8.2.2. 엔터프라이즈 Packed 어테스테이션 명세의 인증서 요구사항

Extension OID 1.3.6.1.4.1.45724.1.1.2 (id-fido-gen-ce-sernum)은 엔터프라이즈 목적의 packed 어테스테이션에서 추가로 포함될 수 있습니다. 있을 경우, 이 확장은 특정 AAGUID에 대해 기기별로 고유한 octet string 값을 포함해야 합니다. 이 값은 공장 초기화(factory reset) 동안에도 동일하게 유지되어야 하며, 기기와 연관된 다른 일련번호 또는 하드웨어 식별자와는 다를 수도 있습니다. 이 확장은 critical로 지정하면 안 되며, 값은 OCTET STRING으로 인코딩되어야 하며, 엔터프라이즈가 아닌 어테스테이션에는 포함되지 않아야 합니다.

8.3. TPM 어테스테이션 명세 형식

이 어테스테이션 명세 형식은 일반적으로 암호 엔진으로 신뢰 플랫폼 모듈(TPM)을 사용하는 인증기에서 사용됩니다.

어테스테이션 명세 형식 식별자

tpm

지원 어테스테이션 타입

AttCA

구문

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

X.509 인코딩된 aikCert 및 그 인증서 체인입니다.

aikCert

어테스테이션에 사용되는 AIK 인증서(X.509 인코딩).

sig

어테스테이션 서명 값으로, [TPMv2-Part2] 11.3.4절에 명시된 대로 TPMT_SIGNATURE 구조체입니다.

certInfo

위 서명이 계산된 TPMS_ATTEST 구조체로, [TPMv2-Part2] 10.12.8절 참고.

pubArea

TPM이 자격 증명 공개키를 나타내는 데 사용하는 TPMT_PUBLIC 구조체([TPMv2-Part2] 12.2.4절 참고)입니다.

서명 절차

authenticatorData어테스테이션을 위한 인증기 데이터로, clientDataHash직렬화된 클라이언트 데이터의 해시로 둡니다.

authenticatorDataclientDataHash를 연결하여 attToBeSigned를 만듭니다.

[TPMv2-Part3] 18.2절의 절차에 따라 어테스테이션 개인키를 사용해 서명을 생성합니다. 이때 extraData 파라미터에는 attToBeSigned를 "alg"와 대응되는 해시 알고리즘으로 다이제스트한 값을 사용합니다. ("RS256"의 경우 SHA-256.)

pubArea 필드는 자격 증명 공개키의 공개 영역(TPMT_PUBLIC 구조체)로, certInfo는 TPMS_ATTEST 구조체, sig는 위 과정에서 얻은 서명 값으로 각각 설정합니다.

참고: TPM의 TPM2_ReadPublic 명령으로 pubArea를 읽으면 TPM2B_PUBLIC 구조체가 반환됩니다. TPM2B_PUBLIC은 2바이트 길이 뒤에 TPMT_PUBLIC가 오므로, 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 구조체입니다.

  • magic 값이 TPM_GENERATED_VALUE로 설정됐는지 확인합니다.

  • type 값이 TPM_ST_ATTEST_CERTIFY로 설정됐는지 확인합니다.

  • extraDataattToBeSigned에 대해 "alg" 해시 알고리즘으로 계산된 해시인지 확인합니다.

  • attested[TPMv2-Part2] 10.12.3절 기준으로, name 필드가 pubArea의 유효한 Name(이름)인 TPMS_CERTIFY_INFO 구조체가 있는지 확인합니다. Name 계산은 [TPMv2-Part1] 16절의 nameAlg 규칙에 따라 시행합니다.

    참고: TPM은 항상 namepubArea의 nameAlg와 동일한 nameAlg가 사용된 TPMS_CERTIFY_INFO 구조체를 반환합니다.

    참고: "표준 어테스테이션 구조체" ([TPMv2-Part1] 31.2절)의 qualifiedSigner, clockInfo, firmwareVersion 필드는 무시합니다. aikCert 키 속성에 따라 해당 값들이 가려질 수 있습니다. 유효하다면 위험 엔진의 입력값으로 사용할 수 있습니다.

  • 모두 성공하면, 구현에 맞는 값(예: 어테스테이션 타입 AttCA어테스테이션 트러스트 경로 x5c)을 반환합니다.

8.3.1. TPM 어테스테이션 명세의 인증서 요구사항

TPM 어테스테이션 인증서에는 다음 필드/확장이 반드시 포함되어야 합니다:

8.4. Android Key 어테스테이션 명세 형식

해당 인증기가 Android "N" 이상 플랫폼의 플랫폼 인증기라면, 어테스테이션 명세는 Android 키 어테스테이션에 기반합니다. 이런 경우, 어테스테이션 명세는 보안 운영 환경에서 동작하는 컴포넌트가 생성하지만, 어테스테이션을 위한 인증기 데이터는 이 환경 외부에서 생성됩니다. WebAuthn Relying Party어테스테이션에 사용된 것으로 주장되는 인증기 데이터가 어테스테이션 인증서 확장 데이터 필드와 일치하는지 확인해야 합니다.

어테스테이션 명세 형식 식별자

android-key

지원 어테스테이션 타입

Basic

구문

Android key 어테스테이션 명세는 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 어테스테이션을 요청할 때 keyStore.getCertificateChain(myKeyUUID)를 호출하고, clientDataHash를 challenge 값으로 제공합니다(예: setAttestationChallenge 사용). x5c는 반환 값을 그대로 사용합니다.

인증기는 authenticatorDataclientDataHash를 연결한 값을 자격 증명 개인키로 서명하여 sig 값을 생성하고, alg는 해당 서명 알고리즘으로 설정합니다.

검증 절차

검증 절차 입력값 attStmt, authenticatorData, clientDataHash가 주어지면, 검증 절차는 다음과 같습니다:

  • attStmt가 위 정의된 구문에 맞는 유효한 CBOR인지 확인하고, CBOR 디코딩 후 필드를 추출합니다.

  • sigauthenticatorDataclientDataHash를 연결해 만든 값에 대해 x5c 첫번째 인증서의 공개키와 alg 알고리즘으로 올바른 서명인지 검증합니다.

  • x5c의 첫 번째 인증서에서 추출한 공개키가, authenticatorDatacredentialPublicKey 와 동일한지 검증합니다.

  • 어테스테이션 인증서의 확장 데이터attestationChallenge 필드가 clientDataHash와 동일한지 검증합니다.

  • 어테스테이션 인증서 확장 데이터의 authorization list에서 아래 항목을 확인합니다:

    • AuthorizationList.allApplications 필드는 두 authorization list(softwareEnforced, teeEnforced) 어디에도 없어야 합니다. PublicKeyCredential은 반드시 RP ID 범위여야 합니다.

    • 이하 조건들은 RP가 신뢰 실행환경(TEE) 키만 허용하려면 teeEnforced 리스트만, 그렇지 않으면 teeEnforcedsoftwareEnforced의 합집합을 사용합니다.

      • AuthorizationList.origin 필드 값이 KM_ORIGIN_GENERATED과 일치해야 합니다.

      • AuthorizationList.purpose 필드 값이 KM_PURPOSE_SIGN과 일치해야 합니다.

  • 모두 성공 시, 구현에 따라 어테스테이션 유형 Basic어테스테이션 트러스트 경로 x5c를 반환합니다.

8.4.1. Android Key 어테스테이션 명세의 인증서 요구사항

Android Key 어테스테이션 어테스테이션 인증서Android key 어테스테이션 인증서 확장 데이터는 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

구문

Android 어테스테이션 명세의 구문은 다음과 같습니다:

$$attStmtType //= (
                      fmt: "android-safetynet",
                      attStmt: safetynetStmtFormat
                  )

safetynetStmtFormat = {
                          ver: text,
                          response: bytes
                      }

각 필드의 의미는 다음과 같습니다:

ver

SafetyNet API를 제공하는 Google Play Services의 버전번호입니다.

response

SafetyNet API의 getJwsResult() 호출의 UTF-8 인코딩 결과입니다. 이 값은 Compact Serialization 형태의 JWS [RFC7515] 객체입니다(자세한 내용은 SafetyNet 온라인 문서 참고).

서명 절차

authenticatorData어테스테이션을 위한 인증기 데이터로, clientDataHash직렬화된 클라이언트 데이터의 해시로 둡니다.

authenticatorDataclientDataHash를 연결하고, SHA-256 해시를 수행해 나온 결과를 attToBeSigned로 둡니다.

SafetyNet 어테스테이션을 요청할 때 attToBeSigned를 nonce로 제공해야 합니다. response는 SafetyNet이 반환한 응답, ver는 구동 중인 Google Play Services 버전으로 설정합니다.

검증 절차

검증 절차 입력값 attStmt, authenticatorData, clientDataHash가 주어지면, 검증 절차는 다음과 같습니다:

  • attStmt가 위 구문에 맞는 유효한 CBOR인지, CBOR 디코딩 후 필드를 추출합니다.

  • response 값이 ver 버전을 따르는 올바른 SafetyNet 응답인지 SafetyNet 온라인 문서에 정의된 단계로 검사합니다. (현재 SafetyNet 응답 형식은 하나뿐이며, ver는 향후 지원을 위해 예약됨.)

  • response의 payload에서 nonce 속성이 authenticatorDataclientDataHash를 연결해 SHA-256 한 값을 Base64한 값과 동일한지 검증합니다.

  • SafetyNet 응답이 실제로 SafetyNet 서비스에서 발급됐는지 SafetyNet 온라인 문서에 안내된 절차로 확인합니다.

  • 모두 성공 시, 구현 의사에 따라 어테스테이션 유형 Basic어테스테이션 트러스트 경로 x5c를 반환합니다.

8.6. FIDO U2F 어테스테이션 명세 형식

이 어테스테이션 명세 형식은 [FIDO-U2F-Message-Formats]에 정의된 포맷을 사용하는 FIDO U2F 인증기에서 사용됩니다.

어테스테이션 명세 형식 식별자

fido-u2f

지원 어테스테이션 타입

Basic, AttCA

구문

FIDO U2F 어테스테이션 명세의 구문은 다음과 같습니다:

$$attStmtType //= (
                      fmt: "fido-u2f",
                      attStmt: u2fStmtFormat
                  )

u2fStmtFormat = {
                    x5c: [ attestnCert: bytes ],
                    sig: bytes
                }

각 필드의 의미는 다음과 같습니다:

x5c

X.509 형식의 어테스테이션 인증서 한 개가 담긴 배열입니다.

sig

어테스테이션 서명 값입니다. 이 서명은 [FIDO-U2F-Message-Formats]에 정의된 U2F 등록 응답 메시지 원문 전체에 대해 계산됩니다. (인증기로부터 클라이언트가 전송받은 데이터.)

서명 절차

attested credential자격 증명 공개키가 알고리즘 -7("ES256")이 아니면 중지하고 에러를 반환합니다. 그렇지 않으면 authenticatorData어테스테이션을 위한 인증기 데이터로, clientDataHash직렬화된 클라이언트 데이터의 해시로 둡니다. (SHA-256이 쓰이므로 clientDataHash는 32바이트입니다.)

[FIDO-U2F-Message-Formats] 4.3절(Registration Response Message)에 따라 등록 응답 메시지를 만드는데, application parameter는 해당 자격 증명속한 RP ID의 SHA-256 해시, challenge parameter는 clientDataHash, key handle parameter는 해당 자격 증명 ID로 합니다. 해당 메시지의 raw signature 부분(즉, 사용자 공개키, key handle, 인증서 제외)이 sig로, 어테스테이션 공개키의 인증서가 x5c로 설정됩니다.

검증 절차

검증 절차 입력값 attStmt, authenticatorData, clientDataHash가 주어지면, 검증 절차는 다음과 같습니다:

  1. attStmt가 위 구문대로 유효한 CBOR인지 확인한 후, CBOR 디코딩 후 필드를 추출합니다.

  2. x5c에 정확히 한 개의 요소가 있는지 확인하고, attCert가 해당 인증서임을 둡니다. certificate public keyattCert의 공개키입니다. 만약 해당 공개키가 P-256 곡선 상의 타원곡선(EC) 공개키가 아니라면 실패 처리합니다.

  3. authenticatorData에서 rpIdHash를, 그리고 authenticatorData.attestedCredentialData에서 credentialIdcredentialPublicKey를 추출합니다.

  4. credentialPublicKey(COSE_KEY 형식, RFC9052 7절)을 Raw ANSI X9.62 공개키 형식(FIDO Registry 3.6.2절)으로 변환합니다.

    • xcredentialPublicKey의 "-2" 키(x 좌표) 값으로, 크기는 32바이트이어야 합니다. 크기가 다르거나 키가 없으면 알고리즘을 실패 처리합니다.

    • ycredentialPublicKey의 "-3" 키(y 좌표) 값으로, 크기는 32바이트이어야 합니다. 크기가 다르거나 키가 없으면 실패 처리합니다.

    • publicKeyU2F0x04 || x || y로 연결한 값입니다.

      참고: 이것은 ECC 압축되지 않은(UNCOMPRESSED) 공개키 형식입니다.

  5. verificationData0x00 || rpIdHash || clientDataHash || credentialId || publicKeyU2F으로 연결한 값입니다(4.3절 참고).

  6. sigverificationDatacertificate public key[SEC1] 4.1.4절의 절차에 따라 SHA-256 해시를 사용해 검증합니다.

  7. 선택적으로 x5c를 검사하고, 외부 정보를 참고해 attStmtBasic 또는 AttCA 어테스테이션인지 확인 가능합니다.

  8. 모두 성공하면, 구현 의사에 따라 어테스테이션 유형 Basic, AttCA 또는 불명확, 그리고 어테스테이션 트러스트 경로 x5c를 반환합니다.

8.7. None 어테스테이션 명세 형식

none 어테스테이션 명세 형식은 WebAuthn Relying Party인증기가 제공한 어테스테이션 명세를 받고 싶지 않음을 나타냈을 때, 이를 대체하는 용도로 사용됩니다. 자세한 내용은 § 5.4.7 Attestation Conveyance Preference Enumeration (enum AttestationConveyancePreference)를 참조하십시오.

인증기어테스테이션을 지원하지 않으면, 인증기가 직접 이 형식의 어테스테이션 명세를 생성할 수도 있습니다.

어테스테이션 명세 형식 식별자

none

지원 어테스테이션 타입

None

구문

none 어테스테이션 명세의 구문은 다음과 같습니다:

$$attStmtType //= (
                      fmt: "none",
                      attStmt: emptyMap
                  )

emptyMap = {}
서명 절차

위에 정의된 정해진 어테스테이션 명세를 반환합니다.

검증 절차

구현의사에 맞게 어테스테이션 유형 None과 빈 어테스테이션 트러스트 경로를 반환합니다.

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. attStmt 내의 각 subStmt마다 해당 어테스테이션 명세 형식 식별자 subStmt.fmt에 대응하는 검증 절차검증 절차 입력값 (subStmt, authenticatorData, clientDataHash)로 평가합니다.

    하나 이상의 subStmt에 대해 유효성 검증에 실패하면, 이에 대한 처리는 Relying Party 정책에 따릅니다.

  2. 충분히 많은(이 기준은 Relying Party 정책에 따라 결정됨) 항목이 성공적으로 검증되면, 성공한 검증 절차의 출력 조합을 나타내는 구현별 값을 반환합니다.

9. WebAuthn 확장

공개키 자격 증명의 생성, 인증 어서션의 요청 및 생성을 위한 § 5 Web Authentication API에서 정의된 메커니즘은 특정 용례에 맞게 확장할 수 있습니다. 각 용례는 등록 확장 또는 인증 확장을 정의함으로써 지원됩니다.

모든 확장은 클라이언트 확장입니다. 즉, 확장은 클라이언트와의 통신과 처리 과정을 포함합니다. 클라이언트 확장은 다음과 같은 단계와 데이터를 정의합니다:

공개키 자격 증명을 생성하거나 인증 어서션을 요청할 때 WebAuthn Relying Party는 여러 확장들의 사용을 요청할 수 있습니다. 각 확장은 클라이언트 또는 WebAuthn 인증기가 지원할 경우 해당 작업 도중 호출됩니다. Relying Partyget() 호출(인증 확장) 또는 create() 호출(등록 확장)에서 각 확장에 대해 클라이언트 확장 입력을 전송합니다. 클라이언트는 지원하는 각 확장마다 클라이언트 확장 처리를 수행하며, 각 확장별로 확장 식별자클라이언트 확장 출력 값을 클라이언트 데이터에 포함해 결과를 보강합니다.

확장에는 인증기 확장도 있습니다. 인증기 확장은 인증기와의 통신 및 처리를 포함한다는 의미입니다. 인증기 확장은 다음 단계를 정의합니다:

인증기 확장의 경우, 클라이언트 확장 처리의 일환으로, 클라이언트는 각 확장에 대해 CBOR 인증기 확장 입력 값을 생성(보통 대응하는 클라이언트 확장 입력에서 계산)하여 호출 도중 인증기에 전달합니다(create() 호출 시 등록 확장, get() 호출 시 인증 확장). 이 값들은 CBOR 형식의 이름-값 쌍으로 전달되며, 이름은 확장 식별자, 값은 해당 인증기 확장 입력입니다. 인증기는 지원하는 확장별로 추가 처리를 하고, 각 확장별로 CBOR 인증기 확장 출력을 반환합니다. 인증기 확장 출력은 서명된 인증기 데이터 일부로 반환되므로, 인증기 확장에서는 서명되지 않은 확장 출력도 정의할 수 있습니다(예: 출력 값이 인증기 데이터에 의존적일 때). 클라이언트 확장 처리의 일환으로 인증기 확장에서 인증기 확장 출력 및 서명되지 않은 확장 출력을 활용하여 클라이언트 확장 출력을 생성할 수도 있습니다.

모든 WebAuthn 확장은 클라이언트와 인증기 모두에서 선택사항입니다. 즉, Relying Party가 요청한 확장을 브라우저 또는 OS가 인증기까지 전달하지 않거나, 인증기가 무시할 수 있으며, 어떠한 경우에도 WebAuthn API 처리 과정에서 실패로 간주하지 않습니다. 따라서 Relying Party는 확장을 API 호출에 포함할 때, 일부 또는 전부가 무시될 수 있음을 고려해야 합니다.

모든 WebAuthn 확장클라이언트인증기가 미지원하더라도 사용자의 보안 및 프라이버시를 침해하지 않도록 정의해야 합니다. 예를 들어, 확장에서 클라이언트 처리가 필요하다면 JSON에서 CBOR로 단순 변환만 해도 인증기에서 의미 없는 값을 생성하게 설계하면, 인증기는 해당 확장을 자동으로 무시합니다. 모든 확장이 선택사항이므로 이로 인해 API 동작상 실패가 발생하지 않습니다.

최신 WebAuthn 확장 목록은 [IANA-WebAuthn-Registries]의 IANA "WebAuthn Extension Identifiers" registry에서 확인 가능합니다.

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 인증기 확장 출력 값을 지정해야 합니다. 확장은 서명되지 않은 확장 출력도 정의할 수 있습니다.

클라이언트가 처리하는 클라이언트 확장은, 반드시 클라이언트 확장 출력값을 반환해야 하며, 이를 통해 WebAuthn Relying Party가 해당 확장이 클라이언트에서 처리된 것을 인지할 수 있습니다. 마찬가지로 인증기 처리가 필요한 확장은 반드시 인증기 확장 출력을 반환하여, Relying Party가 인증기에서 처리됐음을 인지할 수 있게 해야 합니다. 결과 값이 필요 없는 확장은 true로 된 JSON Boolean 클라이언트 확장 출력으로 정의할 수 있습니다. 인증기 확장도 마찬가지로, 값이 필요 없다면 true(CBOR Boolean)을 반환해야 합니다.

9.3. 확장 요청 파라미터 확장하기

확장은 1~2개의 요청 인자를 정의합니다. 클라이언트 확장 입력은 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"
            }
        }
    }
});

확장 정의 시 클라이언트 확장 입력의 유효 값도 명시해야 합니다. 클라이언트는 유효하지 않은 입력의 확장은 무시해야 합니다. 인자 값이 필요 없는 확장은 Boolean 값 true로 요청하도록 정의할 수 있습니다.

클라이언트 처리에만 영향을 주는 확장은 인증기 확장 입력을 정의할 필요가 없습니다. 인증기 처리가 필요한 확장은 클라이언트 확장 입력에서 인증기 확장 입력을 어떻게 계산하는지 정의해야 하며, CDDL 타입 AuthenticationExtensionsAuthenticatorInputsAuthenticationExtensionsAuthenticatorOutputs에서 $$extensionInput$$extensionOutput 그룹 소켓에 확장 식별자를 키로 추가해야 합니다. 입력 파라미터가 필요없는 확장(즉, Boolean 클라이언트 확장 입력 true)은 인증기 확장 입력도 Boolean true(CBOR major type 7, value 21)로 정의됩니다.

아래 예시는 식별자 webauthnExample_foobar인 확장이 unsigned integer 입력을 인증기 확장 입력으로 받고, 1개 이상의 바이트 문자열 배열을 인증기 확장 출력값으로 반환함을 정의합니다:

$$extensionInput //= (
  webauthnExample_foobar: uint
)
$$extensionOutput //= (
  webauthnExample_foobar: [+ bytes]
)

일부 인증기는 블루투스 저전력, NFC 등 좁은 대역폭 링크를 사용하므로, 확장 설계 시 인증기 인자가 최대한 작도록 권장합니다.

9.4. 클라이언트 확장 처리

확장은 자격 증명 생성 또는 어서션 생성 시 클라이언트에서 추가 처리 요구를 정의할 수 있습니다. 해당 확장의 클라이언트 확장 입력값이 이 처리의 입력값이 됩니다. 클라이언트는 지원하는 클라이언트 확장마다 clientExtensions map에 확장 식별자를 키, 해당 확장 입력값을 값으로 추가합니다.

마찬가지로, 클라이언트 확장 출력getClientExtensionResults() 반환값의 딕셔너리로 표현되며, 키는 확장 식별자, 값은 각 확장의 클라이언트 확장 출력입니다. 클라이언트 확장 입력처럼, 클라이언트 확장 출력도 JSON으로 인코딩 가능한 값이어야 합니다. 무시된 확장에 대해서는 어떤 값도 반환하면 안 됩니다.

인증기 처리 확장이 필요한 경우, 클라이언트 확장 입력을 바탕으로 CBOR 인증기 확장 입력을 계산하는 방법과, CBOR 인증기 확장 출력, 그리고 서명되지 않은 확장 출력이 사용될 때, 그것을 클라이언트 확장 출력으로 변환하는 방법도 정의해야 합니다.

9.5. 인증기 확장 처리

처리된 각 인증기 확장CBOR 인증기 확장 입력 값은 authenticatorMakeCredentialauthenticatorGetAssertion 동작의 extensions 파라미터에 포함됩니다. extensions는 CBOR map으로, 키는 확장 식별자이며 값은 해당 인증기 확장 입력입니다.

확장 출력은 인증기 데이터의 extensions 파트에 표현됩니다. 인증기 데이터extensions 파트는 CBOR map으로, 키는 확장 식별자이며 값은 해당 인증기 확장 출력입니다.

서명되지 않은 확장 출력은 인증기 데이터와 별개로 표현되며, 인증기가 반환하는 별도 map입니다(키는 동일 확장 식별자를 사용함). 이 map은 서명되지 않은 출력을 사용하는 인증기 확장에만 해당 항목을 포함합니다. 확장에서 인증기 데이터에 대한 서명을 출력하는 경우, 또는 일부 출력이 Relying Party에 전송되지 않아야 할 경우 등에서 유용합니다.

참고: [FIDO-CTAP]에서는 unsignedExtensionOutputs라는 map에 CBOR로 반환됩니다.

각 지원 확장별로, 해당 확장에 대한 인증기 확장 처리 규칙을 적용해 인증기 확장 출력 및 필요시 서명되지 않은 확장 출력을 해당 입력과 추가 입력값에서 계산합니다. 무시된 확장에 대해서는 어떤 값도 반환하면 안 됩니다.

10. 정의된 확장

이 절과 하위 절에서는 IANA "WebAuthn Extension Identifiers" 레지스트리([IANA-WebAuthn-Registries])에 추가로 등록될 확장들을 정의합니다. 이 확장들은 다양한 상호운용성을 목표로 사용자 에이전트에서 구현될 수 있습니다.

10.1. 클라이언트 확장

이 절에서는 오직 클라이언트 확장만을 정의합니다.

10.1.1. FIDO AppID 확장 (appid)

이 확장은 이전에 FIDO U2F JavaScript API [FIDOU2FJavaScriptAPI]로 자격 증명을 등록한 WebAuthn Relying Party가 어서션을 요청할 수 있도록 합니다. FIDO API는 Relying Party에 대해 AppID라는 추가 식별자를 사용하며([FIDO-APPID]), 해당 API로 생성된 자격 증명은 모두 그 식별자로 스코프가 지정됩니다. 이 확장 없이는 AppID가 아닌 RP ID로 스코프를 변경하려면 자격 증명을 재등록해야 했습니다.

appid 확장 입력 외에, U2F 자격 증명 인증을 허용하려면 Relying Party 쪽에서 다음 추가 처리가 필요합니다:

  1. 원하는 U2F 자격 증명들을 allowCredentials 옵션에 나열합니다. get() 메서드 이용:

    • type 값을 public-key로 설정.

    • id 값은 원하는 U2F 키 핸들로 설정. U2F 키 핸들은 보통 base64url 인코딩이지만, 실제 전달 시에는 바이너리로 디코드해야 함.

    allowCredentials 에 WebAuthn 자격 증명 ID와 U2F 키 핸들을 혼합해 사용 가능하며, 이 확장 입력이 WebAuthn의 RP ID 스코프의 자격 증명 사용을 막지는 않습니다.

  2. 어서션 검증시, rpIdHash 값이 RP ID가 아니라 AppID의 해시일 수도 있음을 허용해야 합니다.

이 확장만으로 FIDO 호환 자격 증명을 생성할 수 없습니다. 즉, WebAuthn에서 생성된 자격 증명은 FIDO JS API와 호환되지 않습니다.

참고: appid 값은 Relying Party이전에 FIDO API에서 사용한 AppID로 설정해야 하며, WebAuthn RP ID와 변환 값이 다를 수 있습니다. 예를 들어 이전 AppID가 "https://accounts.example.com"이었고, 현재 RP ID가 "example.com"일 수 있음.

확장 식별자

appid

적용 용도

인증

클라이언트 확장 입력

FIDO AppID를 지정하는 DOMString 하나.

partial dictionary AuthenticationExtensionsClientInputs {
  DOMString appid;
};
클라이언트 확장 처리
  1. facetId를 호출자의 origin을 FIDO의 FacetID 결정 알고리즘에 넣어 얻습니다.

  2. appId는 확장 입력입니다.

  3. facetIdappId를 FIDO의 FacetID가 해당 AppID에 대해 권한이 있는지 판단하는 알고리즘에 전달합니다. 거부되면 SecurityError DOMException 를 반환합니다.

  4. allowCredentialDescriptorList 생성 중에, U2F 인증기가 자격 증명이 부적합하다고 나타내면(SW_WRONG_DATA 반환 등) 클라이언트는 U2F application parameter를 appId의 SHA-256 해시로 다시 시도해야 하며, 이로 유효한 자격 증명을 찾으면 이를 리스트에 반드시 포함해야 합니다. 이 경우 appIdauthenticatorGetAssertion의 rpId 파라미터 대신 사용됩니다.

  5. output를 Boolean false로 둡니다.

  6. assertionCreationData 생성 시, U2F 인증기가 appId의 SHA-256 해시를 U2F application parameter로 사용해 어서션을 만들었다면 outputtrue로 둡니다.

참고: 실제로는 여러 구현이 위 FacetID/권한검증 알고리즘의 step 4 이후를 생략하며, 대신 step 3에서 호스트 비교를 동일 사이트(same site)까지만 허용합니다.

클라이언트 확장 출력

output 값을 반환합니다. true면 AppID가 사용됐으므로 어서션 검증rpIdHashAppID의 해시, RP ID가 아니여야 함을 Relying Party가 예상해야 합니다.

partial dictionary AuthenticationExtensionsClientOutputs {
  boolean appid;
};
인증기 확장 입력

없음.

인증기 확장 처리

없음.

인증기 확장 출력

없음.

10.1.2. FIDO AppID 제외 확장(appidExclude)

이 등록 확장은 WebAuthn Relying Party가 이전 FIDO U2F JavaScript API [FIDOU2FJavaScriptAPI]로 생성된 특정 자격 증명을 포함하는 인증기를 제외하도록 허용합니다.

FIDO U2F JavaScript API에서의 전환 중, Relying Party는 레거시 자격 증명을 이미 등록한 사용자를 다수 보유할 수 있습니다. appid 확장은 로그인 플로우 전환을 원활하게 할 수 있지만, 등록 플로우 전환 시 excludeCredentials 필드는 해당 내용을 WebAuthn 자격 증명으로만 간주하기 때문에 레거시 자격 증명이 있는 인증기를 효과적으로 제외하지 못합니다. 이 확장은 클라이언트 플랫폼excludeCredentials 목록을 WebAuthn과 레거시 FIDO 자격 증명 모두로 간주하도록 지시합니다. 참고로, U2F 키 핸들은 일반적으로 base64url 인코딩을 사용하지만, excludeCredentials 내에서 사용할 때는 바이너리로 디코딩해야 합니다.

확장 식별자

appidExclude

적용 작업

등록

클라이언트 확장 입력

FIDO AppID를 지정하는 단일 DOMString 값.

partial dictionary AuthenticationExtensionsClientInputs {
  DOMString appidExclude;
};
클라이언트 확장 처리

새 자격 증명 생성 시:

  1. RP ID를 정한 직후 다음 단계 수행:

    1. facetId를 호출자의 origin을 FIDO FacetID 결정 알고리즘에 넣은 결과로 한다.

    2. appId를 확장 입력 appidExclude의 값으로 한다.

    3. facetId, appId를 FIDO FacetID/권한 알고리즘에 전달한다. 거부되면 SecurityError DOMException 을 반환하고 자격 증명 생성 알고리즘 및 이 절차를 즉시 종료한다.

      참고: 실제로 여러 구현체는 FacetID/AppID 권한 알고리즘의 4단계 이후를 구현하지 않으며, 대신 3단계에서 호스트 비교를 same site로 완화함.

    4. 위 조건에 걸리지 않으면 일반 절차대로 진행.

  2. authenticatorMakeCredential 호출 직전 다음 단계 수행:

    1. authenticator가 U2F 프로토콜 [FIDO-U2F-Message-Formats] 지원 시, excludeCredentialDescriptorList 내credential descriptor C에 대해:

      1. C가 U2F 자격 증명인지 확인하려면 authenticator에 다음 "5가지 값"으로 U2F_AUTHENTICATE 메시지를 전송:

        control byte

        0x07 ("check-only")

        challenge parameter

        32바이트 랜덤

        application parameter

        appId의 SHA-256 해시

        key handle length

        C.id의 길이(바이트)

        key handle

        C.id, 즉 credential id

      2. authenticatormessage:error:test-of-user-presence-required (즉, 성공)으로 응답하면, 해당 authenticator에 대한 일반 처리 중단 및 플랫폼 구현별로 인증기 사용 불가 표시(UI, 추가 사용자 동의 요청 등, 동의시 InvalidStateError 처리 가능). 사용자 동의는 control byte0x03("enforce-user-presence-and-sign")으로 재전송해 응답 무시해도 됨.

    2. 위 절차 없이 일반 처리 지속.

클라이언트 확장 출력

Relying Party에 이 확장이 적용되었음을 true 값으로 반환합니다.

partial dictionary AuthenticationExtensionsClientOutputs {
  boolean appidExclude;
};
인증기 확장 입력

없음.

인증기 확장 처리

없음.

인증기 확장 출력

없음.

10.1.3. 자격 증명 속성 확장(credProps)

클라이언트 등록 확장클라이언트가 알고 있는 특정 자격 증명 속성WebAuthn Relying Party에게 등록 절차 결과로 공개키 자격 증명 소스가 생성될 때 보고할 수 있도록 합니다.

현재, 하나의 자격 증명 속성이 정의되어 있습니다: 클라이언트 측 발견 가능한 자격 증명 속성입니다.

확장 식별자

credProps

적용 작업

등록

클라이언트 확장 입력

Relying Party가 이 확장을 요청함을 나타내기 위해 true Boolean 값을 입력합니다.

partial dictionary AuthenticationExtensionsClientInputs {
    boolean credProps;
};
클라이언트 확장 처리

authenticatorMakeCredential 연산을 호출할 때 사용된 requireResidentKey 파라미터의 값을 rk로 설정합니다.

클라이언트 확장 출력

Set clientExtensionResults["credProps"]["rk"]authenticatorMakeCredential 연산을 호출할 때 사용된 requireResidentKey 파라미터의 값으로 설정합니다.

dictionary CredentialPropertiesOutput {
    boolean rk;
};

partial dictionary AuthenticationExtensionsClientOutputs {
    CredentialPropertiesOutput credProps;
};
rk, of type boolean

이 선택적 속성은 클라이언트 측 발견 가능한 자격 증명 속성 또는 거주 키 자격 증명 속성이라고도 하며, PublicKeyCredential등록 절차 결과로 클라이언트 측 발견 가능한 자격 증명인지 여부를 나타내는 Boolean 값입니다. rk 값이 true면 자격 증명은 발견 가능한 자격 증명입니다. rk 값이 false서버 측 자격 증명입니다. rk 속성이 존재하지 않으면 해당 자격 증명이 발견 가능한 자격 증명인지 서버 측 자격 증명인지 알 수 없습니다.

참고: 일부 인증기클라이언트 플랫폼이 요청하지 않아도 발견 가능한 자격 증명을 생성할 수 있습니다. 이 때문에 클라이언트 플랫폼rk 값을 충분히 신뢰할 수 없으면 포함하지 않을 수 있습니다. Relying PartycredProps 확장이 지원될 경우 클라이언트 플랫폼rk 속성을 채우려 노력함을 가정해야 하며, 속성이 없으면 생성된 자격 증명이 비발견 자격 증명임을 의미함을 참고하십시오.

인증기 확장 입력

없음.

인증기 확장 처리

없음.

인증기 확장 출력

없음.

10.1.4. 의사 난수 함수 확장 (prf)

클라이언트 등록 확장인증 확장Relying Party자격 증명과 연계된 의사 난수 함수(PRF)의 출력을 계산할 수 있게 해줍니다. 이 확장이 제공하는 PRF는 어떤 길이의 BufferSource도 입력으로 받아 32바이트 BufferSource로 매핑합니다.

대표적인 예로, PRF 출력을 대칭키로 사용해 사용자 데이터를 암호화할 수 있습니다. 이렇게 암호화된 데이터는 연관 자격 증명에서 어서션을 얻을 수 있을 때에만 접근이 가능하게 됩니다. 아래 규정에 따라 한 번의 어서션 작업에서 두 입력에 대해 PRF를 계산하면, 어서션 동안 매번 새 랜덤 입력을 선택해서 암호화 키를 주기적으로 교체할 수 있습니다. 입력이 예측 불가능하다면, 사용자 검증까지 만족하고 인증기에 일시적으로 접근할 수 있더라도 올바른 PRF 입력을 모르면 암호화 키를 얻을 수 없습니다.

이 확장은 [FIDO-CTAP]hmac-secret 확장 위에 구현되어 있습니다. WebAuthn과 하위 플랫폼 간의 사용 분리를 위해 입력과 출력을 사용자 에이전트만 암호화 가능하게 해야 하므로 별도의 클라이언트 확장입니다. 이 분리는 제공된 PRF 입력에 컨텍스트 문자열과 함께 해싱하는 방식으로 이루어지며, 임의 입력에 대한 PRF 계산을 방지합니다.

hmac-secret 확장은 자격 증명 당 2개의 PRF를 제공합니다: 하나는 사용자 검증이 수행될 때, 나머지 하나는 기타 요청에 사용됩니다. 본 확장은 자격 증명 당 하나의 PRF만 노출하며, hmac-secret 구현 시 반드시 사용자 검증이 수행되는 경우의 PRF만 노출해야 합니다. 필요하다면 UserVerificationRequirement를 우선합니다.

참고: 이 확장은 인증기[FIDO-CTAP]을 사용하지 않아도 Relying Party의 관점에서 동일한 동작을 보장하면 구현될 수 있습니다.

확장 식별자

prf

적용 작업

등록인증

클라이언트 확장 입력
dictionary AuthenticationExtensionsPRFValues {
    required BufferSource first;
    BufferSource second;
};

dictionary AuthenticationExtensionsPRFInputs {
    AuthenticationExtensionsPRFValues eval;
    record<DOMString, AuthenticationExtensionsPRFValues> evalByCredential;
};

partial dictionary AuthenticationExtensionsClientInputs {
    AuthenticationExtensionsPRFInputs prf;
};
eval, of type AuthenticationExtensionsPRFValues

PRF를 계산할 하나 또는 두 입력입니다. 모든 인증기가 생성 시 PRF 계산을 지원하지 않으므로, 출력이 없을 수 있습니다. 그렇다면 출력을 얻으려면 어서션이 필요합니다.

evalByCredential, of type record<DOMString, AuthenticationExtensionsPRFValues>

base64url로 인코딩된 자격 증명 ID를 해당 PRF 입력에 매핑합니다. allowCredentials가 비어 있지 않은 경우 어서션에만 적용됩니다.

클라이언트 확장 처리 (등록)
  1. evalByCredential 이 존재하면 이름이 "NotSupportedError"인 DOMException을 반환합니다.

  2. 인증기 확장 입력에서 hmac-secrettrue로 설정합니다.

  3. eval 값이 있고 향후 [FIDO-CTAP]에서 생성 시 PRF 계산을 허용하면, 아래와 같이 hmac-secret 입력을 설정합니다:

    • salt1SHA-256(UTF8Encode("WebAuthn PRF") || 0x00 || eval.first) 값으로 한다.

    • eval.second 값이 있으면 salt2SHA-256(UTF8Encode("WebAuthn PRF") || 0x00 || eval.second) 값으로 한다.

  4. 인증기 확장 출력의 enabledhmac-secret의 값을 할당. 없으면 enabled 값을 false로 설정.

  5. 복호화된 PRF 결과(있다면)를 results 에 설정합니다.

클라이언트 확장 처리 (인증)
  1. evalByCredential 이 비어 있지 않은데 allowCredentials 가 비어 있으면 이름이 "NotSupportedError"인 DOMException을 반환합니다.

  2. evalByCredential 의 어떤 key라도 빈 문자열이거나, 유효한 base64url 인코딩이 아니거나, id 와 일치하지 않으면 (base64url decode 후) 이름이 "SyntaxError"인 DOMException을 반환합니다.

  3. prf 확장 출력을 빈 딕셔너리로 초기화합니다.

  4. ev를 null로 두고, 매핑되는 PRF 입력을 찾음:

    1. evalByCredential 이 존재하고 해당 entrykey가 반환될 credential ID의 base64url 인코딩이면, ev를 그 값으로 한다.

    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. 인증기hmac-secret 확장을 salt1과 (있으면) salt2와 함께 보냅니다.

    4. 확장 결과를 복호화하여 PRF 결과(있으면)를 results 에 씁니다.

인증기 확장 입력 / 처리 / 출력

이 확장[FIDO-CTAP]hmac-secret 확장을 사용해서 인증기와 통신합니다. Relying Party를 위한 별도의 인증기 동작은 명시하지 않습니다.

클라이언트 확장 출력
dictionary AuthenticationExtensionsPRFOutputs {
    boolean enabled;
    AuthenticationExtensionsPRFValues results;
};

partial dictionary AuthenticationExtensionsClientOutputs {
    AuthenticationExtensionsPRFOutputs prf;
};
enabled, of type boolean

생성된 자격 증명에 대해 하나 또는 두 PRF가 사용 가능하면 true입니다. 이 값은 등록 중에만 보고되며, 인증의 경우 전달되지 않습니다.

results, of type AuthenticationExtensionsPRFValues

eval 또는 evalByCredential 입력에 대해 계산된 PRF 결과입니다. 등록 동안 출력이 없는 경우도 있습니다. eval의 설명을 참고하세요.

일부 상황(예: PRF 출력이 클라이언트 측 키 파생에만 사용되는 경우)에서는 results 값을 PublicKeyCredential 이 원격 서버에 전송될 때(예: § 7 WebAuthn Relying Party Operations) 포함하지 않는 것이 필요할 수 있습니다. 특히 RegistrationResponseJSONAuthenticationResponseJSONPublicKeyCredential.toJSON() 을 통해 반환될 때, results 값이 포함될 수 있습니다.

10.1.5. 대용량 blob 저장 확장(largeBlob)

클라이언트 등록 확장인증 확장Relying Party가 자격 증명에 연관된 불투명 데이터(opaque data)를 저장할 수 있게 해줍니다. 인증기는 소량의 데이터만 저장할 수 있고, 대부분의 Relying Party는 온라인 서비스로서 사용자별로 임의의 상태를 별도로 저장할 수 있으므로, 이 기능은 일부 특수한 경우에만 유용합니다. 예를 들어, Relying Party가 중앙 인증 서비스 대신 인증서 발급 식으로 운용하고 싶은 경우가 해당됩니다.

참고: Relying Party는 저장 공간이 제한된 디바이스에 쓸 때 불투명 데이터가 압축됨을 전제로 별도 압축 없이 데이터를 저장해도 됩니다.

인증서 시스템은 자격 증명의 공개키에 서명해야 하는데, 해당 공개키는 자격 증명 생성 이후에만 알 수 있으므로, 이 확장은 등록 컨텍스트에서 blob 기록 기능을 제공하지 않습니다. 다만, Relying Party가 이후 인증 확장을 쓸 계획이라면 자격 증명 생성 시 등록 확장을 함께 사용하는 것이 좋습니다.

인증서는 대부분의 인증기가 저장할 수 있는 용량에 비해 큰 데이터이므로, 사용자 에이전트는 리소스 할당이 적절하고 오용되지 않도록 사용자에게 알림/확인을 적절히 제공해야 합니다.

참고: 상호운용을 위해 [FIDO-CTAP]을 이용해 인증기에 대용량 blob을 쓰는 사용자 에이전트는 해당 사양에 명시된 자격 증명별 대용량 blob 저장 방식을 따라야 합니다.

참고: 이동형 인증기[FIDO-CTAP]을 교차 플랫폼 전송 프로토콜로 사용할 경우 Large Blob 확장은 발견 가능한 자격 증명에만 지원되며, authenticatorSelection.residentKey 값이 preferred 또는 required 가 아닌 경우 에러가 날 수 있습니다. 하지만 FIDO-CTAP을 사용하지 않는 인증기는 반드시 발견 가능한 자격 증명에만 이 확장을 제한하지는 않을 수 있습니다.

확장 식별자

largeBlob

적용 작업

등록인증

클라이언트 확장 입력
partial dictionary AuthenticationExtensionsClientInputs {
    AuthenticationExtensionsLargeBlobInputs largeBlob;
};

enum LargeBlobSupport {
  "required",
  "preferred",
};

dictionary AuthenticationExtensionsLargeBlobInputs {
    DOMString support;
    boolean read;
    BufferSource write;
};
support, of type DOMString

값은 LargeBlobSupport의 값 중 하나를 취하는 DOMString입니다. (§ 2.1.1 Enumeration as DOMString types 참고) 등록 시에만 유효합니다.

read, of type boolean

이 불리언 값이 있으면 Relying Party가 해당 자격 증명에 이미 저장된 blob을 가져오고 싶음을 나타냅니다. 인증(Assertion) 시에만 유효합니다.

write, of type BufferSource

해당 자격 증명에 연관해 Relying Party가 저장하고 싶은 불투명 바이트 문자열입니다. 인증(Assertion) 시에만 유효합니다.

클라이언트 확장 처리 (등록)
  1. read 또는 write 가 지정되면:

    1. 이름이 "NotSupportedError"인 DOMException 반환.

  2. support 값이 required 이면:

    1. supportedtrue로 설정.

      참고: 이는 대용량 blob 저장이 가능한 인증기가 추후 제공되는 것을 가정함. 12단계에서 확장 처리 도중 일어남. AuthenticationExtensionsLargeBlobOutputs 는 만족스런 인증기가 없을 경우 버려짐.

    2. 후보 인증기가 선택될 경우(22단계), options 평가 전에 continue (즉, 후보 인증기를 무시)하며, 해당 후보가 대용량 blob 저장을 지원하지 않으면 건너뜁니다.

  3. 그 외(support 없음, 또는 preferred일 경우):

    1. 선택 인증기가 있고 대용량 blob을 지원하면 supportedtrue로, 아니면 false로 둡니다.

클라이언트 확장 처리 (인증)
  1. support 값이 지정되어 있으면:

    1. 이름이 "NotSupportedError"인 DOMException 반환.

  2. readwrite 모두 지정되어 있으면:

    1. 이름이 "NotSupportedError"인 DOMException 반환.

  3. read 값이 true면:

    1. 클라이언트 확장 출력 largeBlob 을 초기화합니다.

    2. 어떤 인증기라도 성공(즉, [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors)에서)이면 해당 자격 증명에 저장된 largeBlob 데이터를 읽으려고 시도합니다.

    3. 성공 시 blob 에 결과값을 설정합니다.

      참고: 읽기에 실패하면, largeBlobAuthenticationExtensionsClientOutputs 에는 존재하지만, blob 멤버는 존재하지 않습니다.

  4. write 값이 있으면:

    1. allowCredentials 항목이 정확히 하나가 아니면:

      1. 이름이 "NotSupportedError"인 DOMException 반환.

    2. assertion 연산이 성공하면, 인증기write 의 내용을 해당 자격 증명에 연계하여 기록합니다.

    3. 성공 시 writtentrue를, 아니면 false를 설정합니다.

클라이언트 확장 출력
partial dictionary AuthenticationExtensionsClientOutputs {
    AuthenticationExtensionsLargeBlobOutputs largeBlob;
};

dictionary AuthenticationExtensionsLargeBlobOutputs {
    boolean supported;
    ArrayBuffer blob;
    boolean written;
};
supported, of type boolean

해당 자격 증명이 대용량 blob 저장을 지원 시에만 true. 등록 결과에만 포함됨.

blob, of type ArrayBuffer

해당 자격 증명(rawId)과 연관된 불투명 바이트 문자열입니다. readtrue일 때만 유효합니다.

written, of type boolean

write 값이 해당 인증기에 성공적으로 저장되면 true, 아니면 false.

인증기 확장 처리

이 확장은 대용량 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

[RFC3986]의 부록 A에 명시된 unreserved production에서 최대 48자까지 사용한 널이 아닌 문자열입니다. 가상 인증기를 고유하게 식별합니다.

protocol

가상 인증기가 사용하는 프로토콜. "ctap1/u2f", "ctap2", "ctap2_1" 중 하나입니다. [FIDO-CTAP]

transport

모사되는 AuthenticatorTransport 값. transportinternal이면 인증기는 플랫폼 연계를, 아니면 교차 플랫폼 연계를 시뮬레이션합니다.

hasResidentKey

true로 설정하면, 인증기는 클라이언트 측 발견 가능한 자격 증명을 지원합니다.

hasUserVerification

true로 설정하면, 인증기는 사용자 검증을 지원합니다.

isUserConsenting

모든 사용자 동의 승인 제스처(authorization gesture), 그리고 확장으로서 사용자 존재 확인의 결과를 좌우합니다. true면 항상 사용자 동의가 허가되며, false면 거부됩니다.

isUserVerified

가상 인증기사용자 검증 결과를 결정합니다. true면 항상 검증이 성공하고, false면 실패합니다.

참고: hasUserVerificationfalse면 이 속성의 효과는 없습니다.

extensions

가상 인증기가 지원하는 확장 식별자들의 문자열 배열입니다.

가상 인증기extensions 배열에 포함된 모든 인증기 확장을 필수로 지원해야 하며, 포함돼 있지 않은 확장은 지원하면 안 됩니다.

defaultBackupEligibility

새로 생성되는 모든 공개키 자격 증명 소스에 해당 백업 자격(backup eligibility)자격 증명 속성의 기본값을 지정합니다. 가상 인증기에서 authenticatorMakeCredential 수행 시 이 값이 BE authenticator data 플래그로 반영되어야 합니다.

defaultBackupState

새로 생성되는 모든 공개키 자격 증명 소스에 해당 백업 상태자격 증명 속성의 기본값을 지정합니다. 가상 인증기에서 authenticatorMakeCredential 수행 시, BS authenticator data 플래그로 반드시 반영되어야 합니다.

11.3. 가상 인증기 추가

가상 인증기 추가 WebDriver 확장 명령은 소프트웨어 가상 인증기를 생성합니다. 정의는 다음과 같습니다:

HTTP 메서드 URI 템플릿
POST /session/{session id}/webauthn/authenticator

인증기 설정JSON 객체로, 원격 엔드 스텝parameters로 전달됩니다. 여기에 아래 key, value 쌍이 포함됩니다:

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 객체(Object)가 아니면, WebDriver 오류WebDriver error code invalid argument와 함께 반환합니다.

    참고: parameters인증기 설정(Authenticator Configuration) 객체입니다.

  2. authenticator를 새 가상 인증기로 둡니다.

  3. parameters의 각 enumerable 고유 속성(own property)에 대해:

    1. key를 해당 속성 이름으로 둡니다.

    2. valueparameters에서 key 속성 가져오기 결과로 둡니다.

    3. 인증기 설정key가 없으면 WebDriver 오류WebDriver error code invalid argument와 함께 반환.

    4. value가 해당 key유효 값(valid values)에 없으면 WebDriver 오류WebDriver error code invalid argument와 함께 반환.

    5. authenticator에 keyvalue로 설정합니다.

  4. 인증기 설정에서 기본값이 정의된 각 속성에 대해:

    1. keyauthenticator에 정의된 속성이 아니라면, key를 default로 설정합니다.

  5. 인증기 설정의 각 속성에 대해:

    1. keyauthenticator에 정의된 속성이 아니라면, WebDriver 오류WebDriver error code invalid argument와 함께 반환.

  6. authenticator.extensions에 있는 각 extension에 대해:

    1. extension확장 식별자이면서, 엔드포인트 노드 WebAuthn WebDriver 구현에서 지원하지 않으면, WebDriver 오류WebDriver error code unsupported operation과 함께 반환.

  7. 고유한 authenticatorId를 생성합니다.

  8. authenticatorauthenticatorIdauthenticatorId 설정.

  9. authenticator가상 인증기 데이터베이스에 저장합니다.

  10. 성공(success)과 데이터 authenticatorId를 반환합니다.

11.4. 가상 인증기 제거

가상 인증기 제거 WebDriver 확장 명령은 이전에 생성된 가상 인증기를 제거합니다. 정의는 다음과 같습니다:

HTTP 메서드 URI 템플릿
DELETE /session/{session id}/webauthn/authenticator/{authenticatorId}

원격 엔드 스텝은 다음과 같습니다:

  1. authenticatorId가상 인증기 데이터베이스에 저장된 어떤 가상 인증기와도 일치하지 않으면, WebDriver 오류WebDriver error code invalid argument와 함께 반환합니다.

  2. authenticatorId로 식별되는 가상 인증기가상 인증기 데이터베이스에서 제거합니다.

  3. 성공을 반환합니다.

11.5. 자격 증명 추가

자격 증명 추가 WebDriver 확장 명령공개키 자격 증명 소스를 기존 가상 인증기에 주입합니다. 정의는 다음과 같습니다:

HTTP 메서드 URI 템플릿
POST /session/{session id}/webauthn/authenticator/{authenticatorId}/credential

자격 증명 파라미터JSON 객체이며 원격 엔드 스텝parameters로 전달됩니다. 다음 key, value 쌍을 포함합니다:

Key 설명 값 타입
credentialId Credential IDBase64url 인코딩한 값 string
isResidentCredential true클라이언트 측 발견 가능 자격 증명이 생성됨. false서버 측 자격 증명 생성됨. boolean
rpId 자격 증명이 스코프되는 Relying Party ID string
privateKey 개인키 1개만 담긴 비대칭 키 패키지. [RFC5958], Base64url 인코딩 사용. string
userHandle 자격 증명과 연관된 userHandleBase64url 인코딩. 없을 수 있음. string
signCount 서명 카운터의 초기값 number
largeBlob 자격 증명별 대용량 blob공개키 자격 증명 소스에 연관, Base64url 인코딩. 없을 수 있음. string
backupEligibility 공개키 자격 증명 소스백업 자격 시뮬레이션 값. 지정되지 않으면 가상 인증기의 defaultBackupEligibility 사용. authenticator dataBE 플래그로 반영되어야 함 boolean
backupState 공개키 자격 증명 소스백업 상태 시뮬레이션 값. 지정되지 않으면 가상 인증기의 defaultBackupState 사용. authenticator dataBS 플래그로 반영되어야 함 boolean
userName 해당 자격 증명에 연관된 username. 지정되지 않으면 빈 문자열이 기본. string
userDisplayName 해당 자격 증명에 연관된 userdisplayName. 지정되지 않으면 빈 문자열이 기본. string

원격 엔드 스텝은 다음과 같습니다:

  1. parameters가 JSON 객체가 아니면, WebDriver 오류WebDriver error code invalid argument와 함께 반환.

    참고: parameters자격 증명 파라미터 객체입니다.

  2. credentialIdparameterscredentialId 속성 값에 대해 Base64url 디코딩 결과로 둡니다.

  3. credentialId가 실패면 WebDriver 오류WebDriver error code invalid argument와 함께 반환.

  4. isResidentCredentialparametersisResidentCredential 속성 값으로 둡니다.

  5. isResidentCredential이 정의되지 않으면 WebDriver 오류WebDriver error code invalid argument와 함께 반환.

  6. rpIdparametersrpId 속성 값으로 둡니다.

  7. rpId가 유효한 RP ID가 아니면, WebDriver 오류WebDriver error code invalid argument와 함께 반환.

  8. privateKeyparametersprivateKey 속성 값에 대해 Base64url 디코딩 결과로 둡니다.

  9. privateKey가 실패면 WebDriver 오류WebDriver error code invalid argument와 함께 반환.

  10. privateKey[RFC5958]의 P-256 곡선상 ECDSA 단일 개인키가 포함된 정상 인코딩 키 패키지가 아니면, WebDriver 오류WebDriver error code invalid argument와 함께 반환.

  11. parametersuserHandle 속성이 정의된 경우:

    1. userHandleparametersuserHandle 속성 값에 대해 Base64url 디코딩 결과로 둡니다.

    2. userHandle이 실패면 WebDriver 오류WebDriver error code invalid argument와 함께 반환.

  12. 그 외의 경우:

    1. isResidentCredentialtrueWebDriver 오류WebDriver error code invalid argument와 함께 반환.

    2. userHandlenull로 둡니다.

  13. authenticatorId가상 인증기 데이터베이스에 저장된 어떤 가상 인증기와도 일치하지 않으면, WebDriver 오류WebDriver error code invalid argument와 함께 반환.

  14. authenticatorauthenticatorId에 해당하는 가상 인증기로 둡니다.

  15. isResidentCredentialtrue이고 해당 authenticatorhasResidentKey 값이 falseWebDriver 오류WebDriver error code invalid argument와 함께 반환.

  16. 해당 authenticatorlargeBlob 확장을 지원하고 parameterslargeBlob 속성이 정의되어 있으면:

    1. largeBlobparameterslargeBlob 속성 값에 대해 Base64url 디코딩 결과로 둡니다.

    2. largeBlob이 실패면 WebDriver 오류WebDriver error code 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

    userNameuserDisplayName로 구성합니다.

  27. credential백업 자격 자격 증명 속성backupEligibility로 설정.

  28. credential백업 상태 자격 증명 속성backupState로 설정.

  29. credential과 연계된 서명 카운터 counterparameterssignCount 또는 정의되지 않았다면 0으로 설정.

  30. largeBlobnull이 아니면, credential자격 증명별 대용량 blob으로 설정.

  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 error code invalid argument와 함께 반환합니다.

    참고: parameters자격 증명 속성 설정 파라미터 객체입니다.

  2. authenticatorId가상 인증기 데이터베이스에 저장된 어떤 가상 인증기와도 일치하지 않으면, WebDriver 오류WebDriver error code invalid argument와 함께 반환합니다.

  3. credentialauthenticatorcredentialId로 관리하는 공개키 자격 증명 소스로 둡니다.

  4. credential이 비어 있으면 WebDriver 오류WebDriver error code invalid argument와 함께 반환합니다.

  5. backupEligibilityparametersbackupEligibility 속성 값으로 둡니다.

  6. backupEligibility가 정의되어 있으면, credential백업 자격 자격 증명 속성을 해당 값으로 설정합니다.

    참고: 일반적으로 backupEligibility 속성은 공개키 자격 증명 소스에 대해 영구적입니다. 이 명령은 테스트 및 디버깅 목적으로 속성을 변경할 수 있도록 합니다.

  7. backupStateparametersbackupState 속성 값으로 둡니다.

  8. backupState가 정의되어 있으면 credential백업 상태 자격 증명 속성을 해당 값으로 설정합니다.

  9. 성공을 반환합니다.

12. IANA 고려 사항

12.1. WebAuthn 어테스테이션 명세 식별자 등록 업데이트

이 절에서는 § 8 정의된 어테스테이션 명세에서 정의된 아래 어테스테이션 명세 식별자들을 IANA "WebAuthn Attestation Statement Format Identifiers" 레지스트리 [IANA-WebAuthn-Registries]에 대해 업데이트하며, [RFC8809]에 의해 제정되었고, 최초 [WebAuthn-1]에서 등록된 식별자가 본 명세를 참조하도록 변경합니다.

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 정의된 확장에서 새롭게 정의된 확장 식별자 값을 IANA "WebAuthn Extension Identifiers" 레지스트리 [IANA-WebAuthn-Registries]에 신규로 등록함을 명시합니다. 본 레지스트리는 [RFC8809]에 의해 제정되었습니다.

13. 보안 고려사항

이 명세서는 Web API와 암호학적 피어-엔터티 인증 프로토콜을 정의합니다. Web Authentication API는 웹 개발자(즉, "author")가 자신의 등록인증 절차에서 Web Authentication 프로토콜을 활용할 수 있게 합니다. Web Authentication 프로토콜 엔드포인트를 구성하는 엔터티는 사용자 제어 하의 WebAuthn Authenticator들과 WebAuthn Relying Party의 실행 환경에서 호스팅되는 Relying Party웹 애플리케이션입니다. 이 모델에서 사용자 에이전트는 WebAuthn Client와 함께 authenticatorRelying Parties 사이의 중개자 역할을 합니다. 또한, authenticator는 자신의 출처에 관해 attest할 수 있습니다.

현재 이 명세서는 상세한 보안 고려사항을 모두 포함하지는 않습니다. 다만 [FIDOSecRef] 문서는 본 명세에 전반적으로 적용 가능한 보안 분석을 제공합니다. 또한 [FIDOAuthnrSecReqs] 문서 모음은 authenticator의 보안 특성에 관해 유용한 정보를 제공합니다.

이하 소항들은 현재의 Web Authentication-특유 보안 고려사항을 구성합니다. 대상별로 구분되어 있으며; 일반적인 보안 고려사항은 이 섹션의 직접 하위절이고, authenticator, clientRelying Party 구현자들을 위한 고려사항은 각각의 하위절로 그룹화되어 있습니다.

13.1. 서명되지 않은 Credential ID

credential IDauthentication assertion과 함께 서명되지 않은 상태로 전송됩니다. 이는 문제가 되지 않습니다. 만약 authenticator가 잘못된 credential ID를 반환하거나, 공격자가 credential ID를 가로채 조작하더라도, 결과적으로 WebAuthn Relying Party는 반환된 서명된 authenticator data를 검증하기 위한 올바른 credential public key를 조회하지 못하게 되고, 결과 상호작용은 오류로 끝나게 됩니다.

13.2. 클라이언트와 인증기 간 물리적 근접성

WebAuthn의 authenticator 모델에서는 일반적으로 roaming authenticators가 클라이언트와 물리적으로 가깝고 직접 통신한다고 가정합니다. 이러한 배치는 중요한 장점을 제공합니다.

클라이언트와 authenticator 간의 물리적 근접성은 something you have 인증 요소의 핵심 강점입니다. 예를 들어, roaming authenticator가 USB 또는 Bluetooth로만 통신할 수 있다면, 이러한 전송 수단의 제한된 범위는 악의적 행위자가 authenticator와 상호작용하려면 물리적으로 그 범위 내에 있어야 함을 보장합니다. 반면, 원격에서 호출될 수 있는 authenticator의 경우에는 반드시 그렇지 않습니다 — 설령 authenticator사용자 존재 확인을 수행하더라도, 사용자가 원격으로 시작된 악성 요청을 승인하도록 속을 수 있습니다.

클라이언트와 authenticator의 직접 통신은 clientscope 제약을 강제로 적용할 수 있게 합니다. 반면, 클라이언트와 인증기 간 통신이 제3자에 의해 중개된다면, client는 제3자가 범위 제약을 집행하고 authenticator 접근을 제어하도록 신뢰해야 합니다. 이를 실패할 경우 악의적 Relying Party가 다른 Relying Parties용으로 유효한 authentication assertions를 받거나, 악의적 사용자가 다른 사용자의 authentication assertions에 접근할 수 있게 될 수 있습니다.

만약 authenticator가 클라이언트와 물리적으로 가깝지 않아도 되도록 설계하거나, 또는 clientauthenticator가 직접 통신하지 않는 솔루션을 설계한다면, 설계자는 이것이 scope 제약의 집행과 authenticatorsomething you have 인증 요소로서의 강도에 어떤 영향을 미치는지 고려해야 합니다.

13.3. 인증기(authenticators)에 대한 보안 고려사항

13.3.1. 어테스테이션 인증서 계층

어테스테이션 인증서를 위한 3계층 구조(예: Attestation Root, Attestation Issuing CA, Attestation Certificate)를 권고합니다. 또한 각 WebAuthn Authenticator 디바이스 라인(모델)마다 별도의 발급 CA를 사용하는 것이 권장됩니다. 이는 특정 인증기 모델 버전의 문제를 격리하는 데 도움이 됩니다.

어테스테이션 루트 인증서가 단일 WebAuthn Authenticator 디바이스 라인(AAGUID)에만 전용되지 않은 경우, attestation 인증서 자체에 AAGUID를 명시하여 authenticator data와 대조 검증할 수 있어야 합니다.

13.3.2. 어테스테이션 인증서 및 CA 유출

어테스테이션 인증서를 발급하는 중간 CA 또는 루트 CA가 유출된 경우, WebAuthn Authenticatorattestation key pairs 자체는 안전하지만 해당 인증서들은 더 이상 신뢰할 수 없습니다. 만약 제조업체가 자사 authenticator 모델들의 attestation public keys를 기록해 두었다면, 새로운 중간 CA 또는 루트 CA로부터 이 키들을 위한 새로운 attestation certificates를 발급할 수 있습니다. 루트 CA가 변경된다면 WebAuthn Relying Parties는 신뢰하는 루트 인증서를 적절히 업데이트해야 합니다.

발급 CA가 해당 private key가 유출되었다고 판단하면, 해당 WebAuthn Authenticatorattestation certificate는 발급 CA에 의해 폐기되어야 합니다. 제조업체는 펌웨어 업데이트를 배포하고 이미 제조된 WebAuthn Authenticators에 새로운 attestation private keyscertificates를 주입해야 할 수 있습니다(이 과정은 본 명세의 범위를 벗어납니다). 제조업체가 이를 수행할 수 없다면, 영향을 받은 WebAuthn Authenticators로부터의 향후 attestation statements를 신뢰할 수 없게 될 수 있습니다.

관련 내용은 Relying Parties에 대한 관련 보안 고려사항인 § 13.4.5 폐기된 어테스테이션 인증서를 참조하세요.

13.4. Relying Parties를 위한 보안 고려사항

13.4.1. WebAuthn Relying Parties에 대한 보안 이점

이 명세서가 WebAuthn Relying Parties에게 제공하는 주요 이점은 다음과 같습니다:

  1. 사용자와 계정을 광범위하게 호환되며 사용하기 쉬운 다중요소 인증으로 보호할 수 있습니다.

  2. Relying Party는 사용자에게 인증기 하드웨어를 제공할 필요가 없습니다. 대신 각 사용자는 적합한 authenticator를 독립적으로 구비하고 동일한 authenticator를 여러 Relying Parties에서 사용할 수 있습니다. Relying Party는 선택적으로 authenticators의 보안 속성에 대한 요구사항을 attestation statements를 검사함으로써 강제할 수 있습니다.

  3. Authentication ceremonies중간자 공격(man-in-the-middle attacks)에 저항력이 있습니다. 등록 절차에 대해서는 아래 § 13.4.4 어테스테이션 한계를 참조하세요.

  4. Relying Party는 PIN, 생체인식 등 다양한 형태의 사용자 검증을 거의 코드 변경 없이 자동으로 지원할 수 있으며, 각 사용자는 선호하는 인증 방식을 자신이 선택한 authenticator로 결정할 수 있습니다.

  5. Relying Party는 위의 이점을 얻기 위해 추가 비밀을 저장할 필요가 없습니다.

Conformance 섹션에 명시된 바와 같이, 위의 모든 보안 이점을 얻기 위해 Relying Party§ 7 WebAuthn Relying Party Operations에 기술된 대로 동작해야 합니다. 다만 한 가지 예외적 사용 사례가 아래 § 13.4.4 어테스테이션 한계에 설명되어 있습니다.

13.4.2. 임베디드 사용 시 가시성 고려사항

간단히 WebAuthn을 임베디드 컨텍스트에서 사용하는 것(예: iframe 내 사용, § 5.10 iframe 요소 내 Web Authentication 사용 참조)은 사용자를 UI Redressing 공격(일명 "Clickjacking")에 취약하게 만들 수 있습니다. 공격자가 자신의 UI를 Relying Party의 의도된 UI 위에 포개고 사용자가 의도하지 않은 동작을 하도록 속이려 할 수 있습니다. 예를 들어, 공격자가 사용자를 속여 물건을 구매하거나 돈을 이체하게 할 수 있습니다.

비록 WebAuthn-특유 UI는 일반적으로 client platform이 처리하므로 UI Redressing에 취약하지 않지만, 임베디드된 WebAuthn 콘텐츠를 가진 Relying Party는 자신의 콘텐츠 UI가 사용자에게 보이는지를 보장하는 것이 중요합니다. 이를 위해 실험적 수단으로 Intersection Observer v2isVisible 속성 상태를 관찰하는 방법이 있습니다. 예를 들어, 임베디드 컨텍스트에서 실행되는 Relying Party 스크립트가 isVisiblefalse로 설정되는 것을 감지하면 미리 팝업 창으로 로드하여 콘텐츠가 가려지는 상황을 우회할 수 있습니다.

13.4.3. 암호학적 챌린지

암호학적 프로토콜로서 Web Authentication은 재생 공격(replay attacks)을 피하기 위해 랜덤화된 챌린지에 의존합니다. 따라서 PublicKeyCredentialCreationOptions.challengePublicKeyCredentialRequestOptions.challenge의 값은 반드시 신뢰할 수 있는 환경(예: 서버 측)에서 Relying Parties에 의해 무작위로 생성되어야 하며, 클라이언트의 응답에 포함된 challenge 값은 생성된 값과 일치해야 합니다. 이는 클라이언트의 동작에 의존하지 않는 방식으로 수행되어야 합니다. 예를 들어 Relying Party는 연산이 완료될 때까지 챌린지를 일시적으로 저장해야 합니다. 불일치를 허용하면 프로토콜의 보안이 손상됩니다.

챌린지는 권장 범위 및 기본 WebAuthn 절차 타임아웃의 상한과 유사한 기간 동안 유효해야 합니다.

재생 공격을 방지하기 위해 챌린지는 충분한 엔트로피를 포함해야 합니다. 따라서 챌린지는 최소 16바이트 이상이어야 합니다.

13.4.4. 어테스테이션의 한계

이 절은 규범적이지 않습니다.

새 자격 증명을 등록할 때(registering a new credential), attestation statement가 존재한다면, WebAuthn Relying Party가 다양한 authenticator의 특성에 대해 어느 정도 보증을 도출할 수 있게 해줄 수 있습니다. 예를 들어 authenticator 모델이나 자격 증명 개인키를 어떻게 저장·보호하는지 등에 관하여입니다. 그러나 단지 attestation statement만으로는 Relying Party가 사용자가 의도한 attestation object가 실제로 그 authenticator에서 생성된 것인지, 중간자 공격자에 의해 생성된 것이 아닌지를 확인할 수 있는 수단을 제공하지 않습니다. 예를 들어 공격자는 Relying Party 스크립트에 주입된 악성 코드를 사용할 수 있습니다. 따라서 Relying Party는 TLS 등 관련 기술과 같은 다른 수단에 의존하여 attestation object를 중간자 공격으로부터 보호해야 합니다.

등록 절차가 안전하게 완료되고 authenticatorcredential private key의 기밀성을 유지한다고 가정하면, 그 공개키로 수행되는 이후의 authentication ceremonies는 중간자 공격으로부터 변조에 저항합니다.

위 논의는 모든 attestation types에 적용됩니다. 어떤 경우에도 중간자 공격자는 PublicKeyCredential 객체(여기에는 attestation statement와 등록될 credential public key가 포함됨)를 대체하고 이후의 authentication assertions을 동일한 Relying Party에 대해 변조할 수 있습니다.

이러한 공격은 탐지 가능할 수 있습니다; 만약 Relying Party가 공격자의 credential public key를 등록했다면, 공격자는 이후의 모든 authentication ceremonies를 그 공격자의 키로 변조해야 하므로 정상이었던 절차들이 실패하면서 공격이 드러날 가능성이 있습니다.

Self AttestationNone 이외의 어테스테이션 타입은 이러한 공격의 난이도를 높여 줄 수 있습니다. 왜냐하면 Relying Parties가 사용자에게 인증기 정보(예: 모델 식별)를 표시할 수 있기 때문입니다. 공격자는 사용자의 인증기와 동일 모델의 진짜 authenticator를 사용해야 하거나, 사용자가 Relying Party가 보고하는 인증기 모델이 기대와 다름을 알아차릴 수 있습니다.

참고: 위에서 설명한 모든 변형의 중간자 공격들은 기존의 비밀번호 인증에 대한 중간자 공격보다 공격자가 수행하기 더 어렵습니다.

13.4.5. 폐기된 어테스테이션 인증서

인증서 증명서 검증이 중간 인증 CA 인증서가 폐기되어 실패하고, 신뢰 당사자의 정책이 이러한 상황에서 등록/인증 요청을 거부해야 한다고 요구할 경우, 신뢰 당사자가 동일한 중간 CA로 체인된 인증서 증명서를 사용하여 CA 유출일 이후 등록된 공개 키 자격 증명을 등록 해제(또는 "자체 증명"과 동등한 신뢰 수준으로 표시)하는 것도 권장됩니다. 따라서 신뢰 당사자등록 시 중간 인증 CA 인증서를 기억하여, 해당 인증서가 폐기된 후 수행된 등록에 대해 관련된 공개 키 자격 증명을 등록 해제할 수 있도록 하는 것이 권장됩니다.

또한 인증자에 대한 관련 보안 고려 사항은 § 13.3.2 인증서 증명서 및 인증 CA 유출를 참고하세요.

13.4.6. 자격 증명 손실 및 키 이동성

이 명세서는 credential private keys의 백업이나 authenticators 간 공유를 위한 프로토콜을 정의하지 않습니다. 일반적으로 credential private key는 그것을 생성한 authenticator를 떠나지 않는 것으로 기대됩니다. 따라서 인증기를 분실하면 일반적으로 그 인증기에 바인딩된 모든 credentials를 잃게 되며, 사용자가 Relying Party에 등록된 자격 증명을 하나만 가지고 있다면 계정에 접근할 수 없게 될 수 있습니다. 개인키를 백업하거나 공유하는 대신 Web Authentication API는 동일한 사용자에 대해 복수의 credentials를 등록하도록 허용합니다. 예를 들어 사용자는 자주 사용하는 platform credentials을 자주 사용하는 client devices에 등록하고, 새로운 또는 드물게 사용하는 client devices용으로 하나 이상의 roaming credentials를 백업으로 등록할 수 있습니다.

Relying Parties는 사용자에게 동일한 credentials를 동일한 사용자 계정에 복수 등록하도록 허용하고 권장해야 합니다. Relying PartiesexcludeCredentialsuser.id 옵션을 사용하여 서로 다른 credentials가 서로 다른 authenticators에 바인딩되도록 해야 합니다.

13.4.7. 보호되지 않은 계정 감지

이 절은 규범적이지 않습니다.

이 보안 고려사항은 인증 절차의 첫 단계로 authentication ceremonies를 지원하면서 비-emptyallowCredentials 인자를 사용하는 Relying Parties에 적용됩니다. 예를 들어 서버-사이드 자격 증명을 첫 단계로 사용하는 인증의 경우가 해당합니다.

이 경우 allowCredentials 인자는 어떤 사용자 계정이 WebAuthn 자격 증명을 등록했는지 여부에 대한 정보를 유출할 위험이 있으며, 이는 계정 보호 강도의 신호가 될 수 있습니다. 예를 들어 공격자가 사용자 이름만 제공하여 인증 절차를 시작할 수 있고, Relying Party가 일부 사용자 계정에 대해 비어 있지 않은 allowCredentials를 응답하고 다른 계정에는 실패 또는 비밀번호 챌린지를 응답한다면, 공격자는 후자의 계정들이 WebAuthn 어설션을 요구하지 않을 가능성이 높다고 결론짓고, 그보다 약할 것으로 보이는 계정들을 집중 공격할 수 있습니다.

이 문제는 § 14.6.2 사용자 이름 열거§ 14.6.3 credential ID를 통한 개인정보 유출에서 설명된 문제와 유사하며, 유사한 방식으로 완화할 수 있습니다.

13.4.8. 코드 인젝션 공격

어떤 악성 코드가 origin 내에서 실행되어 scope 내의 Relying Partypublic key credentials에 접근할 수 있게 되면 WebAuthn이 제공하는 모든 보안 보장이 무력화될 수 있습니다. WebAuthn Clients는 WebAuthn API를 secure contexts에서만 노출하므로 기본적인 공격은 완화되지만, Relying Parties는 추가적인 주의를 기울여야 합니다.

코드 인젝션은 여러 경로로 발생할 수 있으며; 이 절은 몇 가지 가능한 시나리오와 완화책을 제시하지만 포괄적인 목록은 아닙니다.

13.4.9. 자격 증명의 origin 검증

자격 증명 등록(registering a credential) 및 어설션 검증(verifying an assertion) 시에, Relying Party는 클라이언트 데이터의 origin 멤버를 반드시 검증해야 합니다.

Relying Party는 예상치 못한 origin 값을 수락해서는 안 됩니다. 그렇게 하면 악의적 웹사이트가 유효한 credentials를 획득할 수 있습니다. WebAuthn 자격 증명의 scope는 그들이 등록된 RP ID 외의 도메인에서 사용되는 것을 방지하지만, Relying Party의 origin 검증은 결함 있는 authenticator가 자격 증명 scope을 집행하지 못할 경우의 추가 보호층으로 작용합니다. 악성 서브도메인에 대한 논의는 § 13.4.8 코드 인젝션 공격을 참조하세요.

검증은 정확한 문자열 일치 또는 Relying Party의 필요에 따라 다른 방법으로 수행될 수 있습니다. 예를 들어:

클라이언트 데이터의 topOrigin 멤버를 검증할 때도 유사한 고려사항이 적용됩니다. topOrigin이 존재할 경우, Relying Party는 그 값이 예상되는지 검증해야 합니다. 이 검증은 정확한 문자열 일치 또는 Relying Party가 필요로 하는 다른 방법으로 수행될 수 있습니다. 예를 들어:

14. 프라이버시 고려사항

[FIDO-Privacy-Principles]의 프라이버시 원칙은 이 명세에도 적용됩니다.

이 절은 대상별로 나누어져 있습니다.
일반 프라이버시 고려사항은 이 절의 직접 하위 절로, authenticator, client, Relying Party 구현자를 위한 프라이버시 고려사항은 각각 별도의 하위 절로 정리되어 있습니다.

14.1. 탈익명화 방지 대책

이 절은 규범적이지 않습니다.

Web Authentication API의 많은 설계 요소들은 프라이버시 우려에서 비롯되었습니다. 본 명세에서 주로 다루는 우려는 사용자의 개인 신원 보호, 즉 인간 개체의 식별 또는 별도의 신원들을 동일인으로 연결하는 것을 방지하는 것입니다. Web Authentication API는 전역 신원을 사용하거나 제공하지 않지만, 다음과 같은 연관 가능한 식별자들이 사용됩니다:

위 정보 중 일부는 Relying Party와 필연적으로 공유되어야 합니다. 이후 절에서는 악의적인 Relying Party가 이러한 정보를 사용하여 사용자의 개인 신원을 파악하지 못하도록 하는 대책을 설명합니다.

14.2. 익명성, 범위 한정, 상호연결 불가 공개키 자격증명

이 절은 규범적이지 않습니다.

Credential IDcredential public key는 강력한 인증을 위해 WebAuthn Relying Party와 공유되어야 하지만, 이들은 식별성을 최소화하도록 설계되어 있으며 Relying Parties 간에 공유되지 않습니다.

또한 클라이언트 측 검색가능 공개키 자격증명 소스에는 Relying Party가 지정한 user handle을 선택적으로 포함할 수 있습니다. 이 자격증명은 사용자를 식별 및 인증하는 데 둘 다 사용할 수 있습니다. 즉, 프라이버시를 신경 쓰는 Relying Party는 기존 사용자명 없이 user account를 생성할 수 있어 Relying Parties 간 연관 가능성이 더 낮아집니다.

14.3. authenticator-로컬 생체 인식

생체 인증기생체 인식authenticator 내부에서 수행합니다. 단, platform authenticators의 경우 구현에 따라 생체 데이터가 client에도 노출될 수 있습니다. 생체 데이터는 WebAuthn Relying Party에는 공개되지 않으며, 오직 로컬에서 user verification을 수행하고, 공개키 자격증명 등록 또는 인증에만 사용됩니다. 따라서 악의적인 Relying Party는 생체 데이터로 사용자의 신원을 파악할 수 없으며, Relying Party에서 보안사고가 나더라도 생체 데이터가 다른 Relying Party에서 로그인을 위조하는 데 악용될 위험이 없습니다.

만약 Relying Party생체 인식을 요구하면, 생체 인증기가 로컬에서 user verification을 수행하고, 그 결과를 UV 플래그를 서명된 assertion 응답에 설정하여 신호만 보냅니다. 생체 데이터를 Relying Party에 직접 공개하지 않습니다.

14.4. authenticator를 위한 프라이버시 고려사항

14.4.1. 인증서(Attestation) 프라이버시

Attestation certificateattestation key pair는 사용자를 추적하거나 동일 사용자의 여러 온라인 신원을 연결하는 데 사용될 수 있습니다.
이를 완화하는 방법은 여러 가지가 있으며, 예시로:

14.4.2. authenticator에 저장된 개인정보(PII)의 프라이버시

authenticator는 본 명세에 정의되지 않은 추가 정보를 client에 제공할 수 있습니다. 예를 들면 사용자가 인증 절차에 사용할 credential을 선택할 수 있게 하는 풍부한 UI 기능이 그 예입니다. 만약 authenticator가 그렇게 한다면, 성공적인 user verification이 이루어지지 않은 한 개인정보를 노출해서는 안 됩니다. user verification이 동시에 두 명 이상 등록유저에 대해 지원된다면, authenticator는 현재 verified된 사용자 이외엔 개인정보를 노출해서는 안 됩니다. user verification 기능이 없는 authenticator는 어떠한 개인정보도 저장하면 안 됩니다.

이와 관련해, user handleid 멤버로 전달되는 PublicKeyCredentialUserEntity의 값은 개인정보로 간주하지 않습니다. 자세한 내용은 § 14.6.1 User Handle 내용을 참고하세요.

이 권고들은 물리적으로 authenticator에 접근할 수 있는 공격자가 등록된 사용자들의 개인정보를 추출하지 못하도록 하기 위함입니다.

14.5. client를 위한 프라이버시 고려사항

14.5.1. 등록 절차 프라이버시

사용자 동의(consent) 없이 사용자가 식별되는 것을 막기 위해, [[Create]](origin, options, sameOriginWithAncestors) 메서드의 구현 시 악의적인 WebAuthn Relying Party가 다음 상황(여기서 "excluded"는 Relying PartyexcludeCredentials에 나열한 credential 중 적어도 하나가 해당 authenticatorbound되어 있다는 뜻)에 따라 구분할 수 있는 정보가 유출되지 않도록 주의해야 합니다:

위 경우를 구분할 수 있다면, 악의적인 Relying Party가 어떤 credential이 사용가능한지 탐색하여 사용자를 식별할 수 있는 정보가 유출됩니다. 예를 들어, 제외된 authenticator가 감지되는 즉시 실패 응답을 반환한다면 특히 이 authenticatorplatform authenticator일 때 Relying Party는 사용자가 수동 취소하기 전 절차가 취소됨을 파악할 수 있어, excludeCredentials 목록 중 최소 1개 credential이 사용 가능하다고 결론지을 수 있습니다.

그러나, 사용자가 식별 가능한 오류가 반환되기 전에 새 credential 생성을 명시적으로 동의했다면 이는 문제가 되지 않습니다. 즉, 사용자가 정보 유출에 동의했으므로 추가 우려가 없습니다.

14.5.2. 인증 절차 프라이버시

사용자 동의 없이 식별을 방지하려면, [[DiscoverFromExternalSource]](origin, options, sameOriginWithAncestors) 메서드를 구현할 때 악의적인 WebAuthn Relying Party가 다음 상황(여기서 "named"란 Relying PartyallowCredentials에 나열한 credential이 존재함을 뜻함)을 구분할 수 있는 정보가 노출되지 않도록 주의해야 합니다:

위 두 경우가 구분 가능하다면, 악의적인 Relying Party가 사용가능한 credential을 탐색해 사용자 식별정보를 알 수 있습니다. 예컨대 클라이언트가 authenticator에서 명명된 credential을 찾은 뒤에만 인증 절차 진행/취소 버튼 등을 표시한다면 이 정보로 인해 Relying Party가 절차가 사용자에 의해 취소(타임아웃 아님)되었음을 탐지하고, 따라서 allowCredentials 에 나온 credential 중 1개 이상이 존재함을 추정할 수 있습니다.

이 문제는 명명된 credential 보유 여부와 관계없이 언제든 인증 절차를 취소할 수 있는 버튼 등을 항상 표시하면 완화될 수 있습니다.

14.5.3. 운영체제 계정 간 프라이버시

여러 명이 사용하는 운영체제를 가진 client deviceplatform authenticator가 포함되어 있다면, platform authenticatorclient device는 platform credential의 존재 여부가 해당 자격증명을 만든 운영체제 사용자에게만 노출되도록 해야 합니다.

14.5.4. 클라이언트 기능 공개

getClientCapabilities 메서드는 WebAuthn Relying Party가 클라이언트 및/또는 사용자의 성공 확률을 높인 등록·인증 경험을 설계할 수 있도록 도와줍니다.

WebAuthn 기능 지원 여부는 지문 채취(핑거프린팅)의 위험이 있으므로, 클라이언트 구현은 정책 및/또는 사용자 동의에 따라 기능 공개를 제한할 수 있습니다.

14.6. Relying Party를 위한 프라이버시 고려사항

14.6.1. user handle 내용

user handle§ 14.4.2 authenticator에 저장된 개인정보(PII)의 프라이버시에서 개인정보로 간주되지 않으며, 또한 authenticatoruser handle을 user verification 없이 공개할 수 있으므로, Relying Party는 user handle에 개인정보(이메일 주소, 사용자명 등)를 담아서는 안 됩니다. 해시값 역시, 해시 함수가 salt 값이 Relying Party에만 비공개로 존재할 때만 허용됩니다. 단순 해시는 예측 가능한 값에 대해 방어하지 못합니다.
권장 방법은 user handle을 64바이트 난수로 하고, 이를 user account에 저장하는 것입니다.

14.6.2. 사용자명(Username) 탐색

registration 또는 authentication ceremony 개시 시, WebAuthn Relying Party가 등록 유저에 관한 민감정보를 유출할 위험이 있습니다. 예를 들어, 어떤 Relying Party가 사용자명으로 이메일 주소를 쓰고, 공격자가 "alex.mueller@example.com"으로 인증 절차를 시도했을 때 실패 응답을, "j.doe@example.com"으로 시도하면 성공 응답을 받았다면 공격자는 "j.doe@example.com"이 등록되어 있고 "alex.mueller@example.com"은 등록되어 있지 않음을 알 수 있습니다. 이렇게 하여 Relying Party는 "j.doe@example.com"이 자기 서비스에 계정이 있다는 민감 정보를 유출하는 셈이 됩니다.

아래는 이와 같은 공격에서 민감정보 유출을 예방/완화할 수 있는 Relying Party의 비규범적 조치 예시입니다:

14.6.3. Credential ID 프라이버시 유출

이 절은 규범적이지 않습니다.

이 프라이버시 고려사항은 비어있지 않은 allowCredentials 인자와 함께 authentication ceremony 1단계를 구현하는 Relying Party에 적용됩니다. 예를 들어 서버측 credential을 첫 1차 인증 단계로 쓰는 경우입니다.

이 경우 allowCredentials 인자를 통해 인증받지 않은 호출자에게 사용자의 credential ID가 노출될 수 있어 개인정보 유출 위험이 있습니다. Credential ID는 여러 Relying Party를 연관짓지 않도록 설계됐으나, credential ID의 길이로 어떤 authenticator가 만들었는지 유추가 가능할 수 있습니다. 한 사용자가 여러 Relying Party에서 동일한 사용자명과 인증기 조합을 사용할 수 있으므로, allowCredentials 내 credential ID 개수와 길이가 전역 식별자가 되어 사용자를 탈익명화할 수도 있습니다.
또한 credential ID를 알면 공격자가 잠시 사용자 인증기에 물리적 접근만 해도 신원 추정 시험이 가능합니다.

이런 정보 유출을 막기 위해 Relying Party는 예를 들어 다음처럼 할 수 있습니다:

위 예방조치들이 곤란한 상황, 즉 사용자명만 주어졌을 때 allowCredentials 노출이 필요한 경우 Relying Party§ 14.6.2 사용자명 탐색과 같이 가상의 credential ID를 반환함으로써 프라이버시 유출을 완화할 수 있습니다.

인증받지 않은 호출자에게 credential id를 노출하지 않기 위해, 해당 credential id가 인식되지 않았음을 신호할 때 WebAuthn Relying PartysignalUnknownCredential(options) 메서드를 쓰고 signalAllAcceptedCredentials(options) 메서드는 사용하지 않아야 합니다.

15. 접근성 고려 사항

사용자 검증이 가능한 인증자로밍이든 플랫폼이든 사용자에게 하나 이상의 사용자 검증 방식을 제공해야 합니다. 예로 지문 인식과 PIN 입력 모두를 제공하는 것입니다. 이렇게 하면 선택한 검증 방식이 어떤 이유로 동작하지 않을 때 다른 사용자 검증 방법으로 대체할 수 있습니다. 또한 로밍 인증자의 경우, 인증자와 플랫폼이 함께 동작하여 PIN 입력과 같은 사용자 검증 방식을 제공할 수 있습니다 [FIDO-CTAP].

Relying Party등록 시점에, 사용자가 향후 승인 제스처를 올바르게 수행할 수 있도록 지원 기능을 제공해야 합니다. 예시로 인증자에 이름을 붙이기, 기기와 연결할 사진을 선택하기 또는 자유형 텍스트 지시(예: 스스로 위한 메모 등)를 입력받는 것을 들 수 있습니다.

타이밍에 의존하는 인증 절차 예를 들어 등록 과정(참고: timeout) 또는 인증 과정(참고: timeout) 등은 [WCAG21]2.2 충분한 시간 가이드라인을 따라야 합니다. 만약 클라이언트 플랫폼Relying Party가 제공한 타임아웃이 [WCAG21] 가이드라인에 적합하지 않다고 판단하면, 클라이언트 플랫폼은 해당 타임아웃을 조정할 수 있습니다.

WebAuthn 인증 절차 타임아웃 권장 범위 및 기본값은 다음과 같습니다:

16. 테스트 벡터

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

이 섹션은 구현 검증에 사용될 수 있는 예시 값(example values)을 나열합니다.

예시는 동일 등록인증 과정 쌍으로 의사코드(pseudocode)로 제시되며, 바이트 문자열 리터럴 및 주석은 CDDL [RFC8610] 표기법을 따릅니다. 예제는 전체 구현을 망라하지 않고 WebAuthn 확장을 포함하지 않습니다.

예제들은 입력에서 출력까지의 흐름을 따르며, 일부 중간 값을 포함할 수 있습니다. 등록 예제에서는 Relying Partychallenge 입력을 정의하고, 클라이언트clientDataJSON 출력을 생성하며 인증자attestationObject 출력을 생성합니다. 인증 예제에서는 Relying Partychallenge 입력을 정의하고, 클라이언트clientDataJSON 출력을 생성하며 인증자authenticatorDatasignature 출력을 생성합니다. 그 외 암호학적으로 관련 없는 입력과 출력은 포함하지 않습니다.

인증자 구현자들은 attestationObject, authenticatorDatasignature 출력을 자신들의 구현이 비슷한 구조로 만드는지 확인할 수 있습니다. 클라이언트 구현자들은 clientDataJSON 출력 구조가 유사한지 확인할 수 있습니다. Relying Party 구현자들은 동일 challenge 입력으로 등록 출력을 성공적으로 검증할 수 있고, 동일 challenge 입력과 등록 예제에서 얻은 credential public key, credential ID로 인증 출력을 검증할 수 있는지 체크할 수 있습니다.

모든 예제는 RP ID example.orgorigin https://example.org 그리고 해당되는 경우 topOrigin https://example.com을 사용합니다. 별도 언급이 없다면 예제에는 attestation 없음이 포함되어 있습니다.

모든 랜덤 값은 CDDL에서 'WebAuthn test vectors'로 명시된 기본 입력 키 소재에서 HKDF-SHA-256 [RFC5869]을 사용해 결정적으로 생성됩니다. ECDSA 서명은 결정론적 nonce [RFC6979]를 사용합니다. 예제의 RSA 키는 p ≥ 1024인 두 개의 가장 작은 메르센 소수 2p - 1 로 구성됩니다.

참고:

참고: CTAP2를 구현하는 인증자[FIDO-CTAP] 명세와는 다른 키로 attestation object를 반환합니다. 이 예제들은 WebAuthn Relying Party가 기대하는 attestation object 포맷을 반영하므로 CTAP2에서 출력된 attestation object는 바이트 단위로 동일해지도록 키 변환이 필요할 수 있습니다.

16.1. Attestation 신뢰 루트 인증서

모든 attestation이 포함된 예제는 X.509 DER [RFC5280]로 인코딩된 아래의 attestation_ca_cert 신뢰 루트 인증서를 사용합니다:

attestation_ca_key = h'7809337f05740a96a78eedf9e9280499dcc8f2aa129616049ec1dccfe103eb2a'   ; Derived by: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='Attestation CA', L=32)
attestation_ca_serial_number = h'ed7f905d8bd0b414d1784913170a90b6'   ; Derived by: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='Attestation CA', L=16)
attestation_ca_cert = h'30820207308201ada003020102021100ed7f905d8bd0b414d1784913170a90b6300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a3062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d030107034200043269300e5ff7b699015f70cf80a8763bf705bc2e2af0c1b39cff718b7c35880ca30f319078d91b03389a006fdfc8a1dcd84edfa07d30aa13474a248a0dab5baaa3423040300f0603551d130101ff040530030101ff300e0603551d0f0101ff040403020106301d0603551d0e0416041445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d04030203480030450220483063b6bb08dcc83da33a02c11d2f42203176893554d138c614a36908724cc8022100f5ef2c912d4500b3e2f5b591d0622491e9f220dfd1f9734ec484bb7e90887663'

16.1.1. ES256 자격 증명(Attestation 없음)

등록:

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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
extra_client_data = h'06441e0e375c4c1ad70620302532c4e5'   ; 파생 방법: 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'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22414d4d507434557878475453746e63647134313759447742466938767049612d7077386f4f755657345441222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20426b5165446a646354427258426941774a544c4535513d3d227d'
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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
; 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.1.2. 자체 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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
extra_client_data = h'53d8535ef284d944643276ffd3160756'   ; 파생 방법: 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'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a2265476e4374334c55745936366b336a506a796e6962506b31716e666644616966715a774c33417032392d55222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a205539685458764b453255526b4d6e625f3078594856673d3d227d'
attestationObject = h'a363666d74667061636b65646761747453746d74a263616c67266373696758483046022100ae045923ded832b844cae4d5fc864277c0dc114ad713e271af0f0d371bd3ac540221009077a088ed51a673951ad3ba2673d5029bab65b64f4ea67b234321f86fcfac5d68617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b55d00000000df850e09db6afbdfab51697791506cfc0020455ef34e2043a87db3d4afeb39bbcb6cc32df9347c789a865ecdca129cbef58ca5010203262001215820eb151c8176b225cc651559fecf07af450fd85802046656b34c18f6cf193843c5225820927b8aa427a2be1b8834d233a2d34f61f13bfd44119c325d5896e183fee484f2'

인증:

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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
extra_client_data = h'8136f9debcfa121496a265c6ce2982d5'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='packed-self.ES256', L=16)
; auth_data_UV_BS는 인증자 데이터 플래그의 UV와 BS 비트를 설정하나, BS는 등록 시 BE가 설정되었을 때만 설정됨
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'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a225248696843784e534e493352594d45314f7731476d3132786e726b634a5f6666707637546e2d4a71386773222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a206754623533727a36456853576f6d58477a696d4331513d3d227d'
signature = h'3044022076691be76a8618976d9803c4cdc9b97d34a7af37e3bdc894a2bf54f040ffae850220448033a015296ffb09a762efd0d719a55346941e17e91ebf64c60d439d0b9744'

16.1.3. 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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
extra_client_data = h'cd9aae12d0d1f435aaa56e6d0564c5ba'   ; 파생 방법: 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'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a224f2d57717a514e5463554a484930437257576e7951504859647862694332674872434d475666704c4f306b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a207a5a71754574445239445771705735744257544675673d3d227d'
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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
extra_client_data = h'f76a5c4d50f401bcbeab876d9a3e9e7e'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='none.ES256.crossOrigin', L=16)
; auth_data_UV_BS는 인증자 데이터 플래그의 UV와 BS 비트를 설정하나, BS는 등록 시 BE가 설정되었을 때만 설정됨
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'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a226832716c463771445f65356c5f505f62796b7945377135645650674547685f49584a6b655737736e4d5463222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a2039327063545644304162792d713464746d6a366566673d3d227d'
signature = h'304402204396b14b216ed47920dc359e46aa0a1d4a912cf9d50f25a58ec236a11db4cf5e02204fdb59ff01656c4b0868e415436a464b0e30e94b02c719b995afaba9c917146b'

16.1.4. 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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
extra_client_data = h'52216824c5514070c0156162e2fc54a5'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='none.ES256.topOrigin', L=16)
; auth_data_UV_BS는 인증자 데이터 플래그의 UV와 BS 비트를 설정하나, BS는 등록 시 BE가 설정되었을 때만 설정됨
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'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22315570636a4b53324b6f34377379486a7372787a68572d466f51465132796b3572426c584f6573656f4759222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a747275652c22746f704f726967696e223a2268747470733a2f2f6578616d706c652e636f6d222c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a205569466f4a4d565251484441465746693476785570513d3d227d'
signature = h'304402206a19613fa8cfacfc8027272aec5dae3555fea9f983d841581466678d71e6761a02207a9785ba22e48eb18525850357d9dc70795aaad2e6021159c4a4a183146eaa71'

16.1.5. 아주 긴 자격 증명 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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
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'

인증:

challenge = h'ef1deba56dce48f674a447ccf63b9599258ce87648e5c396f2ef0ca1da460e3b'   ; 파생 방법: 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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
; auth_data_UV_BS는 인증자 데이터 플래그의 UV와 BS 비트를 설정하나, BS는 등록 시 BE가 설정되었을 때만 설정됨
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.1.6. ES256 자격 증명을 사용한 Packed Attestation

등록:

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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
extra_client_data = h'f5af1b3588ca0a05ab05753e7c29756a'   ; 파생 방법: 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'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a227752684b58393334424634543345663153324831706c61325a725751475046746877365356756d56494249222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20396138624e596a4b436757724258552d66436c3161673d3d227d'
attestationObject = h'a363666d74667061636b65646761747453746d74a363616c67266373696758473045022025fcee945801b94e63d7c029e6f761654cf02e7100d5364a3b90e03daa6276fc022100eabcdf4ce19feb0980e829c3b6137079b18e42f43ce5c3c573b83368794f354c637835638159022530820221308201c8a00302010202110088c220f83c8ef1feafe94deae45faad0300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d03010703420004a91ba4389409dd38a428141940ca8feb1ac0d7b4350558104a3777a49322f3798440f378b3398ab2d3bb7bf91322c92eb23556f59ad0a836fec4c7663b0e4dc3a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414a589ba72d060842ab11f74fb246bdedab16f9b9b301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d040302034700304402201726b9d85ecd8a5ed51163722ca3a20886fd9b242a0aa0453d442116075defd502207ef471e530ac87961a88a7f0d0c17b091ffc6b9238d30f79f635b417be5910e768617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54d00000000876ca4f52071c3e9b25509ef2cdf7ed60020c9a6f5b3462d02873fea0c56862234f99f081728084e511bb7760201a89054a5a50102032620012158201cf27f25da591208a4239c2e324f104f585525479a29edeedd830f48e77aeae522582059e4b7da6c0106e206ce390c93ab98a15a5ec3887e57f0cc2bece803b920c423'

인증:

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)
; extra_client_data는 client_data_gen_flags의 0x01 비트가 1일 때만 포함됨
extra_client_data = h'019330c8cc486c3f3eba0b85369eabf1'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0b', info='packed.ES256', L=16)
; auth_data_UV_BS는 인증자 데이터 플래그의 UV와 BS 비트를 설정하나, BS는 등록 시 BE가 설정되었을 때만 설정됨
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'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a2273524276704770587676463446524841565833496d4b4130453958773858306b526a44426c4d6668726255222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20415a4d77794d78496244382d756775464e70367238513d3d227d'
signature = h'30460221009d8d54895393894d37b9fa7bdfbcff05403de3cf0d6443ffb394fa239f101579022100c8871288f19c6c48a3b64c09d39868c12d16ed80ea4c5d8890288975c0272f50'

16.1.7. ES384 자격 증명을 이용한 Packed Attestation

등록:

challenge = h'567b030b3e186bc1d169dd45b79f9e0d86f1fd63474da3eade5bdb8db379a0c3'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='packed.ES384', L=32)

credential_private_key = h'271e37d309c558c0f35222b37abba7500377d68e179e4c74b0cb558551b2e5276b47b90a317ca8ebbe1a12c93c2d5dd9'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='packed.ES384', L=48)
client_data_gen_flags = h'32'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='packed.ES384', L=1)
; client_data_gen_flags의 0x01 비트가 1일 때에만 extra_client_data가 포함됩니다
aaguid = h'e950dcda3bdae1d087cda380a897848b'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='packed.ES384', L=16)
credential_id = h'953ae2dd9f28b1a1d5802c83e1f65833bb9769a08de82d812bc27c13fc6f06a9'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='packed.ES384', L=32)
; auth_data_UV_BE_BS는 인증자 데이터 플래그의 UV, BE, BS 비트를 결정하지만, BS는 BE일 때만 설정됩니다
auth_data_UV_BE_BS = h'db'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='packed.ES384', L=1)
attestation_private_key = h'8d979fbb6e49c4eeb5925a2bca0fcdb023d3fb90bcadce8391da9da4ed2aee9a'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='packed.ES384', L=32)
attestation_cert_serial_number = h'3d0a5588bb87ebb1d4cee4a1807c1b7c'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='packed.ES384', L=16)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22566e7344437a3459613848526164314674352d65445962785f574e4854615071336c76626a624e356f4d4d222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
attestationObject = h'a363666d74667061636b65646761747453746d74a363616c67266373696758473045022100c56ecc970b7843833e0f461fde26233f61eb395161d481558c08b9c6ed61675b022029f5e05033705cd0f9b0a07e149468ec308a4f84906409efdceb1da20a7518d6637835638159022530820221308201c7a00302010202103d0a5588bb87ebb1d4cee4a1807c1b7c300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d0301070342000417e5cc91d676d370e36aa7de40c25aacb45a3845f13d2932088ece2270b9b431241c219c22d0c256c9438ade00f2c05e62f8ef906b9b997ae9f3c460c2db66f5a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414c7c8dd95382a2230e4c0dd3664338fa908169a9c301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d0403020348003045022054068cc9ae038937b7c468c307edb9c6927ffdeb6a20070c483eb40330f99f10022100cf41953919c3c04693d6b1f42a613753f204e70e85fc6e9b17036170b83596e068617574684461746158c5bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b55900000000e950dcda3bdae1d087cda380a897848b0020953ae2dd9f28b1a1d5802c83e1f65833bb9769a08de82d812bc27c13fc6f06a9a5010203382220022158304866bd8b01da789e9eb806e5eab05ae5a638542296ab057a2f1bbce9b58f8a08b9171390b58a37ac7fffc2c5f45857da2258302a0b024c7f4b72072a1f96bd30a7261aae9571dd39870eb29e55c0941c6b08e89629a1ea1216aa64ce57c2807bf3901a'

인증:

challenge = h'ff41c3d25dbd8966fb61e28ef5e47041e137ed268520412d76202ba0ad2d1453'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='packed.ES384', L=32)

client_data_gen_flags = h'0c'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='packed.ES384', L=1)
; client_data_gen_flags의 0x01 비트가 1일 때에만 extra_client_data가 포함됩니다
; auth_data_UV_BS는 인증자 데이터 플래그의 UV, BS 비트를 설정하지만, BS는 등록 때 BE가 설정된 경우에만 적용됩니다
auth_data_UV_BS = h'af'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0a', info='packed.ES384', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50d00000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a225f304844306c32396957623759654b4f39655277516545333753614649454574646941726f4b307446464d222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
signature = h'3065023100e4efbb46745ed00e67c4d51ab2bacab2af62ffa8b7c5fecec6d7d9bf2582275034a713a3dd731685eee81adfaf6aa63f0230161655353f07e018a3c2539f8de7c8c4cf88d4c32d2be29fe4e76fa096ecc9458bbfe0895d57129ab324130e6f0692db'

16.1.8. ES512 자격 증명을 이용한 Packed Attestation

등록:

challenge = h'4ee220cd92b07e11451cb4c201c5755bd879848e492a9b12d79135c62764dc2fd28ead4808cafe5ad1de8fa9e08d4a8eeafea4dfb333877b02bc503f475d3b0c1394a7683baaf4f2477829f7b8cf750948985558748c073068396fcfdcd3f245bf2038e6bb38d7532768aad13be8c118f727722e7426139041e9caca503884c5'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='packed.ES512', L=128)

credential_private_key = h'f11120594f6a4944ac3ba59adbbc5b85016895b649f4cc949a610f4b48be47b318850bacb105f747647bba8852b6b8e52a0b3679f1bbbdfe18c99409bcb644fa45'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='packed.ES512', L=65)
client_data_gen_flags = h'6d'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='packed.ES512', L=1)
; client_data_gen_flags의 0x01 비트가 1일 때에만 extra_client_data가 포함됩니다
extra_client_data = h'a37a958ce2f6b535a6e06c64cc8fd082'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='packed.ES512', L=16)
aaguid = h'39d8ce6a3cf61025775083a738e5c254'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='packed.ES512', L=16)
credential_id = h'd17d5af7e3f37c56622a67c8462c9e1c6336dfccb8b61d359dc47378dba58ce4'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='packed.ES512', L=32)
; auth_data_UV_BE_BS는 인증자 데이터 플래그의 UV, BE, BS 비트를 결정하지만, BS는 BE일 때만 설정됩니다
auth_data_UV_BE_BS = h'cf'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='packed.ES512', L=1)
attestation_private_key = h'ffbc89d5f75994f52dc5e7538ee269402d26995d40c16fb713473e34fca98be4'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='packed.ES512', L=32)
attestation_cert_serial_number = h'8a128b7ebe52b993835779e6d9b81355'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='packed.ES512', L=16)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22547549677a5a4b7766684646484c544341635631573968356849354a4b707353313545317869646b33435f536a713149434d722d577448656a366e676a55714f3676366b33374d7a683373437646415f5231303744424f5570326737717654795233677039376a5064516c496d465659644977484d47673562385f63305f4a46767941343572733431314d6e614b72524f2d6a424750636e636935304a684f5151656e4b796c4134684d55222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a206f3371566a4f4c327454576d3447786b7a495f5167673d3d227d'
attestationObject = h'a363666d74667061636b65646761747453746d74a363616c67266373696758483046022100c48fcbd826bbc79680802026688d41ab6da8c3a1d22ab6cecf36c8d7695d22500221008767dfe591277e973078d5692c8c35cf9d579792822e7145c96a0ac4515df5b0637835638159022730820223308201c8a0030201020211008a128b7ebe52b993835779e6d9b81355300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d03010703420004940b68885291536e2f7c60c05acfb252e7eebcf4304425dd93ab7b1962f20492bf18dc0f12862599e81fb764ac92151f9a78fcbb35d7a26c8c52949b18133c06a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e041604143ffad863abcd3dc5717b8a252189f41af97e7f31301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d0403020349003046022100832c8b64c4f0188bd32e1bec63e13301cdc03165d3ef840d1f3dabb9a5719f83022100add57a9d5bedec98f29222dfc97ea795d055ee13a02a153d02be9ce00aedeb9168617574684461746158e9bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54d0000000039d8ce6a3cf61025775083a738e5c2540020d17d5af7e3f37c56622a67c8462c9e1c6336dfccb8b61d359dc47378dba58ce4a5010203382320032158420083240a2c3ad21a3dc0a6daa3d8bc05a46d7cd9825ba010ae2a22686c2d6d663d7d5f678987fb1e767542e63dc197ae915e25f8ee284651af29066910a2cc083f50225842017337df47ab5cce5d716ef8caffa97a3012689b1f326ea6c43a1ba9596c72f71f0122390143552b42be772b4c35ffb961220c743b486a601ea4cb6d5412f5b078d3'

인증:

challenge = h'08d3190c6dcb3d4f0cb659a0333bf5ea124ddf36a0cd33d5204b0d7a22a8cc26f2e4f169d200285c77b3fb22e0f1c7f49a87d4be2d25e92d797808ddaaa9b5715efd3a6ada9339d3052a687dbc5d2f8c871b0451e0691f57ad138541b7b72e7aa8933729ec1c664bf2e4dedae1616d08ecefa80a2a53b103663ce5a881048829'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='packed.ES512', L=128)

client_data_gen_flags = h'ac'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0a', info='packed.ES512', L=1)
; client_data_gen_flags의 0x01 비트가 1일 때에만 extra_client_data가 포함됩니다
; auth_data_UV_BS는 인증자 데이터 플래그의 UV, BS 비트를 설정하지만, BS는 등록 때 BE가 설정된 경우에만 적용됩니다
auth_data_UV_BS = h'52'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0b', info='packed.ES512', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b51900000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22434e4d5a4447334c5055384d746c6d674d7a763136684a4e337a61677a5450564945734e65694b6f7a436279355046703067416f5848657a2d794c67386366306d6f66557669306c3653313565416a6471716d31635637394f6d72616b7a6e544253706f666278644c3479484777525234476b66563630546855473374793536714a4d334b6577635a6b7679354e376134574674434f7a7671416f71553745445a6a7a6c7149454569436b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
signature = h'3081870242009bda02fe384e77bcb9fb42b07c395b7a53ec9d9616dd0308ab8495c2141c8364c7d16e212a4a4fb8e3987ff6c99eafd64d8484fd28c3fc7968f658a9033d1bb1b802416383e9f3ee20c691b66620299fef36bea2df4d39c92b2ead92f58e7b79ab0d9864d2ebf3b0dcc66ea13234492ccee6e9d421db43c959bcb94c162dc9494136c9f6'

16.1.9. RS256 자격 증명을 이용한 Packed Attestation

등록:

challenge = h'bea8f0770009bd57f2c0df6fea9f743a27e4b61bbe923c862c7aad7a9fc8e4a6'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='packed.RS256', L=32)

; 가장 작은 두 메르센 소수 2^p - 1 (p >= 1024)
private_key_p = 2^1279 - 1 = h'7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
private_key_q = 2^2203 - 1 = h'07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
client_data_gen_flags = h'1c'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='packed.RS256', L=1)
; client_data_gen_flags의 0x01 비트가 1일 때에만 extra_client_data가 포함됩니다
aaguid = h'428f8878298b9862a36ad8c7527bfef2'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='packed.RS256', L=16)
credential_id = h'992a18acc83f67533600c1138a4b4c4bd236de13629cf025ed17cb00b00b74df'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='packed.RS256', L=32)
; auth_data_UV_BE_BS는 인증자 데이터 플래그의 UV, BE, BS 비트를 결정하지만, BS는 BE일 때만 설정됩니다
auth_data_UV_BE_BS = h'7e'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='packed.RS256', L=1)
attestation_private_key = h'08a1322d5aa5b5b40cd67c2cc30b038e7921d7888c84c342d50d79f0c5fc3464'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='packed.RS256', L=32)
attestation_cert_serial_number = h'1f6fb7a5ece81b45896b983a995da5f3'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='packed.RS256', L=16)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a2276716a776477414a76566679774e3976367039304f69666b7468752d6b6a79474c48717465705f49354b59222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
attestationObject = h'a363666d74667061636b65646761747453746d74a363616c672663736967584730450221008b8c5c6ea8c142c032e0be69e1353d44461c5c9109941cdda951b976eb95b6b302204d52f406c19e254b3ff9589bd18070fb055ac8db12fdd0a6734bea9d7168e900637835638159022630820222308201c7a00302010202101f6fb7a5ece81b45896b983a995da5f3300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d03010703420004b7b36b7542a11120b443c794d0c99fdc25a06b76586413d81e086163ef6fe147a557afc34e2861d9057d6d465d4705a0310550bdeeb5f35ee35b9425ab859981a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414fb37b647bccfb9e54d989eaaacc1633868703fb3301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d0403020349003046022100b86bc129d92afca7d9869a39f70f139a305b4073a39eb654d81424bed5757d91022100cf9f7c60cab7c4a7d3e7f0020f281a93d4fd0a9f95121b989f56932a68885fba68617574684461746159021bbfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b55d00000000428f8878298b9862a36ad8c7527bfef20020992a18acc83f67533600c1138a4b4c4bd236de13629cf025ed17cb00b00b74dfa4010303390100205901b403fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012143010001'

인증:

challenge = h'295f59f5fa8fe62c5aca9e27626c78c8da376ae6d8cd2dd29aebad601e1bc4c5'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='packed.RS256', L=32)

client_data_gen_flags = h'0e'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='packed.RS256', L=1)
; client_data_gen_flags의 0x01 비트가 1일 때에만 extra_client_data가 포함됩니다
; auth_data_UV_BS는 인증자 데이터 플래그의 UV, BS 비트를 설정하지만, BS는 등록 때 BE가 설정된 경우에만 적용됩니다
auth_data_UV_BS = h'ba'   ; 파생 방법: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='packed.RS256', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b51900000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a224b56395a39667150356978617970346e596d7834794e6f33617562597a5333536d75757459423462784d55222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
signature = h'01063d52d7c39b4d432fc7063c5d93e582bdcb16889cd71f888d67d880ea730a428498d3bc8e1ee11f2b1ecbe6c292b118c55ffaaddefa8cad0a54dd137c51f1eec673f1bb6c4d1789d6826a222b22d0f585fc901fdc933212e579d199b89d672aa44891333e6a1355536025e82b25590256c3538229b55737083b2f6b9377e49e2472f11952f79fdd0da180b5ffd901b4049a8f081bb40711bef76c62aed943571f2d0575304cb549d68d8892f95086a30f93716aee818f8dc06e96c0d5e0ed4cfa9fd8773d90464b68cf140f7986666ff9c9e3302acd0535d60d769f465e2ab57ef8aabc89fccfef7ba32a64154a8b3d26be2298f470b8cc5377dbe3dfd4b0b45f8f01e63bde6cfc76b62771f9b70aa27cf40152cad93aa5acd784fd4b90f676e2ea828d0bf2400aebbaae4153e5838f537f88b6228346782a93a899be66ec77de45b3efcf311da6321c92e6b0cd11bfe653bf3e98cee8e341f02d67dbb6f9c98d9e8178090cfb5b70fbc6d541599ac794ae2f1d4de1286ec8de8c2daf7b1d15c8438e90d924df5c19045220a4c8438c1b979bbe016cf3d0eeec23c3999d4882cc645b776de930756612cdc6dd398160ff02a6'

16.1.10. Ed25519 자격 증명을 사용한 Packed 증명

등록:

challenge = h'560c73a09ce7a1586d61c1d6e41fef149be523e220fc9f385d38ab23702ebf1b'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='packed.Ed25519', L=32)

private_key = h'c87fce9e9cd283d272a2418d9683366f83661e458ad4451f0f1c95cb83b0f0a8'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='packed.Ed25519', L=32)
client_data_gen_flags = h'41'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='packed.Ed25519', L=1)
; client_data_gen_flags의 0x01 비트가 1이면 extra_client_data가 포함됩니다
extra_client_data = h'db7587e24b9187edb77933754331e443'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='packed.Ed25519', L=16)
aaguid = h'164009ea09faae7c397bc3e2ad0e7ec0'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='packed.Ed25519', L=16)
credential_id = h'c6cffa01b7fda368a7e0b29c1384a719820246bca894dd12914708743af0cecd'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='packed.Ed25519', L=32)
; auth_data_UV_BE_BS는 인증기 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만 BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'e8'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='packed.Ed25519', L=1)
attestation_private_key = h'673ee7fd94405de523fd84a088ab082d75b7fceef02a301e2bca0a28537cf243'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='packed.Ed25519', L=32)
attestation_cert_serial_number = h'6e391f23f57150dc7a12dad18f2b43ad'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='packed.Ed25519', L=16)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a225667787a6f4a7a6e6f5668745963485735425f76464a766c492d49675f4a38345854697249334175767873222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a2032335748346b7552682d323365544e31517a486b51773d3d227d'
attestationObject = h'a363666d74667061636b65646761747453746d74a363616c672663736967584730450220730a54d4f76cb1f2b7dd4a5a6eee3374e3c8a60fb3c4daa527c9277e365b64aa0221008b31a04a28cc4148b14c42a916548ee7f430bc7629295b42ee93e5d1aaba8ee6637835638159022530820221308201c7a00302010202106e391f23f57150dc7a12dad18f2b43ad300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d03010703420004fb96a581a0b36742a8c45d6ffb5af1ef155524b50339445ec1109874045e0087db77edef91f3dc949927470d84b01627087b72c86b7c9d02e1389cba680ffc36a360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414ef2ce1a86caba85121130a16e8ce82a75d5a6653301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d0403020348003045022100ad4fa628cffba5a642a562cbfefe63efecce26d90c80114114d1745383e12f01022028af87ba3b0ff868a34b9458bc6973b27380a328dd87b7436651ffa823280bca6861757468446174615881bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54900000000164009ea09faae7c397bc3e2ad0e7ec00020c6cffa01b7fda368a7e0b29c1384a719820246bca894dd12914708743af0cecda401010327200621582089f81eba4a1f510cb243ff7fb9e9cf899bf627e49ce1ac3c3eae8adb2a8d7d7b'

인증:

challenge = h'3790da8b2b72ee8ce19761787ad38cbfaa697eb3ca013a1342988756b98785ab'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='packed.Ed25519', L=32)

client_data_gen_flags = h'de'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0a', info='packed.Ed25519', L=1)
; client_data_gen_flags의 0x01 비트가 1이면 extra_client_data가 포함됩니다
; auth_data_UV_BS는 인증기 데이터 플래그의 UV 및 BS 비트를 설정하지만, BS는 등록 시 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BS = h'18'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0b', info='packed.Ed25519', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b51900000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a224e35446169797479376f7a686c32463465744f4d763670706672504b41546f545170694856726d48686173222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
signature = h'4c873571377ac019f257d6bf07249f63ac2487483c51bc511ce0f0e3266c840cb07a09cdc445a2f963d8603a9f0f6cf9ce709d7fc6a96c7c51ea08d33776010c'

16.1.11. ES256 자격 증명을 사용한 TPM 증명

등록:

challenge = h'cfc82cdf1ceee876120aa88f0364f0910193460cfb97a317b2fe090694f9a299'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='tpm.ES256', L=32)

credential_private_key = h'80c60805e564f6d33e7abdff9d32e3db09a6219fe378a268d23107191b18e39f'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='tpm.ES256', L=32)
client_data_gen_flags = h'84'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='tpm.ES256', L=1)
; client_data_gen_flags의 0x01 비트가 1이면 extra_client_data가 포함됩니다
aaguid = h'4b92a377fc5f6107c4c85c190adbfd99'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='tpm.ES256', L=16)
credential_id = h'ec27bec7521c894bbb821105ea3724c90e770cf1fa354157ef18d0f18f78bea9'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='tpm.ES256', L=32)
; auth_data_UV_BE_BS는 인증기 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만 BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'af'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='tpm.ES256', L=1)
attestation_private_key = h'6210f09e0ce7593e851a880a4bdde2d2192afeac46104abce1a890a5a71cf0c6'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='tpm.ES256', L=32)
attestation_cert_serial_number = h'311fc42da0ab10c43a9b1bf3a75e34e2'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='tpm.ES256', L=16)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a227a38677333787a753648595343716950413254776b51475452677a376c364d587376344a427054356f706b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
attestationObject = h'a363666d746374706d6761747453746d74a663616c67266373696758463044022066e5826a652091030fd444e33c3eca2bc6dc548cf3045013addb38aa6457a21002203f3a5c95c9e707d0e555041bcc8698ee4ebc04e26cc8bae459705471789851766376657263322e30637835638159023a30820236308201dca0030201020210311fc42da0ab10c43a9b1bf3a75e34e2300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a30003059301306072a8648ce3d020106082a8648ce3d03010703420004c54e3f109094f60d7699b7db5d838569ffd1f3e1c9e897cd9eb40063f9402e3e9937e936cf1fcd5eb743ff443c97ab2edcd7c8e0e6cf6cfd413b8ab19fffa769a381d33081d0300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e041604145f546cb6973d4981e80fcdc7463859f5879680e4301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e30100603551d250409300706056781050803305e0603551d110101ff04543052a450304e314c3014060567810502010c0b69643a30303030303030303014060567810502030c0b69643a3030303030303030301e060567810502020c15576562417574686e207465737420766563746f7273300a06082a8648ce3d0403020348003045022063c9a2797b8066f1db34dd609f1ab6695607e7a98e9ff8090a68853c9a9fc949022100a55831a39f5b8a2aa9a68837829cabf43fea2a5cea4859ae851cac78e6ac3e97677075624172656158560023000b0004000000000010001000030010002041202698c9d9753fb4bb3f27cd09fe6b8afdb76438ee2ae54d7c9dade10d864b0020d8735115cdb330a63ea1d6e43d5000f4bd56f99bce83ee1d73301fc270116d076863657274496e666f5869ff544347801700000020277d0e05579dd013215a62273f7f3a3e7e191ead2654a3036d75a5a3ee37a6b0000000000000000011111111222222223300000000000000000022000b9c42d8aad5939331b9af3711af179f17123178098c9a7d0ca89fcd1fc800f3c7000068617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54d000000004b92a377fc5f6107c4c85c190adbfd990020ec27bec7521c894bbb821105ea3724c90e770cf1fa354157ef18d0f18f78bea9a501020326200121582041202698c9d9753fb4bb3f27cd09fe6b8afdb76438ee2ae54d7c9dade10d864b225820d8735115cdb330a63ea1d6e43d5000f4bd56f99bce83ee1d73301fc270116d07'

인증:

challenge = h'00093b66c21d5b5e89f7a07082118907ea3e502d343b314b8c5a54d62db202fb'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='tpm.ES256', L=32)

client_data_gen_flags = h'86'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='tpm.ES256', L=1)
; client_data_gen_flags의 0x01 비트가 1이면 extra_client_data가 포함됩니다
; auth_data_UV_BS는 인증기 데이터 플래그의 UV와 BS 비트를 설정하지만, BS는 등록 시 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BS = h'87'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0a', info='tpm.ES256', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50d00000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a2241416b375a7349645731364a393642776768474a422d6f2d554330304f7a464c6a46705531693279417673222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
signature = h'3045022060dc76b1607ec716c6e5eba8d056695ed6bc47b2e3d7a729c34e759e3ab66aa0022100d010a9e8fddcb64c439dfdca628ddb33cf245d567d157d9f66f942601bed9b38'

16.1.12. ES256 자격 증명을 사용한 Android Key 증명

등록:

challenge = h'3de1f0b7365dccde3ff0cbf25e26ffa7baff87ef106c80fc865dc402d9960050'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='android-key.ES256', L=32)

credential_private_key = h'd4328d911acb0ebcc42aad29b29ffb55d5bc31d8af7ca9a16703d56c21abc7b4'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='android-key.ES256', L=32)
client_data_gen_flags = h'73'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='android-key.ES256', L=1)
; client_data_gen_flags의 0x01 비트가 1이면 extra_client_data가 포함됩니다
extra_client_data = h'555d5c42e476a8b33f6a63dfa07ccbd2'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='android-key.ES256', L=16)
aaguid = h'ade9705e1ce7085b899a540d02199bf8'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='android-key.ES256', L=16)
credential_id = h'0a4729519788b6ed8a2d772b494e186244d8c798c052960dbc8c10c915176795'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='android-key.ES256', L=32)
; auth_data_UV_BE_BS는 인증기 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만 BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'1e'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='android-key.ES256', L=1)
attestation_cert_serial_number = h'1ff91f76b63f44812f998b250b0286bf'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='android-key.ES256', L=16)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a2250654877747a5a647a4e345f384d76795869625f7037725f682d385162494438686c334541746d57414641222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a205656316351755232714c4d5f616d50666f487a4c30673d3d227d'
attestationObject = h'a363666d746b616e64726f69642d6b65796761747453746d74a363616c672663736967584630440220592bbc3c4c5f6158b52be1e085c92848986d7844245dfc9512e1a7e9ff7a2cd8022015bdd0852d3bd091e1c22da4211f4ccf0fdf4d912599d1c6630b1f310d3166f5637835638159026d3082026930820210a00302010202101ff91f76b63f44812f998b250b0286bf300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d0301070342000499169657036d089a2a9821a7d0063d341f1a4613389359636efab5f3cbf1accfdd91c55543176ea99b644406dd1dd63774b6af65ac759e06ff40b1c8ab02df6ba381a83081a5300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e041604141ac81e50641e8d1339ab9f7eb25f0cd5aac054b0301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e3045060a2b06010401d679020111043730350202012c0201000201000201000420b20e943e3a7544b3a438943b6d5655313a47ef1af34e00ff3261aeb9ed155817040030003000300a06082a8648ce3d040302034700304402206f4609c9ffc946c418cef04c64a0d07bcce78f329b99270b822f2a4d1e3b75330220093c8d18328f36ef157f296393bdc7721dd2bd67438ffeaa42f051a044b7457168617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b55d00000000ade9705e1ce7085b899a540d02199bf800200a4729519788b6ed8a2d772b494e186244d8c798c052960dbc8c10c915176795a501020326200121582099169657036d089a2a9821a7d0063d341f1a4613389359636efab5f3cbf1accf225820dd91c55543176ea99b644406dd1dd63774b6af65ac759e06ff40b1c8ab02df6b'

인증:

challenge = h'e4ee05ca9dbced74116540f24ed9adc62aae8507560522844ffa7eea14f7af86'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='android-key.ES256', L=32)

client_data_gen_flags = h'43'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='android-key.ES256', L=1)
; client_data_gen_flags의 0x01 비트가 1이면 extra_client_data가 포함됩니다
extra_client_data = h'ab127107eff182bc3230beb5f1dad29c'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0a', info='android-key.ES256', L=16)
; auth_data_UV_BS는 인증기 데이터 플래그의 UV와 BS 비트를 설정하지만, BS는 등록 시 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BS = h'4a'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0b', info='android-key.ES256', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50900000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22354f344679703238375851525a55447954746d74786971756851645742534b45545f702d36685433723459222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a2071784a78422d5f78677277794d4c3631386472536e413d3d227d'
signature = h'304502202060107d953b286aa1bf35e3e8c78b383fddab5591b2db17ffb23ed83fe7df20022100a99be0297cb0d9d38aa96f30b760a4e0749dab385acd2a51d0560caae570d225'

16.1.13. ES256 자격 증명을 사용한 Apple 익명 증명

등록:

challenge = h'f7f688213852007775009cf8c096fda89d60b9a9fb5a50dd81dd9898af5a0609'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='apple.ES256', L=32)

credential_private_key = h'de987bd9d43eeb44728ce0b14df11209dff931fb56b5b1948de4c0da1144ded0'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='apple.ES256', L=32)
client_data_gen_flags = h'5f'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='apple.ES256', L=1)
; client_data_gen_flags의 0x01 비트가 1이면 extra_client_data가 포함됩니다
extra_client_data = h'4e32cf9e939a5d052b14d71b1f6b5364'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='apple.ES256', L=16)
aaguid = h'748210a20076616a733b2114336fc384'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='apple.ES256', L=16)
credential_id = h'9c4a5886af9283d9be3e9ec55978dedfdce2e3b365cab193ae850c16238fafb8'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='apple.ES256', L=32)
; auth_data_UV_BE_BS는 인증기 데이터 플래그의 UV, BE 및 BS 비트를 결정하지만 BS는 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BE_BS = h'2a'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='apple.ES256', L=1)
attestation_cert_serial_number = h'394275613d5310b81a29ce90f48b61c1'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='apple.ES256', L=16)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22395f61494954685341486431414a7a34774a6239714a316775616e37576c4464676432596d4b396142676b222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73652c22657874726144617461223a22636c69656e74446174614a534f4e206d617920626520657874656e6465642077697468206164646974696f6e616c206669656c647320696e20746865206675747572652c207375636820617320746869733a20546a4c506e704f6158515572464e6362483274545a413d3d227d'
attestationObject = h'a363666d74656170706c656761747453746d74a1637835638159025c30820258308201fea0030201020210394275613d5310b81a29ce90f48b61c1300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d030107034200048a3d5b1b4c543a706bf6e4b00afedb3c930b690dd286934fe2911f779cc7761af728e1aa3b0ff66692192daa776b83ddf8e3340d2d9a0eabdfc324eb3e2f136ca38196308193300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e0416041412f1ce6c0ae39b403bfc9200317bc183a4e4d766301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e303306092a864886f76364080204263024a122042097851a1a98b69c0614b26a94b70ec3aa07c061f89dbee23fbee01b6c42d718b0300a06082a8648ce3d040302034800304502207d541a5553f38b93b78b26a9dca58e64a7f8fac15ca206ae3ea32497cda375fb0221009137c6b75e767ec08224b29a7f703db4b745686dcc8a26b66e793688866d064f68617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54900000000748210a20076616a733b2114336fc38400209c4a5886af9283d9be3e9ec55978dedfdce2e3b365cab193ae850c16238fafb8a50102032620012158208a3d5b1b4c543a706bf6e4b00afedb3c930b690dd286934fe2911f779cc7761a225820f728e1aa3b0ff66692192daa776b83ddf8e3340d2d9a0eabdfc324eb3e2f136c'

인증:

challenge = h'd3eb2964641e26fed023403a72dde093b19c4ba9008c3f9dd83fcfd347a66d05'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='apple.ES256', L=32)

client_data_gen_flags = h'c2'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='apple.ES256', L=1)
; client_data_gen_flags의 0x01 비트가 1이면 extra_client_data가 포함됩니다
; auth_data_UV_BS는 인증기 데이터 플래그의 UV와 BS 비트를 설정하지만, BS는 등록 시 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BS = h'e2'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'0a', info='apple.ES256', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50900000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a22302d73705a4751654a76375149304136637433676b37476353366b416a442d6432445f503030656d625155222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
signature = h'3046022100ee35db795ce28044e1f8231d68b3d79a9882f7415aa35c1b5ac74d24251073c8022100dcc65691650a412d0ceef843710c09827acf26c7845bddac07eec95863e7fc4c'

16.1.14. ES256 자격 증명을 사용한 FIDO U2F 증명

등록:

challenge = h'e074372990b9caa507a227dfc67b003780c45325380d1a90c20f81ed7d080c06'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'00', info='fido-u2f.ES256', L=32)

credential_private_key = h'51bd002938fa10b83683ac2a2032d0a7338c7f65a90228cfd1f61b81ec7288d0'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'01', info='fido-u2f.ES256', L=32)
client_data_gen_flags = h'00'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'02', info='fido-u2f.ES256', L=1)
; client_data_gen_flags의 0x01 비트가 1이면 extra_client_data가 포함됩니다
aaguid = h'afb3c2efc054df425013d5c88e79c3c1'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'03', info='fido-u2f.ES256', L=16)
credential_id = h'a4ba6e2d2cfec43648d7d25c5ed5659bc18f2b781538527ebd492de03256bdf4'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'04', info='fido-u2f.ES256', L=32)
attestation_private_key = h'66fda477a2a99d14c5edd7c1041a297ba5f3375108b1d032b79429f42349ce33'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'05', info='fido-u2f.ES256', L=32)
attestation_cert_serial_number = h'04f66dc6542ea7719dea416d325a2401'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'06', info='fido-u2f.ES256', L=16)

clientDataJSON = h'7b2274797065223a22776562617574686e2e637265617465222c226368616c6c656e6765223a22344851334b5a4335797155486f696666786e73414e344445557955344452715177672d4237583049444159222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
attestationObject = h'a363666d74686669646f2d7532666761747453746d74a26373696758473045022100f41887a20063bb26867cb9751978accea5b81791a68f4f4dd6ea1fb6a5c086c302204e5e00aa3895777e6608f1f375f95450045da3da57a0e4fd451df35a31d2d98a637835638159022530820221308201c7a003020102021004f66dc6542ea7719dea416d325a2401300a06082a8648ce3d0403023062311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331253023060355040b0c1c41757468656e74696361746f72204174746573746174696f6e204341310b30090603550406130241413020170d3234303130313030303030305a180f33303234303130313030303030305a305f311e301c06035504030c15576562417574686e207465737420766563746f7273310c300a060355040a0c0357334331223020060355040b0c1941757468656e74696361746f72204174746573746174696f6e310b30090603550406130241413059301306072a8648ce3d020106082a8648ce3d0301070342000456fffa7093dede46aefeefb6e520c7ccc78967636e2f92582ba71455f64e93932dff3be4e0d4ef68e3e3b73aa087e26a0a0a30b02dc2aa2309db4c3a2fc936dea360305e300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d0603551d0e04160414420822eb1908b5cd3911017fbcad4641c05e05a3301f0603551d2304183016801445aff715b0dd786741fee996ebc16547a3931b1e300a06082a8648ce3d040302034800304502200d0b777f0a0b181ad2830275acc3150fd6092430bcd034fd77beb7bdf8c2d546022100d4864edd95daa3927080855df199f1717299b24a5eecefbd017455a9b934d8f668617574684461746158a4bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b54100000000afb3c2efc054df425013d5c88e79c3c10020a4ba6e2d2cfec43648d7d25c5ed5659bc18f2b781538527ebd492de03256bdf4a5010203262001215820b0d62de6b30f86f0bac7a9016951391c2e31849e2e64661cbd2b13cd7d5508ad225820503b0bda2a357a9a4b34475a28e65b660b4898a9e3e9bbf0820d43494297edd0'

인증:

challenge = h'f90c612981d84f599438de1a500f76926e92cc84bef8e02c6e23553f00485435'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'07', info='fido-u2f.ES256', L=32)

client_data_gen_flags = h'2c'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'08', info='fido-u2f.ES256', L=1)
; client_data_gen_flags의 0x01 비트가 1이면 extra_client_data가 포함됩니다
; auth_data_UV_BS는 인증기 데이터 플래그의 UV와 BS 비트를 설정하지만, BS는 등록 시 BE가 설정된 경우에만 설정됩니다
auth_data_UV_BS = h'd1'   ; 파생됨: HKDF-SHA-256(IKM='WebAuthn test vectors', salt=h'09', info='fido-u2f.ES256', L=1)

authenticatorData = h'bfabc37432958b063360d3ad6461c9c4735ae7f8edd46592a5e0f01452b2e4b50100000000'
clientDataJSON = h'7b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a222d5178684b59485954316d554f4e3461554139326b6d36537a49532d2d4f417362694e5650774249564455222c226f726967696e223a2268747470733a2f2f6578616d706c652e6f7267222c2263726f73734f726967696e223a66616c73657d'
signature = h'304402206172459958fea907b7292b92f555034bfd884895f287a76200c1ba287239137002204727b166147e26a21bbc2921d192ebfed569b79438538e5c128b5e28e6926dd7'

16.2. WebAuthn 확장에 대한 테스트 벡터

이 섹션은 WebAuthn 확장의 예시 값을 나열합니다.

16.2.1. 의사 난수 함수 확장 (prf)

이 섹션은 의사 난수 함수(prf) 확장의 예시 값을 나열합니다.

prf 확장은 CTAP2의 hmac-secret 확장 [FIDO-CTAP]과 통합되므로, 예시는 두 섹션으로 나뉩니다: WebAuthn prf 확장의 예시 입력 및 출력(관련: WebAuthn 클라이언트WebAuthn 릴라잉 파티); 그리고 WebAuthn prf 확장과 CTAP2 hmac-secret 확장 간의 매핑 예시(관련: WebAuthn 클라이언트WebAuthn 인증기).

16.2.1.1. 웹 인증 API

다음 예시는 WebAuthn 클라이언트 구현 및 WebAuthn 릴라잉 파티prf 확장 사용을 테스트하는 데 사용할 수 있습니다. 예시는 모두를 포괄하지는 않습니다.

이 섹션에서 사용된 의사 난수 값들은 다음과 같이 생성되었습니다:

16.2.1.2. CTAP2 hmac-secret 확장

다음 예시는 WebAuthn 클라이언트 구현이 prf 확장을 CTAP2의 [FIDO-CTAP] hmac-secret 확장과 어떻게 연동하는지 테스트하는 데 사용할 수 있습니다. 예시는 CDDL 표기법으로 제공됩니다. 예시는 모두를 포괄하지는 않습니다.

이 섹션에서 사용된 입력 및 의사 난수 값들은 다음과 같이 생성되었습니다:

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.

Adam Powers가 전체 등록인증 흐름 다이어그램 (그림 1그림 2)을 제작해주신 데에 감사드립니다.

Anthony Nadalin, John Fontana, 그리고 Richard Barnes 가 Web Authentication Working Group의 공동 의장으로 활동하며 기여해주신 점에 감사드립니다.

Simone Onofri, Philippe Le Hégaret, Wendy Seltzer, Samuel Weiler, 그리고 Harry Halpin 이 W3C 팀 컨택트로서 기여해주신 데에도 감사의 말씀을 전합니다.

18. 변경 이력

이 절은 규범적이지 않습니다.

이 절은 시간이 지남에 따라 이 명세에 이루어진 주요 변경 사항을 요약한 것입니다.

18.1. Web Authentication Level 2 [webauthn-2-20210408] 이후 변경점

18.1.1. 주요 변경

다음 변경 사항들은 Web Authentication API 및 그 동작 방식에 적용되었습니다.

변경 사항:

폐지 사항:

신규 기능:

18.1.2. 편집상 변경

다음 변경 사항들은 문서의 명확성, 가독성, 탐색성 등 향상을 위해 반영되었습니다.

색인

이 명세에서 정의된 용어

참조에 의해 정의된 용어

참고 문헌

규범적 참고 문헌

[CREDENTIAL-MANAGEMENT-1]
Nina Satragno; Marcos Caceres. Credential Management Level 1. 2024년 8월 13일. 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/
[CSS21]
Bert Bos; 외. Cascading Style Sheets Level 2 Revision 1 (CSS 2.1) Specification. 2011년 6월 7일. REC. URL: https://www.w3.org/TR/CSS21/
[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; 외. 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-CTAP]
J. Bradley; 외. Client to Authenticator Protocol (CTAP). 2022년 6월 21일. FIDO Alliance Proposed Standard. 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 Whitepaper. 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 Proposed Standard. 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
[FIDO-V2.1]
Client to Authenticator Protocol (CTAP). Editor's Draft. URL: https://fidoalliance.org/specs/fido-v2.1-ps-20210615/fido-client-to-authenticator-protocol-v2.1-ps-errata-20220621.html
[HTML]
Anne van Kesteren; 외. 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/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[Permissions-Policy]
Ian Clelland. Permissions Policy. 2025년 1월 13일. WD. URL: https://www.w3.org/TR/permissions-policy-1/
[PRIVATE-AGGREGATION-API]
Private Aggregation API. Unofficial Proposal Draft. URL: https://patcg-individual-drafts.github.io/private-aggregation-api/
[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월. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc3986
[RFC4648]
S. Josefsson. The Base16, Base32, and Base64 Data Encodings. 2006년 10월. Proposed Standard. 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월. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc5234
[RFC5280]
D. Cooper; 외. Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile. 2008년 5월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc5280
[RFC5890]
J. Klensin. Internationalized Domain Names for Applications (IDNA): Definitions and Document Framework. 2010년 8월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc5890
[RFC6454]
A. Barth. The Web Origin Concept. 2011년 12월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6454
[RFC7515]
M. Jones; J. Bradley; N. Sakimura. JSON Web Signature (JWS). 2015년 5월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7515
[RFC8152]
J. Schaad. CBOR Object Signing and Encryption (COSE). 2017년 7월. Proposed Standard. 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월. Proposed Standard. 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월. Proposed Standard. 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월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc8265
[RFC8266]
P. Saint-Andre. Preparation, Enforcement, and Comparison of Internationalized Strings Representing Nicknames. 2017년 10월. Proposed Standard. 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 Proposed Standard. URL: https://tools.ietf.org/html/rfc8610
[RFC8615]
M. Nottingham. Well-Known Uniform Resource Identifiers (URIs). 2019년 5월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc8615
[RFC8809]
Jeff Hodges; Giridhar Mandyam; Michael B. Jones. Registries for Web Authentication (WebAuthn). 2020년 8월. IETF Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc8809
[RFC8949]
C. Bormann; P. Hoffman. Concise Binary Object Representation (CBOR). 2020년 12월. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc8949
[RFC9052]
J. Schaad. CBOR Object Signing and Encryption (COSE): Structures and Process. 2022년 8월. Internet Standard. 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; 외. TCG Infrastructure Working Group: A CMC Profile for AIK Certificate Enrollment. 2011년 3월 24일. Published. URL: https://trustedcomputinggroup.org/wp-content/uploads/IWG_CMC_Profile_Cert_Enrollment_v1_r7.pdf
[TokenBinding]
A. Popov; 외. The Token Binding Protocol Version 1.0. 2018년 10월. IETF Proposed Standard. 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; 외. Web Content Accessibility Guidelines (WCAG) 2.1. 2024년 12월 12일. REC. URL: https://www.w3.org/TR/WCAG21/
[WEBAUTHN-2-20210408]
Jeff Hodges; 외. 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]
Michael Jones; Akshay Kumar; Emil Lundberg. Web Authentication: An API for accessing Public Key Credentials - Level 3. 2023년 9월 27일. WD. URL: https://www.w3.org/TR/webauthn-3/
[WebDriver]
Simon Stewart; David Burns. WebDriver. 2018년 6월 5일. REC. URL: https://www.w3.org/TR/webdriver1/
[WEBDRIVER2]
Simon Stewart; David Burns. WebDriver. 2024년 12월 12일. 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. Ceremony Design and Analysis. 2007. URL: https://eprint.iacr.org/2007/399.pdf
[CSS-OVERFLOW-3]
Elika Etemad; Florian Rivoal. CSS Overflow Module Level 3. 2023년 3월 29일. WD. URL: https://www.w3.org/TR/css-overflow-3/
[EduPersonObjectClassSpec]
EduPerson. 계속 진행 중. URL: https://refeds.org/eduperson
[FIDO-Transports-Ext]
FIDO Alliance. FIDO U2F Authenticator Transports Extension. FIDO Alliance Proposed Standard. 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 Authenticator Commands. 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; 외. FIDO Authenticator Security Requirements. FIDO Alliance Final Documents. URL: https://fidoalliance.org/specs/fido-security-requirements-v1.0-fd-20170524/
[FIDOMetadataService]
R. Lindemann; B. Hill; D. Baghdasaryan. FIDO Metadata Service. 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; 외. FIDO Security Reference. 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 JavaScript API. FIDO Alliance Proposed Standard. 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. Information technology — Vocabulary — Biometrics. 2012년 12월 15일. International Standard: ISO/IEC 2382-37:2012(E) First Edition. URL: http://standards.iso.org/ittf/PubliclyAvailableStandards/c055194_ISOIEC_2382-37_2012.zip
[RFC3279]
L. Bassham; W. Polk; R. Housley. Algorithms and Identifiers for the Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile. 2002년 4월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc3279
[RFC5869]
H. Krawczyk; P. Eronen. HMAC-based Extract-and-Expand Key Derivation Function (HKDF). 2010년 5월. Informational. URL: https://www.rfc-editor.org/rfc/rfc5869
[RFC5958]
S. Turner. Asymmetric Key Packages. 2010년 8월. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc5958
[RFC6265]
A. Barth. HTTP State Management Mechanism. 2011년 4월. Proposed Standard. URL: https://httpwg.org/specs/rfc6265.html
[RFC6979]
T. Pornin. Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA). 2013년 8월. Informational. URL: https://www.rfc-editor.org/rfc/rfc6979
[RFC8017]
K. Moriarty, Ed.; 외. PKCS #1: RSA Cryptography Specifications Version 2.2. 2016년 11월. Informational. URL: https://www.rfc-editor.org/rfc/rfc8017
[UAFProtocol]
R. Lindemann; 외. FIDO UAF Protocol Specification v1.0. FIDO Alliance Proposed Standard. URL: https://fidoalliance.org/specs/fido-uaf-v1.0-ps-20141208/fido-uaf-protocol-v1.0-ps-20141208.html
[UAX29]
UNICODE Text Segmentation. URL: http://www.unicode.org/reports/tr29/
[WebAuthn-1]
Dirk Balfanz; 외. Web Authentication:An API for accessing Public Key Credentials Level 1. 2019년 3월 4일. REC. URL: https://www.w3.org/TR/webauthn-1/
[WebAuthnAPIGuide]
Web Authentication API Guide. 실험적. URL: https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API

IDL 색인

[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 AuthenticationExtensionsClientOutputs {
  boolean appid;
};

partial dictionary AuthenticationExtensionsClientInputs {
  DOMString appidExclude;
};

partial dictionary AuthenticationExtensionsClientOutputs {
  boolean appidExclude;
};

partial dictionary AuthenticationExtensionsClientInputs {
    boolean credProps;
};

dictionary CredentialPropertiesOutput {
    boolean rk;
};

partial dictionary AuthenticationExtensionsClientOutputs {
    CredentialPropertiesOutput credProps;
};

dictionary AuthenticationExtensionsPRFValues {
    required BufferSource first;
    BufferSource second;
};

dictionary AuthenticationExtensionsPRFInputs {
    AuthenticationExtensionsPRFValues eval;
    record<DOMString, AuthenticationExtensionsPRFValues> evalByCredential;
};

partial dictionary AuthenticationExtensionsClientInputs {
    AuthenticationExtensionsPRFInputs prf;
};

dictionary AuthenticationExtensionsPRFOutputs {
    boolean enabled;
    AuthenticationExtensionsPRFValues results;
};

partial dictionary AuthenticationExtensionsClientOutputs {
    AuthenticationExtensionsPRFOutputs prf;
};

partial dictionary AuthenticationExtensionsClientInputs {
    AuthenticationExtensionsLargeBlobInputs largeBlob;
};

enum LargeBlobSupport {
  "required",
  "preferred",
};

dictionary AuthenticationExtensionsLargeBlobInputs {
    DOMString support;
    boolean read;
    BufferSource write;
};

partial dictionary AuthenticationExtensionsClientOutputs {
    AuthenticationExtensionsLargeBlobOutputs largeBlob;
};

dictionary AuthenticationExtensionsLargeBlobOutputs {
    boolean supported;
    ArrayBuffer 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