특성

빠른 페어링 서비스

빠른 페어링 제공자는 다음 GATT 서비스를 보유해야 합니다.

서비스 UUID
빠른 페어링 서비스 0xFE2C

이 서비스는 다음 특징을 가져야 합니다.

빠른 페어링 서비스 특성 암호화됨 권한 UUID
모델 ID 아니요 읽기 FE2C1233-8366-4814-8EB0-01DE32100BEA
키 기반 페어링 아니요 작성 및 알림 FE2C1234-8366-4814-8EB0-01DE32100BEA
패스키 아니요 작성 및 알림 FE2C1235-8366-4814-8EB0-01DE32100BEA
계정 키 아니요 쓰기 FE2C1236-8366-4814-8EB0-01DE32100BEA

기기 정보 서비스

빠른 페어링 제공자는 기기 정보 서비스도 지원해야 합니다.

서비스 UUID
기기 정보 서비스 0x180A

빠른 페어링 탐색기는 다음 특성을 사용합니다.

이름 암호화됨 권한 UUID
펌웨어 버전 아니요 읽기 0x2A26

특성: 모델 ID

이 특성을 사용하면 탐색기가 기기가 검색 가능 모드로 광고하는 경우를 제외하고 필요에 따라 모델 ID를 읽을 수 있습니다. 항상 다음 데이터를 반환해야 합니다.

옥텟 데이터 유형 설명 값
0~2 uint24 모델 ID 다양한 가격

특성: 키 기반 페어링

이 특성은 키 기반 페어링 절차를 제어합니다. 이 절차에서는 시커와 제공자가 모두 사전 공유 키를 보유하고 있는지 확인하여 특정 수준의 신뢰를 설정합니다. 각 사례에서 키가 다릅니다.

  • 케이스 1: 사전 공유 키는 스푸핑 방지 공개/비공개 키 쌍과 각 페어링 시도마다 변경되는 시커의 자체 공개/비공개 키 쌍을 기반으로 합니다.

    • 제공업체가 페어링 모드입니다.
    • 시커는 제공자가 스푸핑 방지 비공개 키를 보유하고 있는지 확인합니다.

    페어링 모드에 있는 경우 공급자는 빠른 페어링의 키 기반 페어링을 지원하지 않는 기기와 페어링하는 등 일반적인 방식으로 페어링할 수도 있습니다.

  • 케이스 2: 사전 공유 키가 계정 키 중 하나입니다.

    • 제공업체는 일반적으로 페어링 모드가 아닙니다. (하지만 이는 요구사항이 아닙니다. 제공업체는 페어링 모드에 있는 경우에도 계정 키 사용을 지원해야 합니다.)
    • 시커와 제공자는 서로 계정 키를 소유하고 있는지 확인합니다.

두 사례는 사용되는 사전 공유 키를 제외하고 매우 유사하므로 절차에서 결합됩니다.

데이터 형식

각 형식이 사용되는 방식은 절차를 참고하세요.

옥텟 데이터 유형 설명 값 필수 여부
0~15 uint128 암호화된 요청 다양한 가격 필수
16~79 공개 키 다양한 가격 선택사항

표 1.1: 암호화된 요청, 탐색기가 특성에 작성

옥텟 데이터 유형 설명 값 필수 여부
0 uint8 메시지 유형 0x00 = 키 기반 페어링 요청 필수
1 uint8 플래그
  • 비트 0 (MSB): 지원 중단되었으며 탐색기에서 무시됩니다.
  • 비트 1: 시커가 제공자가 결합을 시작하도록 요청하고 이 요청에 시커의 BR/EDR 주소가 포함된 경우 1입니다. 그 외의 경우 0
  • 비트 2: 탐색기가 공급자에게 기존 이름을 알리도록 요청하는 경우 1입니다. 그 외의 경우 0
  • 비트 3: 소급하여 계정 키를 쓰는 경우 1입니다. 그 외의 경우 0
  • 비트 4~7은 나중에 사용하기 위해 예약되어 있으며 무시해야 합니다.
다름 필수
2~7 uint48 다음 중 하나를 충족해야 합니다.
  • 제공자의 현재 BLE 주소
  • 제공업체의 공개 주소
다름 필수
8~13 uint48 탐색기의 BR/EDR 주소 다름 플래그 비트 1 또는 3이 설정된 경우에만 표시됩니다.
n - 15 임의 값 (솔트) 다름 필수

표 1.2.1: 원시 요청 (유형 0x00) 표 1.1의 암호화된 요청에서 복호화되었습니다.

옥텟 데이터 유형 설명 값 필수 여부
0 uint8 메시지 유형 0x10 = 작업 요청 필수
1 uint8 플래그
  • 비트 0 (MSB): 기기 작업인 경우 1, 그렇지 않은 경우 0
  • 비트 1: 추가 데이터 특성이 뒤따르는 경우 1, 그렇지 않은 경우 0
  • 비트 2~7은 나중에 사용하기 위해 예약되어 있으며 무시해야 합니다.
