015. FIDO 2.0 Signature Format - FIDO Extensions - (1)

FIDO 2.0 Signature Format

FIDO의 3가지 스펙 문서 중 두 번째인 Signature Format에 대해서 정리한다.

참고 FIDO alliance : FIDO 2.0 Signature Format 문서

FIDO Extensions - (1)

FIDO Web API 문서에 정의된대로 FIDO 2.0의 credential을 생성하고 FIDO 2.0의 Assertion을 요청하고 생성하는 방식은 사용하는 방법에 따라 확장될 수 있다.

각 사용 사례에 따라 Registration의 확장 및 Signature의 확장을 정의하여 확장할 수 있으며 아래의 절차에 따라 확장할 수 있다.

  • makeCredential
    Registration의 확장을 위해 FIDO Web API 문서에 나와 있는 makeCredential의 요청 매개변수를 확인한다.

    참고 FIDO Web API Document

  • getAssertion
    Signature의 확장을 위해 FIDO Web API 문서에 나와있는 getAssertion의 요청 매개변수를 확인한다.

    참고 FIDO Web API Document

  • clientData
    Registration의 확장과 Signature의 확장을 위한 클라이언트 프로세싱과 clientData의 구조를 확인한다.

  • authenticatorData
    Signature의 학장을 위한 Authenticator 프로세싱과 authenticatorData의 구조를 확인한다.

FIDO 2.0 credential을 대한 assertion을 요청할 때, Client나 Authenticator가 지원하는 경우 Relying Party는 사용할 extension들에 대해 리스트업할 수 있다.

이 리스트는 Signature의 확장시 getAssertion 을 호출하거나 Registration의 확장시 makeCredential 을 호출하기 위한 매개변수들을 client platform에게 전달한다.

이를 받은 client platform은 각 플랫폼은 지원하는 각 extension에 대해 추가적인 처리과정을 거친 후에 extension이 요구사항에 맞게 clientData를 보강한다.

만약 client platform이 지원하지 않는 extension이 있다면 authenticator에게 매개변수를 통해 전달한다.

참고 지원하지 않는 extension의 경우 후술한다.

위와 같은 과정을 통해 Authenticator에게만 영향을 주는 extension을 정의할 수 있다.

마찬가지로 Authenticator는 지원가능한 extension에 대해 추가적인 처리과정을 거친 후 authenticatorData를 보강한다.

만약 미지원 extension이 있다면 이 extension은 무시된다.

Extensions that are not supported are ignored.

Extension identifiers(확장 식별자)

Extension은 extension을 만든 작성자가 선택한 문자열로 식별된다.

이를 Extension identifier(확장 식별자)라 한다.

이 Extension identifier는 말 그대로 해당 extension이 무엇인지 정확히 식별하기 위한 것으로 각 식별자는 전 세계적으로 유일무이하게 존재해야 한다.

참고 예를들어 리버스 도메인 com.example.fido.myextension과 같이 정의된 entity를 사용해야 한다.

Extension들은 여러 버전에 걸쳐 존재할 수 있기 때문에 extension identifier에는 해당 버전을 포함시켜야 한다.

하지만 위에서 언급했듯 식별자는 유일하게 존재해야 하므로 다른 버전의 extension은 사실상 다른 extension으로 취급한다.

이 포스팅에 정의된 FIDO에 의해 정의된 extension은 접두사 fido를 고정적으로 식별자로 사용하므로 fido 접두사는 서드파티에서 사용해서는 안된다.

Defining Extensions(확장 정의)

Extension을 정의할 때는 최소한 getAssertion 이나 makeCredential 호출을 통해 전송할 extension identifier와 extension client의 매개변수를 정의해야 한다.

또한 extension은 clientData 에 특정 값을 추가할 수 있는데 Signature의 Extension의 경우엔 authenticatorData 에도 특정 값을 추가할 수 있다.

