Характеристики

Сервис быстрого подключения

У поставщика быстрого подключения должен быть следующий сервис GATT.

Сервис UUID
Сервис быстрого подключения 0xFE2C

Этот сервис должен иметь следующие характеристики.

Характеристика сервиса быстрого подключения Зашифровано Разрешения UUID
Идентификатор модели Нет Чтение FE2C1233-8366-4814-8EB0-01DE32100BEA
Подключение на основе ключа Нет Написать и уведомить FE2C1234-8366-4814-8EB0-01DE32100BEA
Ключ доступа Нет Написать и отправить уведомление FE2C1235-8366-4814-8EB0-01DE32100BEA
Ключ аккаунта Нет Запись FE2C1236-8366-4814-8EB0-01DE32100BEA

Сервис информации об устройстве

Поставщик услуг быстрого подключения также должен поддерживать сервис информации об устройстве.

Сервис UUID
Сервис информации об устройстве 0x180A

Устройство, выполняющее поиск, использует следующие характеристики.

Название Зашифровано Разрешения UUID
Версия встроенного ПО Нет Чтение 0x2A26

Характеристика: идентификатор модели

Эта характеристика позволяет Искателю считывать идентификатор модели по мере необходимости, а не только когда устройство передает данные в режиме обнаружения. Он всегда должен возвращать следующие данные:

Октет Тип данных Описание Значение
0–2 uint24 Идентификатор модели изменяется

Характеристика: сопоставление на основе ключа

Эта характеристика управляет процедурой подключения на основе ключа. В этой процедуре определенный уровень доверия устанавливается путем проверки того, что и Искатель, и Поставщик владеют общим ключом. В каждом случае ключ будет разным:

  • Случай 1. Предварительно заданный ключ основан на паре открытого и закрытого ключей для защиты от спуфинга и собственной паре открытого и закрытого ключей искателя, которая будет меняться при каждой попытке подключения.

    • Поставщик находится в режиме подключения.
    • Запрашивающая сторона проверяет, есть ли у Поставщика закрытый ключ для защиты от спуфинга.

    Обратите внимание, что в режиме подключения поставщик может также подключаться обычным способом, например к устройству, которое не поддерживает быстрое подключение на основе ключей.

  • Вариант 2. Общий ключ – это один из ключей аккаунта.

    • Поставщик обычно не находится в режиме подключения. (Но это не является обязательным требованием. Поставщик должен поддерживать использование ключа аккаунта даже в режиме подключения.)
    • Искатель и Поставщик проверяют, что у каждого из них есть ключ аккаунта.

Поскольку оба случая очень похожи, за исключением того, какой общий ключ используется, они объединены в процедуру.

Формат данных

Инструкции по использованию каждого формата.

Октет Тип данных Описание Значение Обязательно?
0–15 uint128 Зашифрованный запрос изменяется Обязательно
16–79 Открытый ключ изменяется Необязательно

Таблица 1.1. Зашифрованный запрос, записанный в характеристику искателем.

Октет Тип данных Описание Значение Обязательно?
0 uint8 Тип сообщения 0x00 – запрос на подключение на основе ключа. Обязательно
1 uint8 Flags
  • Бит 0 (MSB): устарел и игнорируется Seeker.
  • Бит 1: 1, если Искатель запрашивает у Поставщика инициировать связывание, и этот запрос содержит адрес BR/EDR Искателя. В противном случае возвращается значение 0.
  • Бит 2: 1, если Искатель запрашивает у Поставщика уведомление о существующем названии. В противном случае возвращается значение 0.
  • Бит 3: 1, если это ретроактивная запись ключа аккаунта. В противном случае возвращается значение 0.
  • Биты 4–7 зарезервированы для использования в будущем и должны игнорироваться.
varies Обязательно
2–7 uint48 Один из вариантов:
  • Текущий BLE-адрес поставщика
  • Общедоступный адрес поставщика
varies Обязательно
8–13 uint48 Адрес BR/EDR искателя varies Присутствует, только если установлен бит 1 или 3 в поле Flags
n – 15 Случайное значение (соль) varies Обязательно

Таблица 1.2.1. Необработанный запрос (тип 0x00). расшифрованные из зашифрованного запроса в таблице 1.1.

Октет Тип данных Описание Значение Обязательно?
0 uint8 Тип сообщения 0x10 = запрос действия Обязательно
1 uint8 Flags varies Обязательно
2–7 uint48 Один из вариантов:
  • Текущий BLE-адрес поставщика
  • Общедоступный адрес поставщика