다름 필수
2~7 uint48 다음 중 하나를 충족해야 합니다.
  • 제공자의 현재 BLE 주소
  • 제공업체의 공개 주소
다름 필수
8 uint8 그룹에 메시지 보내기 다름 플래그 비트 0이 설정된 경우 필수
9 uint8 메시지 코드 다름 플래그 비트 0이 설정된 경우 필수
10 uint8 플래그에 따라 다름:
  • 비트 0이 설정됨: 추가 데이터 길이가 6 미만임
  • 비트 1이 설정됨: 데이터 ID
다름 플래그 비트 0 또는 1이 설정된 경우 필수
11 - n 추가 데이터 다름 선택사항
n - 15 임의 값 (솔트) 다름 필수

표 1.2.2: 원시 요청 (유형 0x10) 표 1.1의 암호화된 요청에서 복호화되었습니다.

옥텟 데이터 유형 설명 값
0 uint8 메시지 유형 0x01 = 키 기반 페어링 응답
1~6 uint48 제공업체의 공개 (BR/EDR) 주소 다름
7~15 임의 값 (솔트) 다름

표 1.3: 원시 응답 암호화되어 표 1.4에 암호화된 응답을 생성합니다.

옥텟 데이터 유형 설명 값
0~15 uint128 암호화된 응답 다름

표 1.4: 알림을 통해 제공자가 요청자에게 전송하는 암호화된 응답

특성: 패스키

이 특성은 키 기반 페어링 절차 중에 사용됩니다.

옥텟 데이터 유형 설명 값
0~15 uint128 암호화된 패스키 블록 다름

표 2.1: 암호화된 패스키 블록 사용에 관한 내용은 키 기반 페어링 절차를 참고하세요.

옥텟 데이터 유형 설명 값
0 uint8 메시지 유형 다음 중 하나:
  • 0x02 = Seeker's Passkey
  • 0x03 = 제공업체의 패스키
1~3 unit32 6자리 패스키 다름
4~15 임의 값 (솔트) 다름

표 2.2: 원시 패스키 블록 표 2.1의 복호화된 버전

특성: 계정 키

페어링 후 빠른 페어링 탐색기는 계정 키를 빠른 페어링 제공업체에 씁니다.

옥텟 데이터 유형 설명 값
0~15 uint128 계정 키 (암호화됨) 다름

쓰기 요청을 받으면 빠른 페어링 제공자는 다음을 실행해야 합니다.

  1. 절차의 4단계에서 생성된 공유 비밀번호를 사용하여 계정 키를 복호화합니다.
    • 결합이 필요한 제공업체 (일반적)의 경우:
      • 복호화하기 전에 공유 비밀번호가 12단계의 패스키 요청을 복호화하는 데 사용되었는지 확인합니다. 이 단계가 이 시크릿을 사용하여 통과되지 않은 경우 이 쓰기를 무시하고 종료합니다.
    • 이 시점에서 공유 비밀 (절차의 K)은 이 페어링에 다시 사용되지 않습니다. 절차를 다시 시작하지 않고 이 키로 암호화된 요청은 거부해야 합니다.
  2. 복호화된 값이 0x04 또는 0xFF로 시작하는지 확인합니다. 그렇지 않으면 이 쓰기를 무시하고 종료합니다.
    • 값이 0x04인 경우:
      • 영구 저장된 계정 키 목록에 새 값을 위한 공간이 있는지 확인합니다.
      • 그렇지 않으면 목록에서 가장 오래전에 사용된 값을 삭제합니다.
      • 목록에 새 값을 추가합니다.
    • 값이 0xFF인 경우:
      • 이를 임시 페어링 세션으로 처리하고 작업을 실행하지 않습니다.
      • 이 문제는 소급하여 계정 키 쓰기 흐름에서 발생할 수 있습니다.
      • 키를 저장하지 않고 계정 키 목록, 암호화 또는 MAC 계산에 사용하지 않습니다.
      • 결합 삭제는 기능별 이벤트 또는 시간 초과에 의해 트리거됩니다. LE 오디오 공유의 경우 임시 세션 연결이 해제된 후 10분 후에 BLE 결합 및 링크 키를 삭제하는 것이 좋습니다.

목록의 계정 키는 키 기반 페어링 중에 사용됩니다.

특성: 펌웨어 버전

이 특성을 통해 시커는 필요에 따라 제공자의 펌웨어 버전을 읽을 수 있습니다. 항상 다음 데이터를 반환해야 합니다.

옥텟 데이터 유형 설명 값
0 - var utf8s 펌웨어 버전 코드 다름

제공자에 펌웨어가 두 개 이상 (예: 왼쪽 이어폰, 오른쪽 이어폰, 케이스용 펌웨어 3개) 있는 경우에도 단일 utf8 문자열로 캡슐화해야 합니다. 공급자는 특수한 경우에 특정 문자열을 반환할 수도 있습니다.

  1. status-updating: 프로바이더가 현재 새 펌웨어로 업데이트하는 경우 또는 제공업체는 스테이징된 펌웨어 버전을 반환할 수 있습니다.

  2. status-abnormal: 제공업체가 비정상 상태인 경우 예를 들어 펌웨어 업데이트가 실패하여 오작동했습니다. 이 값은 시커가 사용자에게 지금 업데이트해야 한다는 메시지를 표시하도록 합니다.