참고
clientDataauthenticatorData 에 추가 사항을 정의하지 않는 extension은 가능한 지양해야 한다. 만약 추가 사항이 정의되지 않는 경우엔 Relying Party는 client나 authenticator에 의해 extension이 지원되었는지 처리되었는지 알 수가 없다.

Extending request parameters
요청 매개변수의 확장에 대해 알아보자.

extension은 client argumentauthenticator argument 라는 두 개의 요청 매개변수를 정의한다.

client argumentgetAssertion 또는 makeCredential 호출을 통해 Relying Party에서 클라이언트로 전달된다.

반대로 authenticator augment 는 클라이언트에서 Authenticator로 전달되는데, 위의 getAssertion 또는 makeCredential 호출을 처리하는 동안 FIDOEAP를 통해 기본적으로 처리된다.

참고 FIDOEAP : FIDOEAP : FIDO External Authenticator Protocol

참고 기본적으로 처리될 수도, 외부의 Authenticator에 의해 처리될 수도 있다.

Extension의 정의는 반드시 client argument 에 유효한 값을 지정해야 한다. 만약 client argument 가 잘못된 값을 가지고 있을 땐 클라이언트가 이를 무시할 수 있다.

Extension 중 일부는 클라이언트의 처리과정에만 영향을 미치므로 Authenticator argument 는 무조건 지정해야하는 것은 아니다.

Relying Party는 extension을 사용하고 사용할 extension의 client argument 를 설정하기 위해 extension dictionary 매개변수의 entry를 포함하여 getAssertion 또는 makeCredential 를 호출한다.

entry key는 extension identifier이여 하며 client argument의 값을 가져야 한다.

id:"j53psuao"}
1
2
3
4
// Example 1
var assertionPromise = credentials.getAssertion(..., /* extensions */ {
"com.example.fido.foobar": 42
});

client platform에 영향을 주는 extension은 매개변수를 JSON으로 인코딩할 수 있는 값의 집합으로 정의할 수 있다.

항상 그런 것은 아니지만 client platform에 영향을 주는 extension은 일반적으로 clientData 구조에 값을 추가하여 지정한다.

또한, extension을 구현할 플랫폼에서 Authenticator에게 보낼 것으로 예상되는 authenticator argument 를 지정할 수 있으며 authenticator argument 는 byte 문자열이다.

참고
extension은 저전력 블루투스나 NFC와 같은 낮은 대역폭을 가진 기기에서도 동작하기 위해 최대한 적은 Authenticator argument를 정의하도록 노력해야 한다.

참고
extension 중 몇몇 extension은 특정 매개변수를 정의할 필요가 없지만, client argument 는 무조건 정의해 주어야 하는데 이런 경우의 매개변수 값은 상수 true로 정의해주면 좋다.

추가적인 authenticator 처리만 하는 extension인 경우엔 플랫폼이 어떤 extension인지 알 필요가 없도록 처리해야 하며, 이를 지원하기 위해 플랫폼은 동일한 extension identifier에서 알수없는 extension은 authenticator argument 로 전달하여야 한다.

authenticator argumentclient argument 를 CBOR 구조로 인코딩한 결과여야 한다.

참고 RFC 7049 Section 4.2 - Converting from JSON to CBOR

클라이언트는 client argument 가 CBOR 구조로 인코딩 될 수 없는 extension 인 경우 자동으로 삭제처리해야 한다.

Extending client processing

확장된 클라이언트 처리를 알아보자.

extension은 credential이나 assertion을 생성하는 동안 client platform에 추가적인 처리 요구사항을 정의하여 전달할 수 있다.

Relying Party가 클라이언트의 처리 여부를 확인하기 위해서 extension은 clientData 구조에 포함될 데이터값을 지정해야 하며, 지정된 값은 Relying Party가 알아야하는 결과값을 처리하는 경우에도 사용된다.

이 clientData 구조에 들어가는 값들은 JSON으로 인코딩할 수 있는 값일 수 있다. 클라이언트에 의해 처리된 extension이 JSON으로 인코딩할 수 있는 값들로 정의되는 경우, 클라이언트는 keyData와 함께 clientData에 dictionary를 포함시켜야 한다.