varies Обязательно
8 uint8 Групповой чат varies Обязательный, если установлен флаг Bit 0
9 uint8 Код сообщения varies Обязательно, если установлен бит 0 флагов.
10 uint8 Зависит от флагов:
  • Бит 0 установлен: длина дополнительных данных меньше 6
  • Бит 1: идентификатор данных.
varies Обязательно, если установлен бит 0 или 1 флага.
11 – n Дополнительные данные varies Необязательно
n – 15 Случайное значение (соль) varies Обязательно

Таблица 1.2.2. Необработанный запрос (тип 0x10). расшифрованные данные из зашифрованного запроса, указанного в таблице 1.1.

Октет Тип данных Описание Значение
0 uint8 Тип сообщения 0x01 – ответ на запрос о подключении на основе ключа.
1–6 uint48 Общедоступный адрес поставщика (BR/EDR) varies
7–15 Случайное значение (соль) varies

Таблица 1.3. Необработанный ответ. Зашифрованный ответ, который должен быть создан в соответствии с таблицей 1.4.

Октет Тип данных Описание Значение
0–15 uint128 Зашифрованный ответ varies

Таблица 1.4. Зашифрованный ответ, отправленный Поставщиком Искателю через уведомление.

Характеристика: ключ доступа

Эта характеристика используется во время установления связи на основе ключа.

Октет Тип данных Описание Значение
0–15 uint128 Зашифрованный блок ключа доступа varies

Таблица 2.1. Блок зашифрованного ключа доступа. Инструкции по использованию приведены в разделе Подключение на основе ключа.

Октет Тип данных Описание Значение
0 uint8 Тип сообщения Один из вариантов:
  • 0x02 = ключ доступа Искателя
  • 0x03 – ключ доступа поставщика.
1–3 unit32 6-значный ключ доступа varies
4–15 Случайное значение (соль) varies

Таблица 2.2. Блок необработанных ключей доступа. Расшифрованная версия таблицы 2.1.

Характеристика: ключ аккаунта

После подключения искатель быстрого подключения запишет ключ аккаунта в поставщик быстрого подключения.

Октет Тип данных Описание Значение
0–15 uint128 Ключ аккаунта (зашифрованный) varies

При получении запроса на запись поставщик быстрого подключения должен выполнить следующие действия:

  1. Расшифруйте ключ аккаунта, используя секретный ключ, созданный на шаге 4 процедуры.
    • Для поставщиков, которым требуется страхование ответственности (распространенный случай):
      • Перед расшифровкой убедитесь, что для расшифровки запроса ключа доступа из шага 12 использовался общий секрет. Если этот шаг не пройден с использованием этого секрета, проигнорируйте запись и выйдите.
    • На этом этапе общий секрет (K в процедуре) больше не будет использоваться для этой пары. Все запросы, зашифрованные этим ключом, должны отклоняться без перезапуска процедуры.
  2. Убедитесь, что расшифрованное значение начинается с 0x04 или 0xFF. Если нет, проигнорируйте эту запись и выйдите.
    • Если значение равно 0x04:
      • Проверьте, есть ли в сохраненном списке ключей аккаунта место для нового значения.
      • Если нет, удалите из списка значение, которое использовалось раньше всех.
      • Добавьте в список новое значение.
    • Если значение равно 0xFF:
      • Рассматривайте это как временный сеанс подключения и не выполняйте никаких действий.
      • Это может произойти при ретроактивной записи ключа аккаунта.
      • Не храните ключ и не используйте его в списке ключей аккаунта, для шифрования или вычисления MAC.
      • Удаление связи запускается событием, относящимся к определенной функции, или по истечении времени ожидания. При использовании функции передачи аудио LE настоятельно рекомендуется удалить связь BLE и ключ связи через 10 минут после отключения временного сеанса.

Ключи аккаунта из списка используются при создании пары на основе ключа.

Характеристика: версия встроенного ПО

Эта характеристика позволяет устройству Seeker при необходимости считывать версию встроенного ПО устройства Provider. Он должен возвращать следующие данные:

Октет Тип данных Описание Значение
0 – var utf8s Код версии встроенного ПО varies

