Оптимизируйте свои подборки
Сохраняйте и классифицируйте контент в соответствии со своими настройками.
Процедура быстрого сопряжения
Процедура
Вместо немедленного вызова любой из обычных процедур связывания BR/EDR или BLE, Seeker сначала включает уведомления о характеристике сопряжения на основе ключей, а затем записывает в него данные из таблицы 1.1 .
При обработке запроса на запись от искателя быстрого соединения поставщик быстрого соединения должен сделать следующее:
Если присутствует необязательное поле открытого ключа:
Если устройство не находится в режиме сопряжения, проигнорируйте запись и выйдите.
В противном случае:
Используйте полученный открытый ключ (64-байтовую точку на эллиптической кривой secp256r1), предустановленный закрытый ключ защиты от спуфинга — также secp256r1 и алгоритм Эллиптической кривой Диффи-Хеллмана для генерации 256-битного ключа AES.
Используйте SHA-256 для хеширования 256-битного ключа AES.
Возьмите первые 128 бит результата. Это ключ AES защиты от спуфинга, который будет использоваться на следующем этапе.
Используя AES-128, попытайтесь расшифровать значение. Поскольку значение представляет собой один 16-байтовый блок AES, режим IV или многоблочного шифрования не требуется.
Какой ключ использовать:
Если ключ AES защиты от спуфинга был создан на шаге 1, используйте этот ключ.
В противном случае попробуйте каждый ключ в сохраненном списке ключей учетной записи.
Если ключ успешно расшифровывает значение, прервите его и перейдите к следующему шагу.
Значение расшифровывается успешно, если выходные данные соответствуют формату в таблице 1.2.1 или таблице 1.2.2 (то есть, если они содержат либо текущий адрес BLE поставщика быстрого соединения, либо публичный адрес поставщика быстрого соединения).
ПРИМЕЧАНИЕ. В конце упаковки прикреплена соль. Когда это возможно, эти соли следует отслеживать, и если поставщик получает запрос, содержащий уже использованную соль, этот запрос следует игнорировать, чтобы предотвратить атаки повторного воспроизведения.
В качестве альтернативы отслеживанию солей, если запись включает в себя частный адрес поставщика, другой способ предотвратить атаки повторного воспроизведения — перенести время следующей разрешимой ротации частного адреса, чтобы ротация произошла до того, как будет выполнена следующая запись спаривания на основе ключей. принял.
Если ни один ключ не может успешно расшифровать значение, проигнорируйте запись и выйдите.
Ведите подсчет этих неудач. Когда количество ошибок достигнет 10, немедленно отклоняйте все новые запросы. Сбросьте счетчик ошибок через 5 минут, после включения питания или после успешного завершения.
В противном случае сохраните успешный ключ как K. Отметьте этот K как пригодный для расшифровки записей пароля и персонализированного имени, полученных по этой ссылке LE, но не для других записей или записей по любой другой ссылке. Запустите таймер, чтобы сбросить K через 10 секунд, если соединение не было начато. Также отбросьте K , если этот канал LE отключится.
Создайте 16-байтовый необработанный ответ, показанный в таблице 1.3 , путем объединения типа и адреса BR/EDR поставщика, а затем заполнения оставшейся части пакета блоком случайных байтов (то есть солью).
Зашифруйте необработанный ответ с помощью K, чтобы получить 16-байтовый зашифрованный ответ, показанный в таблице 1.4 . Отправьте это через уведомление о характеристике сопряжения на основе ключей.
Это указывает на то, что Искатель запрашивает Поставщика инициировать соединение с адресом BR/EDR Искателя, который присутствует в байтах 8–13.
Отправьте запрос на сопряжение на адрес BR/EDR Искателя. Запрос на сопряжение должен быть таким, как описано ниже (шаг «Во время сопряжения»).
Причина, по которой это необходимо: инициирование поставщиком позволяет обойти проблему на некоторых устройствах.
Если в байте флагов запроса бит 1 установлен в 0:
Подождите до 10 секунд для запроса на сопряжение. Если ничего не получено, выйдите.
Обратите внимание, что это может быть запрос BR/EDR с другого адреса (публичный адрес Искателя вместо его разрешаемого частного адреса). Во время сопряжения мы повторно проверим, что запрашивающее устройство владеет K .
Во время сопряжения:
При получении пакета запроса/ответа на сопряжение от Seeker: Если в запросе указаны возможности устройства NoInput/NoOutput, завершите сопряжение, чтобы избежать использования метода сопряжения Just Works.
Для пакета запроса/ответа на сопряжение, отправленного поставщиком: установите в поле «Возможности устройства» значение «Отображение/ДаНет» и установите для параметра «Требования аутентификации» значение «Требуется защита MITM» . Это активирует метод сопряжения числового сравнения (также известный как подтверждение пароля на Android). Мы полагаемся на это, чтобы подтвердить, что запрашивающее устройство на самом деле является устройством поиска быстрой пары и что посредника нет. См. примеры .
Причина, по которой это необходимо: метод внеполосного сопряжения подойдет лучше, но платформа не предоставляет его на всех желаемых версиях Android.
Обычно при использовании этого метода сопряжения пользователь должен подтвердить, что ключи доступа, отображаемые на экране каждого устройства, идентичны. Вместо этого, только для этого соединения, мы передаем их через BLE, зашифровав их доверенным предварительным ключом.
Обратите внимание, что этот подход не следует применять для устройств с экраном или клавиатурой, поскольку он несколько снижает защиту MITM. По этой причине Fast Pair в настоящее время не поддерживает эти типы устройств.
Если 10-секундный таймер истекает без записи ключа доступа, отбросьте K .
Когда значение записывается в характеристику ключа доступа , это зашифрованный блок ключа доступа. Расшифруйте его с помощью K, чтобы получить необработанный блок ключа доступа в формате, показанном в разделе «Характеристика: Ключ доступа»>Таблица 2.2 — (тип = Ключ доступа Искателя).
Если расшифровка не удалась, игнорируйте запись и отбрасывайте K.
В противном случае блок необработанного ключа доступа содержит 6-значный ключ доступа P Seeker , который является ключом доступа, который ожидает Seeker.
Сравните P Seeker с нашим ожидаемым ключом доступа P Provider .
Если значения равны, ответьте «да» на подтверждение.
В противном случае ответьте «нет» на подтверждение, что приведет к сбою сопряжения.
Независимо от того, не удалось ли сопряжение, создайте еще один блок необработанного ключа доступа в формате, показанном в разделе «Характеристика: Ключ доступа»>Таблица 2.2 , содержащий наш собственный ожидаемый ключ доступа P Provider .
Убедитесь, что блок имеет правильный тип (пароль провайдера; см. таблицу). ПРИМЕЧАНИЕ. Не используйте повторно соль из блока ключа, полученного от Искателя. Создайте новое случайное значение.
Зашифруйте необработанный блок ключа с помощью K и отправьте полученный зашифрованный блок ключа через уведомление о характеристике ключа доступа.
Если Искатель получит и расшифровает правильный ключ доступа P , Искатель также ответит «да» на подтверждение, и соединение будет успешным.
Если сопряжение прошло успешно, отметьте K как пригодный для расшифровки записи ключа учетной записи по этой ссылке LE, но не для любой последующей записи пароля или записи по любой другой ссылке. Запустите таймер, чтобы сбросить K через 10 секунд. Также отбрасывайте K после любой попытки записать ключ учетной записи и, как указано в шаге 4, если связь LE отключается.
Если спаривание не удалось, отбросьте K.
Переключите поле возможностей устройства обратно на возможности ввода-вывода по умолчанию, а требования аутентификации — на значение по умолчанию, чтобы новые пары продолжались должным образом.
Обратите внимание, что для Провайдеров, которым не требуется связывание, Искатель не отправляет Поставщику запрос на сопряжение, то есть шаги 8–17 пропускаются. Кроме того, «К» используется в характеристике «Ключ счета» .
Примеры
Пример 1: Успешная попытка спаривания (без посредника).Пример 2: Неудачная попытка соединения с посредником.
[null,null,["Последнее обновление: 2025-08-13 UTC."],[[["\u003cp\u003eFast Pair utilizes BLE for initial key exchange and then triggers BR/EDR pairing for secure connection.\u003c/p\u003e\n"],["\u003cp\u003eThe Provider verifies the Seeker's authenticity using encryption, a shared secret, and a numeric comparison pairing method.\u003c/p\u003e\n"],["\u003cp\u003eAccount Keys are exchanged securely after successful pairing to enable seamless future connections.\u003c/p\u003e\n"],["\u003cp\u003eThe process includes anti-spoofing measures like public key cryptography and salt tracking to enhance security.\u003c/p\u003e\n"],["\u003cp\u003eThe Provider initiates the BR/EDR pairing to address compatibility issues with certain devices.\u003c/p\u003e\n"]]],[],null,["Fast Pair Procedure\n-------------------\n\n### Procedure\n\n| **Note:** Google recommends implementing the [Cryptographic Test Cases](/nearby/fast-pair/specifications/appendix/cryptotestcases \"Link to the Cryptographic Test Cases.\") to ease verification of these requirements.\n\nInstead of immediately invoking any of the normal BR/EDR or BLE bonding\nprocedures, the Seeker first enables Notifications on the Key-based Pairing\ncharacteristic, and then writes the data in [Table 1.1](/nearby/fast-pair/specifications/characteristics#table1.1 \"table 1.1\") to it.\n\nWhen handling a write request from a Fast Pair Seeker, the Fast Pair Provider\nshall do the following:\n\n1. If the optional Public Key field **is present** :\n 1. If the device is not in pairing mode, ignore the write and exit.\n 2. Otherwise:\n 1. Use the received Public Key (a 64-byte point on the secp256r1 elliptic curve), the pre-installed [Anti-Spoofing Private Key](/nearby/fast-pair/specifications/configuration#antispoofing \"Anti-Spoofing\") - also secp256r1, and the Elliptic-Curve Diffie-Hellman algorithm to generate a 256-bit AES key.\n 2. Use SHA-256 to hash the 256-bit AES key.\n 3. Take the first 128 bits of the result. This is the Anti-Spoofing AES Key, used in the next step.\n2. Using AES-128, attempt to decrypt the value. Since the value is a single\n 16-byte AES block, no IV or multi-block cipher mode is necessary.\n\n 1. Which key to use:\n 1. If an Anti-Spoofing AES Key was generated in step 1, use that key.\n 2. Otherwise, try each key in the persisted Account Key List.\n 2. If a key successfully decrypts the value, break, and continue to the next step.\n 3. The value is decrypted successfully if the output matches the format in\n [Table 1.2.1](/nearby/fast-pair/specifications/characteristics#table1.2.1 \"table 1.2.1\") or [Table 1.2.2](/nearby/fast-pair/specifications/characteristics#table1.2.2 \"table 1.2.2\") - (that is, if it\n contains either the Fast Pair Provider's current BLE address, or the Fast\n Pair Provider's public address).\n\n NOTE: At the end of the packet there is a salt attached. When\n possible, these salts should be tracked, and if the Provider receives a\n request containing an already used salt, the request should be ignored to\n prevent replay attacks.\n 4. As an alternative to tracking salts, if the write includes the Provider's\n private address, another way to prevent replay attacks is to bring\n forward the time of the next resolvable private address rotation so that\n the rotation occurs before the next Key-based Pairing write will be\n accepted.\n\n3. If no key could successfully decrypt the value, ignore the write and exit.\n\n 1. Keep a count of these failures. **When the failure count hits 10, fail\n all new requests immediately. Reset the failure count after 5 minutes,\n after power on, or after a success.**\n4. Otherwise, save the successful key as *K* . Mark this *K* as usable for\n decrypting Passkey and Personalized name writes received on this LE link, but\n not other writes nor any writes on any other link. Start a timer to discard\n *K* after 10 seconds if pairing has not been started. Also discard *K* if\n this LE link disconnects.\n\n5. Produce the 16-byte Raw Response shown in [Table 1.3](/nearby/fast-pair/specifications/characteristics#table1.3 \"table 1.3\"), by\n concatenating the type and the Provider's BR/EDR address, and then filling\n the remainder of the packet with a block of random bytes (that is, a salt).\n\n6. Encrypt the Raw Response with K to produce the 16-byte Encrypted Response\n shown in [Table 1.4](/nearby/fast-pair/specifications/characteristics#table1.4 \"table 1.4\"). Send this via a notify on the Key-based Pairing\n characteristic.\n\n7. Read the request flag:\n\n 1. **If the Request's Flags byte has bit 2 set to 1** , notify [Additional Data characteristic](/nearby/fast-pair/specifications/characteristics#AdditionalData \"Characteristic - Additional Data\") with personalized name.\n 2. **If the Request's Flags byte has bit 1 set to 1:**\n 1. This indicates that the Seeker is requesting the Provider to initiate bonding to the Seeker's BR/EDR address, which is present in bytes 8-13.\n 2. Send a pairing request to the Seeker's BR/EDR address. The pairing request must be as described below (\"During pairing\" step).\n 3. Reason this is needed: Having the Provider initiate works around an issue on some devices.\n 3. **If the Request's Flags byte has bit 1 set to 0:**\n 1. Wait up to 10 seconds for a pairing request. If none is received, exit.\n 2. Note that this might be a BR/EDR request, from a different address (the Seeker's public address, instead of its resolvable private address). We will re-verify during pairing that the requesting device is in possession of *K*.\n8. During pairing:\n\n 1. When a **pairing request/response packet** is received from the Seeker: If the Device Capabilities in the request are NoInput/NoOutput, end pairing, to avoid using the Just Works pairing method.\n 2. For the pairing request/response packet sent by the Provider: Set the Device Capabilities field to **Display/YesNo** and set Authentication Requirements to **MITM Protection Required** . This triggers the Numeric Comparison pairing method (also known as [Passkey Confirmation](https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#PAIRING_VARIANT_PASSKEY_CONFIRMATION) on Android). We rely on this to confirm that the requesting device is in fact the Fast Pair Seeker, and that there is no man-in-the-middle. See [examples](#ProcedureExamples).\n 3. Reason this is needed: The Out-of-Band pairing method would be a better fit, but the platform does not expose it on all desired versions of Android.\n9. When **confirmation of the passkey is needed** , wait up to 10 seconds for a\n write to the [Passkey characteristic](/nearby/fast-pair/specifications/characteristics#Passkey \"passkey\").\n\n 1. Normally, with this pairing method, the user would confirm that the passkeys displayed on each device's screen are identical. Instead, only for this pairing, we transfer them over BLE, encrypted with the trusted pre-shared key.\n 2. Note that this approach should not be taken for devices that have a screen or a keyboard as it makes a slight compromise on MITM protection. Fast Pair currently does not support those device types yet because of this.\n 3. If the 10 second timer expires without a passkey being written, then discard *K*.\n10. When a **value is written to the Passkey characteristic** , this is the\n Encrypted Passkey Block. Decrypt it with K to yield a Raw Passkey Block, with\n format shown in [Characteristic: Passkey](/nearby/fast-pair/specifications/characteristics#Passkey \"passkey\") *\\\u003e* [Table 2.2](/nearby/fast-pair/specifications/characteristics#table2.2 \"table 2.2\") - (type =\n Seeker's Passkey).\n\n11. If decryption fails, ignore the write and discard *K*.\n\n12. Otherwise, the Raw Passkey Block contains a 6-digit passkey\n *P~Seeker~*, which is the passkey that the Seeker expects.\n\n13. Compare *P~Seeker~* with our own expected passkey,\n *P~Provider~*.\n\n 1. If the values are equal, reply \"yes\" to the confirmation.\n 2. Otherwise, reply \"no\" to the confirmation, causing pairing to fail.\n14. Regardless of whether pairing failed, produce another Raw Passkey Block, with\n format shown in [Characteristic: Passkey](/nearby/fast-pair/specifications/characteristics#Passkey \"passkey\") *\\\u003e* [Table 2.2](/nearby/fast-pair/specifications/characteristics#table2.2 \"table 2.2\"),\n containing our own expected passkey, *P~Provider~*.\n\n 1. Ensure the block has the correct type (Provider's Passkey; see table). NOTE: Do not reuse the salt from the Passkey Block received from the Seeker. Generate a new random value.\n15. Encrypt the Raw Passkey Block with *K*, and send the resulting Encrypted\n Passkey Block via a notify on the Passkey characteristic.\n\n16. If the Seeker receives and decrypts the correct passkey *P*, the Seeker will\n also reply \"yes\" to the confirmation, and pairing will succeed.\n\n 1. If the pairing succeeds, then mark *K* as usable for decrypting Account Key writes on this LE link, but not for any subsequent Passkey writes nor any writes on any other link. Start a timer to discard *K* after 10 seconds. Also discard *K* following any attempt to write an Account Key and, as per step 4, if the LE link disconnects.\n 2. If the pairing fails, discard *K*.\n17. Switch the device capabilities field back to default I/O capabilities and\n Authentication Requirements to default so that new\n pairings continue as expected.\n\nNote that for Providers that don't require bonding, the Seeker does not send a\npairing request to the Provider, that is step 8 - step 17 are skipped. Also,\n\"K\" is used in [Account Key characteristic](/nearby/fast-pair/specifications/characteristics#AccountKey \"Account Key\").\n\n##### Examples\n\n***Example 1:** Successful pairing attempt\n(no man-in-the-middle).* ***Example 2:** Failed pairing attempt, with a\nman-in-the-middle.*"]]