Đặc điểm
Dịch vụ Ghép nối nhanh
Nhà cung cấp dịch vụ Ghép nối nhanh phải có dịch vụ GATT sau đây.
| Dịch vụ | mã nhận dạng duy nhất (UUID) |
|---|---|
| Dịch vụ Ghép nối nhanh | 0xFE2C |
Dịch vụ này phải có các đặc điểm sau.
| Đặc điểm của Dịch vụ Ghép nối nhanh | Đã mã hóa | Quyền | mã nhận dạng duy nhất (UUID) |
|---|---|---|---|
| Mã kiểu máy | Không | Đọc | FE2C1233-8366-4814-8EB0-01DE32100BEA |
| Ghép nối dựa trên khoá | Không | Viết và thông báo | FE2C1234-8366-4814-8EB0-01DE32100BEA |
| Khoá truy cập | Không | Viết và thông báo | FE2C1235-8366-4814-8EB0-01DE32100BEA |
| Khoá tài khoản | Không | Viết | FE2C1236-8366-4814-8EB0-01DE32100BEA |
Device Information Service
Nhà cung cấp dịch vụ Ghép nối nhanh cũng phải hỗ trợ Dịch vụ thông tin thiết bị.
| Dịch vụ | mã nhận dạng duy nhất (UUID) |
|---|---|
| Device Information Service | 0x180A |
Ghép nối nhanh Seeker sử dụng các đặc điểm sau.
| Tên | Đã mã hóa | Quyền | mã nhận dạng duy nhất (UUID) |
|---|---|---|---|
| Bản sửa đổi chương trình cơ sở | Không | Đọc | 0x2A26 |
Đặc điểm: Mã mẫu
Đặc điểm này cho phép Thiết bị tìm kiếm đọc mã nhận dạng mẫu khi cần, ngoài trường hợp thiết bị đang quảng cáo ở chế độ có thể phát hiện. Hàm này phải luôn trả về dữ liệu sau:
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0 – 2 | uint24 |
Mã kiểu máy | thay đổi |
Đặc điểm: Ghép nối dựa trên khoá
Đặc điểm này kiểm soát quy trình Ghép nối dựa trên khoá. Trong quy trình này, một mức độ tin cậy nhất định được thiết lập bằng cách xác minh rằng cả Thiết bị tìm kiếm và Nhà cung cấp đều sở hữu khoá được chia sẻ trước. Khoá sẽ khác nhau trong mỗi trường hợp:
Trường hợp 1: Khoá được chia sẻ trước dựa trên cặp khoá công khai/riêng tư chống giả mạo và cặp khoá công khai/riêng tư của chính Thiết bị tìm kiếm. Cặp khoá này sẽ thay đổi theo mỗi lần ghép nối.
- Nhà cung cấp đang ở chế độ ghép nối.
- Thiết bị tìm kiếm xác minh rằng Nhà cung cấp đang sở hữu khoá riêng tư chống giả mạo.
Xin lưu ý rằng khi ở chế độ ghép nối, tất nhiên, Nhà cung cấp cũng có thể ghép nối theo cách thông thường, chẳng hạn như ghép nối với một thiết bị không hỗ trợ tính năng Ghép nối dựa trên khoá của công nghệ Ghép nối nhanh.
Trường hợp 2: Khoá được chia sẻ trước là một trong các khoá tài khoản.
- Nhà cung cấp thường không ở chế độ ghép nối. (Nhưng đây không phải là yêu cầu bắt buộc – Nhà cung cấp phải hỗ trợ việc sử dụng khoá tài khoản ngay cả khi ở chế độ ghép nối.)
- Bên tìm kiếm và Bên cung cấp đều xác minh rằng bên kia đang sở hữu khoá tài khoản.
Vì cả hai trường hợp này đều cực kỳ giống nhau, ngoại trừ việc sử dụng khoá được chia sẻ trước, nên chúng được kết hợp trong quy trình.
Định dạng dữ liệu
Hãy xem quy trình để biết cách sử dụng từng định dạng.
| Octet | Loại dữ liệu | Mô tả | Giá trị | Bắt buộc? |
|---|---|---|---|---|
| 0 – 15 | uint128 |
Yêu cầu được mã hoá | thay đổi | Bắt buộc |
| 16 – 79 | Khóa công cộng | thay đổi | Không bắt buộc |
Bảng 1.1: Yêu cầu đã mã hoá, do Seeker ghi vào đặc điểm.
| Octet | Loại dữ liệu | Mô tả | Giá trị | Bắt buộc? |
|---|---|---|---|---|
| 0 | uint8 |
Loại thông báo | 0x00 = Yêu cầu ghép nối dựa trên khoá |
Bắt buộc |
| 1 | uint8 |
Cờ
|
thay đổi | Bắt buộc |
| 2 – 7 | uint48 |
Hoặc:
|
tuỳ thuộc | Bắt buộc |
| 8 – 13 | uint48 |
Địa chỉ BR/EDR của thiết bị tìm kiếm | tuỳ thuộc | Chỉ xuất hiện nếu bạn đặt Bit cờ 1 hoặc 3 |
| n – 15 | Giá trị ngẫu nhiên (salt) | tuỳ thuộc | Bắt buộc |
Bảng 1.2.1: Yêu cầu thô (loại 0x00). Được giải mã từ Yêu cầu đã mã hoá trong Bảng 1.1.
| Octet | Loại dữ liệu | Mô tả | Giá trị | Bắt buộc? |
|---|---|---|---|---|
| 0 | uint8 |
Loại thông báo | 0x10 = Yêu cầu hành động |
Bắt buộc |
| 1 | uint8 |
Cờ
|
thay đổi | Bắt buộc |
| 2 – 7 | uint48 |
Hoặc:
|
tuỳ thuộc | Bắt buộc |
| 8 | uint8 |
Nhắn tin cho nhóm | tuỳ thuộc | Bắt buộc nếu bạn đặt Cờ bit 0 |
| 9 | uint8 |
Mã thông báo | tuỳ thuộc | Bắt buộc nếu Bit cờ 0 được đặt |
| 10 | uint8 |
Phụ thuộc vào cờ:
|
thay đổi | Bắt buộc nếu bạn đặt Bit cờ 0 hoặc 1 |
| 11 – n | Dữ liệu khác | thay đổi | Không bắt buộc | |
| n – 15 | Giá trị ngẫu nhiên (salt) | tuỳ thuộc | Bắt buộc |
Bảng 1.2.2: Yêu cầu thô (loại 0x10). Được giải mã từ Yêu cầu đã mã hoá trong Bảng 1.1.
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0 | uint8 |
Loại thông báo | 0x01 = Phản hồi ghép nối dựa trên khoá |
| 1 – 6 | uint48 |
Địa chỉ công khai (BR/EDR) của Nhà cung cấp | thay đổi |
| 7 – 15 | Giá trị ngẫu nhiên (salt) | tuỳ thuộc |
Bảng 1.3: Phản hồi thô. Được mã hoá để tạo ra Phản hồi đã mã hoá trong Bảng 1.4.
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0 – 15 | uint128 |
Phản hồi được mã hoá | thay đổi |
Bảng 1.4: Phản hồi đã mã hoá, do Nhà cung cấp gửi đến Thiết bị tìm kiếm thông qua một thông báo.
Đặc điểm: Khoá truy cập
Đặc điểm này được dùng trong quy trình Ghép nối dựa trên khoá.
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0 – 15 | uint128 |
Khối khoá truy cập đã mã hoá | tuỳ thuộc |
Bảng 2.1: Khối khoá truy cập đã mã hoá. Hãy xem Quy trình Ghép nối dựa trên khoá để biết cách sử dụng.
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0 | uint8 |
Loại thông báo | Một trong các lựa chọn sau:
|
| 1 - 3 | unit32 |
Khoá truy cập gồm 6 chữ số | thay đổi |
| 4 – 15 | Giá trị ngẫu nhiên (salt) | tuỳ thuộc |
Bảng 2.2: Khối khoá truy cập thô. Phiên bản đã giải mã của Bảng 2.1.
Đặc điểm: Khoá tài khoản
Sau khi ghép nối, Fast Pair Seeker sẽ ghi Khoá tài khoản vào Fast Pair Provider.
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0 – 15 | uint128 |
Khoá tài khoản (đã mã hoá) | tuỳ thuộc |
Khi nhận được yêu cầu ghi, Nhà cung cấp tính năng Ghép nối nhanh sẽ làm như sau:
- Giải mã khoá tài khoản bằng khoá bí mật dùng chung được tạo từ bước 4 trong quy trình.
- Đối với những Nhà cung cấp yêu cầu bảo lãnh (phổ biến):
- Trước khi giải mã, hãy xác minh rằng khoá bí mật dùng chung đã được dùng để giải mã yêu cầu khoá truy cập từ bước 12. Nếu bước này không được thông qua bằng cách sử dụng khoá bí mật này, hãy bỏ qua thao tác ghi này và thoát.
- Tại thời điểm này, khoá bí mật dùng chung (K trong quy trình) sẽ không được dùng lại cho lần ghép nối này. Mọi yêu cầu được mã hoá bằng khoá này mà không khởi động lại quy trình đều sẽ bị từ chối.
- Đối với những Nhà cung cấp yêu cầu bảo lãnh (phổ biến):
- Xác minh rằng giá trị đã giải mã bắt đầu bằng
0x04hoặc0xFF. Nếu không, hãy bỏ qua thao tác ghi này và thoát.- Nếu giá trị là
0x04:- Kiểm tra xem danh sách Khoá tài khoản được lưu trữ có còn chỗ cho giá trị mới hay không.
- Nếu không, hãy xoá giá trị được sử dụng gần đây nhất khỏi danh sách.
- Thêm giá trị mới vào danh sách.
- Nếu giá trị là
0xFF:- Hãy coi đây là một phiên ghép nối tạm thời và không thực hiện thao tác nào.
- Điều này có thể xảy ra với quy trình Ghi khoá tài khoản có hiệu lực từ trước.
- Không lưu trữ khoá và không sử dụng khoá trong Danh sách khoá tài khoản, mã hoá hoặc tính toán MAC.
- Việc xoá liên kết được kích hoạt bởi một sự kiện hoặc thời gian chờ cụ thể của tính năng. Đối với tính năng Chia sẻ âm thanh LE, bạn nên xoá liên kết BLE và khoá liên kết sau 10 phút kể từ khi phiên tạm thời ngắt kết nối.
- Nếu giá trị là
Khoá tài khoản trong danh sách được dùng trong quá trình Ghép nối dựa trên khoá.
Đặc điểm: Bản sửa đổi chương trình cơ sở
Đặc điểm này cho phép Thiết bị tìm kiếm đọc bản sửa đổi chương trình cơ sở của Nhà cung cấp khi cần. Hàm này phải luôn trả về dữ liệu sau:
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0 – var | utf8s |
Mã phiên bản chương trình cơ sở | thay đổi |
Bạn nên đóng gói thành một chuỗi utf8 duy nhất ngay cả khi có nhiều chương trình cơ sở (ví dụ: 3 chương trình cơ sở cho tai nghe bên trái, tai nghe bên phải và hộp sạc) trên Nhà cung cấp. Nhà cung cấp cũng có thể trả về các chuỗi cụ thể cho các trường hợp đặc biệt:
status-updating: nếu Nhà cung cấp hiện đang cập nhật lên một chương trình cơ sở mới. Ngoài ra, Nhà cung cấp có thể trả về phiên bản của chương trình cơ sở theo giai đoạn.
status-abnormal: nếu Nhà cung cấp ở trạng thái bất thường. Ví dụ: thiết bị gặp sự cố do không cập nhật được chương trình cơ sở. Giá trị này sẽ khiến Seeker hiển thị thông báo cho người dùng biết rằng họ phải cập nhật ngay.
Nhà cung cấp nên hạn chế quyền truy cập vào đặc điểm Phiên bản chương trình cơ sở để ngăn chặn việc theo dõi thiết bị. Các quy định hạn chế được đề xuất:
- thiết bị được liên kết phải có quyền truy cập bất cứ lúc nào
- mọi thiết bị đều có thể truy cập khi Nhà cung cấp có thể phát hiện được
Nếu Nhà cung cấp hỗ trợ Trung tâm tìm thiết bị, thì bạn cần triển khai thêm. Hãy tham khảo bài viết Bản cập nhật chương trình cơ sở cho Trung tâm tìm thiết bị để biết thông tin chi tiết.
Đặc điểm: Dữ liệu bổ sung
Dịch vụ này phải có đặc điểm sau.
| Đặc điểm của Dịch vụ ghép nối nhanh | Đã mã hóa | Quyền | mã nhận dạng duy nhất (UUID) |
|---|---|---|---|
| Dữ liệu | Không | Viết và thông báo | FE2C1237-8366-4814-8EB0-01DE32100BEA |
| Đặc điểm của Dịch vụ Ghép nối nhanh cũ (dự kiến sẽ ngừng hoạt động vào ngày 1/1/2021) | Đã mã hóa | Quyền | mã nhận dạng duy nhất (UUID) |
|---|---|---|---|
| Dữ liệu | Không | Viết và thông báo | 0x1237 |
Trước khi ghi hoặc thông báo cho đặc điểm này, phải có một cái bắt tay thông qua đặc điểm FE2C1234-8366-4814-8EB0-01DE32100BEA để có một bí mật chung. AES-CTR sẽ được dùng để mã hoá dữ liệu truyền qua đặc điểm này, thuật toán của đặc điểm này được xác định bên dưới. Chế độ này bảo mật hơn đối với dữ liệu vượt quá một khối 16 byte. HMAC-SHA256 sẽ được dùng để đảm bảo tính toàn vẹn của dữ liệu, cũng được định nghĩa bên dưới.
| Octet | Mô tả | Giá trị |
|---|---|---|
| 0 - 7 | 8 byte đầu tiên của HMAC-SHA256. | tuỳ thuộc |
| 8 – 15 | Số chỉ dùng một lần, được dùng để mã hoá AES-CTR. | thay đổi |
| 16 – var | Dữ liệu đã mã hoá. | tuỳ thuộc |
Bảng 3.1: Gói dữ liệu, do Nhà cung cấp gửi đến Thiết bị tìm kiếm thông qua một thông báo hoặc do Thiết bị tìm kiếm gửi đến Nhà cung cấp thông qua một thao tác ghi.
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0 – var | byte array |
Dữ liệu | thay đổi, hãy giải mã theo Mã dữ liệu của Bảng 1.2.2:
|
Bảng 3.2: Dữ liệu thô. Được giải mã từ dữ liệu đã mã hoá trong Bảng 3.1.
Khi có yêu cầu thông báo (ví dụ: yêu cầu tên được cá nhân hoá thông qua Bit 2 trong Bảng 1.2.1), Nhà cung cấp Ghép nối nhanh sẽ làm như sau:
- Tạo 8 byte ngẫu nhiên được mã hoá cho Nonce.
Mã hoá dữ liệu bằng AES-CTR, trong đó mỗi khối 16 byte được tạo bằng
encryptedBlock[i] = clearBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))trong đó
- Khoá AES là bí mật dùng chung từ bước 4 trong quy trình.
- clearBlock[i] là một khối 16 byte bắt đầu từ data[i * 16]. Khối cuối cùng có thể nhỏ hơn 16 byte.
Thực hiện concat(encryptedBlock[0], encryptedBlock[1],...) để tạo Dữ liệu đã mã hoá.
Tạo HMAC-SHA256 bằng
sha256(concat((K ^ opad), sha256(concat((K ^ ipad), concat(nonce, encrypted_data)))))trong đó
- K được tạo bằng cách concat(shared_secret, 48-byte ZEROs), shared_secret là từ bước 4 trong quy trình.
- opad là khoảng đệm ngoài 64 byte, bao gồm các byte lặp lại có giá trị
0x5C. - ipad là phần đệm bên trong 64 byte, bao gồm các byte lặp lại có giá trị 0x0A
0x36.
Lấy 8 byte đầu tiên từ HMAC-SHA256 làm tiền tố của Gói dữ liệu.
Khi nhận được yêu cầu ghi, Nhà cung cấp tính năng Ghép nối nhanh sẽ làm như sau:
- Xác minh tính toàn vẹn của dữ liệu bằng cách kiểm tra 8 byte đầu tiên của HMAC-SHA256.
Giải mã Dữ liệu đã mã hoá bằng AES-CTR, trong đó mỗi khối được tạo bằng
clearBlock[i] = encryptedBlock[i] ^ AES(key, concat((uint8) i, 0x00000000000000, nonce))trong đó
- encryptedBlock[i] là một khối 16 byte bắt đầu từ encrypted_data[i * 16]. Khối cuối cùng có thể nhỏ hơn 16 byte.
- Khoá AES được tạo hoặc xác định từ quá trình bắt tay, ví dụ:
- trong quy trình đặt tên 1, khoá này là từ ECDH và sẽ không được dùng lại cho hoạt động ghép nối này. Mọi yêu cầu được mã hoá bằng khoá này mà không khởi động lại quy trình đều sẽ bị từ chối.
- trong quy trình đặt tên 2, đây là khoá tài khoản.
Thực hiện concat(clearBlock[0], clearBlock[1],...) để tạo dữ liệu thô.