클라이언트는 이 extension에 대해 extension identifier를 key로 사용하여 client data의 값을 사전에 추가해야 한다.

Extending authenticator processing with signature extensions

Signature의 extension으로 Authenticator 처리를 확장하는 방법도 있다.

추가적인 Authenticator 처리를 위해 정의되는 Signature의 extension은 Authenticator 데이터값과 유사하게 정의되어야 한다.

이 값들은 CBOR 값으로 인코딩 될 수 있는 모든 데이터일 수도 있으며 이 값을 정의하는 Signature extension을 처리하는 Authenticator는 반드시 authenticatorData 에 포함되어야 한다.

As specified in 4. Authenticator data, the authenticator data value of each processed extension is included in the extended data part of the authenticatorData. This part is a CBOR map, with extension identifiers as keys, and the authenticator data value of each extension as the value.

Authenticator 데이터에 지정된 대로 처리된 각 extension의 Authenticator 데이터값은 authenticatorData 의 확장된 데이터 부분에 포함된다.

추가적으로 포함된 이 부분은 extension identifier가 key이고 각 extension의 authenticator 데이터가 값인 CBOR Map 형태로 되어 있다.

Example extension

extension의 예시들을 알아보자.

아래 나오는 예시들은 말 그대로 예시일 뿐 꼭 이대로 제공하라고 강제되지 않는다. 즉 규범이 아니므로 예시로 받아들여야 한다.

위에서 설명한 요구사항들을 확장된 Geo 를 가정해보도록 하자.

여기서 Geo 는 클라이언트와 authenticator 모두 지리적 위치를 Signature에 포함시킬 수 있다고 가정하자.

위의 Geo 확장을 구별할 수 있는 extension identifier는 com.example.fido.geo 로 가정하고 client argument는 상수 true로 지정되어 있다.

상수 true로 지정한 이유는 Geo 확장에서 Relying Party가 extension에 대한 정보의 사용을 요청하는 것 이외에 특정한 정보를 클라이언트로 전달할 필요가 없다고 가정했기 때문이다.

Relying Party는 assertion 요청에서 위의 값들을 설정한다.

아래 예시 코드를 보자.

id:"j53pu9z6"}
1
2
3
4
var assertionPromise =
credentials.getAssertion("SGFuIFNvbG8gc2hvdCBmaXJzdC4",
{}, /* Empty filter */
{ 'com.example.fido.geo': true });

위의 extension은 추가 클라이언트 데이터를 위치데이터를 뜻하는 GeoJSON 지점으로 정의한다.

따라서 클라이언트는 아래와 같은 데이터를 생산하게 된다.

The extension defines the additional client data to be the client’s location, if known, as a GeoJSON [GeoJSON] point. The client constructs the following client data:

이 확장은 추가 클라이언트 데이터를 클라이언트의 위치 (알려진 경우)로 GeoJSON [GeoJSON] 지점으로 정의합니다. 클라이언트는 다음 클라이언트 데이터를 생성합니다.

참고 RFC 7946 - GeoJSON format

id:"j53puo2v"}
1
2
3
4
5
6
7
8
9
{
...,
'extensions': {
'com.example.fido.geo': {
'type': 'Point',
'coordinates': [65.059962, -13.993041]
}
}
}

extension은 클라이언트에게 authenticator argument 를 고정값 1로 설정하도록 요구해야 한다.

마지막으로 extension은 authenticator가 알려진 경우 authenticator data에 geolocation 값을 지정한다.

참고
위치 값을 CBOR로 인코딩된 부동 소수점의 배열로 인코딩한다.

authenticator는 authenticatorData 에 위의 값을 포함시킨 후 authenticator processing을 수행하여 아래와 같은 데이터가 나올 수 있다.

SSwKOJ4

참고 위의 표기법은 RFC 7049에 정의되어 있다.