제공자는 기기 추적을 방지하기 위해 펌웨어 버전 특성에 대한 액세스를 제한해야 합니다. 추천 제한사항:

  • 결합된 기기는 언제든지 액세스할 수 있어야 합니다.
  • 공급자를 검색할 수 있는 경우 모든 기기에서 액세스할 수 있어야 합니다.

특성: 추가 데이터

이 서비스는 다음과 같은 특징이 있어야 합니다.

빠른 페어링 서비스 특성 암호화됨 권한 UUID
데이터 아니요 작성 및 알림 FE2C1237-8366-4814-8EB0-01DE32100BEA
이전 빠른 페어링 서비스 특성 (2021년 1월 1일에 지원 중단 예정) 암호화됨 권한 UUID
데이터 아니요 작성 및 알림 0x1237

이 특성에 쓰거나 알리기 전에 특성 FE2C1234-8366-4814-8EB0-01DE32100BEA를 통해 핸드셰이크가 있어야 공유 비밀번호가 있습니다. AES-CTR은 이 특성을 통해 흐르는 데이터를 암호화하는 데 사용되며, 알고리즘은 아래에 정의되어 있습니다. 이 모드는 단일 16바이트 블록을 초과하는 데이터에서 더 안전합니다. 데이터 무결성을 보장하기 위해 HMAC-SHA256이 사용됩니다. 이는 아래에도 정의되어 있습니다.

옥텟 설명 값
0 - 7 HMAC-SHA256의 처음 8바이트입니다. 다름
8~15 AES-CTR 암호화에 사용되는 nonce입니다. 다름
16 - var 암호화된 데이터입니다. 다름

표 3.1: 알림을 통해 제공자가 탐색기에 전송하거나 쓰기를 통해 탐색기가 제공자에 전송하는 데이터 패킷

옥텟 데이터 유형 설명 값
0 - var byte array 데이터 다름인 경우 표 1.2.2의 데이터 ID에 따라 디코딩합니다.
  • 0x01(개인화된 이름): utf8s

표 3.2: 원시 데이터 표 3.1의 암호화된 데이터에서 복호화되었습니다.

알림이 요청되면 (예: 표 1.2.1의 비트 2를 통해 맞춤 이름 요청) 빠른 페어링 제공자는 다음을 실행해야 합니다.

  1. Nonce의 암호화 방식으로 무작위 8바이트를 생성합니다.
  2. AES-CTR을 사용하여 데이터를 암호화합니다. 여기서 각 16바이트 블록은 다음을 사용하여 생성됩니다.

    encryptedBlock[i] = clearBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))
    

    어디서

    1. AES 키는 절차의 4단계에 나오는 공유 비밀번호입니다.
    2. clearBlock[i] 는 data[i * 16]에서 시작하는 16바이트 블록입니다. 마지막 블록은 16바이트 미만일 수 있습니다.
  3. concat(encryptedBlock[0], encryptedBlock[1],…)을 실행하여 암호화된 데이터를 만듭니다.

  4. 다음과 같이 HMAC-SHA256을 생성합니다.

    sha256(concat((K ^ opad), sha256(concat((K ^ ipad), concat(nonce, encrypted_data)))))
    

    어디서

    1. K는 concat(shared_secret, 48바이트 0)으로 생성되고 shared_secret은 절차의 4단계에서 가져옵니다.
    2. opad는 64바이트 외부 패딩으로, 0x5C 값이 지정된 반복 바이트로 구성됩니다.
    3. ipad는 0x36 값이 반복되는 바이트로 구성된 64바이트 내부 패딩입니다.
  5. HMAC-SHA256에서 처음 8바이트를 데이터 패킷의 접두사로 사용합니다.

쓰기 요청을 받으면 빠른 페어링 제공자는 다음을 실행해야 합니다.

  1. HMAC-SHA256의 처음 8바이트를 확인하여 데이터의 무결성을 확인합니다.
  2. AES-CTR을 사용하여 암호화된 데이터를 복호화합니다. 각 블록은 다음을 사용하여 생성됩니다.

    clearBlock[i] = encryptedBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))
    

    어디서

    1. encryptedBlock[i] 는 encrypted_data[i * 16]에서 시작하는 16바이트 블록입니다. 마지막 블록은 16바이트 미만일 수 있습니다.
    2. AES 키는 핸드셰이크에서 생성되거나 식별됩니다(예:
      1. 명명 흐름 1에서는 ECDH에서 가져오며 이 페어링에 다시 사용되지 않습니다. 절차를 다시 시작하지 않고 이 키로 암호화된 요청은 거부해야 합니다.
      2. 이름 지정 흐름 2에서는 계정 키입니다.
  3. concat(clearBlock[0], clearBlock[1],…)을 실행하여 원시 데이터를 만듭니다.