Она должна быть представлена в виде одной строки UTF-8, даже если у Поставщика несколько встроенных ПО (например, три встроенных ПО для левого наушника, правого наушника и чехла). Поставщик также может возвращать определенные строки для особых случаев:

  1. status-updating – если поставщик в данный момент обновляет встроенное ПО. В качестве альтернативы поставщик может вернуть версию подготовленной прошивки.

  2. status-abnormal – если поставщик находится в аномальном состоянии. Например, он неисправен, потому что не удалось обновить встроенное ПО. В этом случае Seeker покажет сообщение о том, что его нужно обновить.

Поставщик должен ограничить доступ к характеристике "Версия прошивки", чтобы предотвратить отслеживание устройства. Рекомендуемые ограничения:

  • У связанных устройств должен быть доступ в любое время.
  • любое устройство должно иметь доступ, когда поставщик виден;

Если поставщик поддерживает функцию "Найти на канале", необходимо выполнить дополнительные действия. Подробнее об обновлениях встроенного ПО Портала поиска…

Характеристика: дополнительные данные

Этот сервис должен иметь следующие характеристики.

Характеристика сервиса быстрого подключения Зашифровано Разрешения UUID
Данные Нет Написать и уведомить FE2C1237-8366-4814-8EB0-01DE32100BEA
Старая характеристика сервиса быстрого подключения (планируется прекратить поддержку 1 января 2021 г.) Зашифровано Разрешения UUID
Данные Нет Написать и уведомить 0x1237

Прежде чем записывать или уведомлять об этой характеристике, необходимо выполнить рукопожатие через характеристику FE2C1234-8366-4814-8EB0-01DE32100BEA, чтобы получить общий секретный ключ. Для шифрования данных, передаваемых через эту характеристику, будет использоваться алгоритм AES-CTR, описанный ниже. Этот режим обеспечивает более высокий уровень безопасности для данных, размер которых превышает один 16-байтовый блок. Для обеспечения целостности данных будет использоваться алгоритм HMAC-SHA256.

Октет Описание Значение
0–7 Первые 8 байт HMAC-SHA256. varies
8–15 Nonce, используемый при шифровании AES-CTR. varies
16 – var Зашифрованные данные. varies

Таблица 3.1. Пакет данных, отправленный Поставщиком Искателю с помощью уведомления или отправленный Искателем Поставщику с помощью записи.

Октет Тип данных Описание Значение
0 – var byte array Данные varies, декодируйте его в соответствии с идентификатором данных из таблицы 1.2.2:
  • 0x01(персонализированное название): utf8s

Таблица 3.2. Необработанные данные. Расшифровано из зашифрованных данных в таблице 3.1.

Когда запрашивается уведомление (например, запрос персонализированного имени через бит 2 в таблице 1.2.1), поставщик Быстрого подключения должен выполнить следующие действия:

  1. Сгенерируйте криптографически случайные 8 байт для одноразового кода.
  2. Зашифруйте данные с помощью AES-CTR, где каждый 16-байтовый блок генерируется с помощью

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

    где

    1. Ключ AES – это общий секретный ключ, полученный на шаге 4 процедуры.
    2. clearBlock[i] – это 16-байтный блок, начинающийся с data[i * 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-byte ZEROs), где shared_secret – это секретный ключ, полученный на шаге 4 процедуры.
    2. opad – внешнее дополнение размером 64 байта, состоящее из повторяющихся байтов со значением 0x5C.
    3. ipad – это внутренний отступ размером 64 байта, состоящий из повторяющихся байтов со значением 0x36.
  5. Возьмите первые 8 байт из HMAC-SHA256 в качестве префикса пакета данных.

При получении запроса на запись поставщик быстрого подключения должен выполнить следующие действия:

  1. Проверьте целостность данных, используя первые 8 байт HMAC-SHA256.
  2. Расшифруйте зашифрованные данные с помощью алгоритма AES-CTR, где каждый блок генерируется с помощью

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

    где

    1. encryptedBlock[i] – это 16-байтный блок, начинающийся с encrypted_data[i * 16]. Последний блок может быть меньше 16 байтов.
    2. Ключ AES генерируется или определяется на основе рукопожатия, например:
      1. В первом варианте он получен по протоколу ECDH и больше не будет использоваться для этого подключения. Все запросы, зашифрованные с помощью этого ключа без перезапуска процедуры, должны быть отклонены.
      2. в процессе именования 2 – ключ аккаунта.
  3. Выполните concat(clearBlock[0], clearBlock[1],...), чтобы создать необработанные данные.