11.13. Ghép nối và liên kết¶
Tất cả những gì đã trình bày đến đây đều truyền byte qua sóng radio ở dạng rõ. Bất kỳ ai có máy tính xách tay hỗ trợ BLE trong cùng phòng đều có thể nghe trên các kênh quảng bá, theo dõi chuỗi nhảy tần của một kết nối mở, và đọc mọi thao tác đọc, ghi, và thông báo diễn ra trên đó. Đối với hầu hết dữ liệu cảm biến công khai (mức pin, nhiệt độ môi trường) điều đó là chấp nhận được. Nhưng với bất kỳ thứ gì mà hai đầu kết nối muốn giữ riêng tư -- một thanh ghi điều khiển kích hoạt relay, một mật khẩu, một phép đo không nên phát sóng rộng rãi -- liên kết cần được mã hóa, và lý tưởng nhất là camera cần biết mình đang nói chuyện với ai.
BLE cung cấp cả hai thông qua ghép nối và liên kết.
11.13.1. Ghép nối, liên kết, mã hóa¶
Ba khái niệm liên quan chặt chẽ:
Mã hóa là mục tiêu cuối cùng. Sau khi liên kết được mã hóa, mọi gói tin trên các kênh dữ liệu chỉ có thể được giải mã bởi hai đầu; người nghe lén chỉ thấy nhiễu.
Ghép nối là thủ tục mà hai đầu thực hiện để thỏa thuận các khóa mà quá trình mã hóa sử dụng. Đây là một lần trao đổi duy nhất tạo ra vật liệu khóa chung mà tầng liên kết sử dụng trong bộ máy mã hóa của nó.
Liên kết là việc chọn lưu trữ các khóa vào bộ nhớ không thay đổi sau khi ghép nối hoàn tất, để kết nối tiếp theo giữa cùng hai thiết bị bỏ qua bước ghép nối và đi thẳng vào mã hóa.
Nói đơn giản: ghép nối là "tự giới thiệu"; liên kết là "ghi nhớ lần giới thiệu này"; mã hóa là "nói chuyện riêng tư từ bây giờ".
Luồng ghép nối trên đầu một kết nối BLE mở. Sau khi trao đổi khóa hoàn tất, tầng liên kết mã hóa mọi gói tin tiếp theo. Liên kết là bước bổ sung để ghi các khóa vào flash.¶
11.13.2. LE Secure Connections¶
Phương thức trao đổi khóa hiện đại mà BLE sử dụng là LE Secure Connections, được xây dựng trên nền tảng Elliptic Curve Diffie-Hellman. Cả hai bên tạo ra một cặp khóa tạm thời, trao đổi nửa công khai, và kết hợp kết quả với khóa riêng tư của mình để đạt được cùng một bí mật chung -- một bí mật mà kẻ nghe lén không thể tính toán được dù có toàn bộ bản ghi của quá trình trao đổi.
Phương thức cũ hơn LE Legacy kém an toàn hơn (kẻ nghe lén với toàn bộ quá trình trao đổi thường có thể khôi phục lại khóa) và chỉ tồn tại để tương thích ngược với các thiết bị ngoại vi cũ. Giá trị mặc định của aioble là phương thức hiện đại (le_secure=True); hãy giữ nguyên.
11.13.3. Khởi tạo ghép nối¶
Một central thực hiện ghép nối bằng cách gọi aioble.DeviceConnection.pair() trên một kết nối đã mở:
async with await device.connect() as connection:
await connection.pair(bond=True, le_secure=True, mitm=False)
# ... GATT work, now over an encrypted link ...
Sau khi pair trả về, các thuộc tính encrypted, authenticated, bonded, và key_size trên kết nối phản ánh những gì đã được thương lượng.
Bốn đối số từ khóa hữu ích nhất:
bond=True-- lưu các khóa kết quả vào flash để kết nối tiếp theo giữa cùng hai thiết bị bỏ qua quá trình bắt tay ghép nối. Mặc định làTrue.le_secure=True-- sử dụng LE Secure Connections. Mặc định làTrue. Hãy giữ nguyên.mitm=False-- có yêu cầu bảo vệ man-in-the-middle hay không. Điều này cần một kênh ngoài băng tần (một mã số được hiển thị ở một bên và xác nhận ở bên kia, một mã passkey được nhập vào, ...) để người dùng có thể xác minh rằng hai thiết bị trong quá trình bắt tay ghép nối thực sự là những thiết bị mà họ nghĩ. Mặc định làFalse(không có bảo vệ MITM -- kẻ nghe lén thụ động không thể đọc liên kết, nhưng kẻ tấn công chủ động chuyển hướng kết nối có thể tự ghép nối vào). Đặt thànhTruecho bất kỳ thứ gì nhạy cảm, nhưng cần lưu ý rằng điều này yêu cầu thiết bị ngoại vi thực sự hỗ trợ khả năng IO.io=3-- khả năng IO mà thiết bị khai báo. Thông số kỹ thuật Bluetooth định nghĩa năm loại:0chỉ hiển thị,1hiển thị + có/không,2chỉ bàn phím,3không có đầu vào không có đầu ra,4bàn phím + hiển thị. Một camera không có giao diện người dùng thường báo cáo3; nếu bản thân camera có màn hình, ứng dụng có thể hiển thị xác nhận số và sử dụng1. Sự kết hợp của khả năng IO của cả hai bên quyết định liệu bảo vệ MITM thực sự có khả thi hay không.
Các thiết bị ngoại vi không tự gọi pair -- chúng phản hồi với bất kỳ điều gì mà central khởi tạo. Việc mã hóa có được yêu cầu cho một đặc trưng nhất định hay không là thuộc tính của cách nó được khai báo trong cơ sở dữ liệu GATT; các bit truy cập yêu cầu mã hóa là một phần của API bluetooth cấp thấp và hiện không được hiển thị thông qua hàm khởi tạo đặc trưng aioble.
11.13.4. Liên kết -- và nơi các khóa tồn tại¶
Khi bond=True, aioble ghi các khóa vào một tệp JSON trên hệ thống tệp cục bộ. Tên tệp mặc định là ble_secrets.json, được ghi tương đối so với thư mục làm việc hiện tại. Trên một cam mới khởi động, _boot.py đã chọn thư mục đó: /sdcard khi có thẻ nhớ được gắn, ngược lại là /flash -- vì vậy tệp sẽ ở /sdcard/ble_secrets.json hoặc /flash/ble_secrets.json. Tệp chứa các mục cần thiết để mã hóa lại liên kết vào lần tiếp theo thiết bị đồng đẳng đã liên kết kết nối lại, bao gồm địa chỉ danh tính của thiết bị đồng đẳng.
Một sự bất đối xứng cần lưu ý: lưu xảy ra tự động khi các khóa thay đổi, nhưng tải tệp khi khởi động lần sau thì không. Gọi aioble.security.load_secrets() một lần khi khởi động (trước bất kỳ thao tác ghép nối hoặc quảng bá nào) để các thiết bị đồng đẳng đã liên kết trước đó được nhận diện:
import aioble
aioble.security.load_secrets() # default path: ble_secrets.json
Sau đó, lần tiếp theo một thiết bị đồng đẳng đã liên kết xuất hiện, aioble tái sử dụng các khóa đã lưu và liên kết được mã hóa mà không cần bắt tay thêm.
Hai hệ quả thực tế của việc lưu trữ khóa trên flash:
Quên một thiết bị. Xóa
ble_secrets.json(hoặc xóa mục liên quan) để quên tất cả các thiết bị đồng đẳng đã liên kết, sau đó ghép nối lại từ đầu.Truy cập vật lý làm lộ khóa. Bất kỳ ai có quyền truy cập vào hệ thống tệp của camera đều có thể đọc JSON. Đây là loại ràng buộc tương tự như đã đề cập ở phía mạng với các khóa TLS (Các thao tác: khóa, hết hạn và xử lý sự cố): sử dụng khóa riêng cho từng thiết bị, coi mọi khóa đã lưu trữ là có thể khôi phục được, và dựa vào khả năng thu hồi (ở đây, xóa liên kết ở phía central) thay vì dựa vào việc giữ bí mật khóa.
11.13.5. Những gì mã hóa đảm bảo -- và những gì nó không đảm bảo¶
Một liên kết ghép nối rồi mã hóa cung cấp, theo thứ tự độ mạnh:
Tính bảo mật. Luôn luôn. Kẻ nghe lén không thể đọc các byte.
Tính toàn vẹn. Luôn luôn. Các gói tin bị sửa đổi sẽ thất bại trong kiểm tra mã hóa xác thực ở tầng liên kết và bị loại bỏ.
Xác thực. Chỉ với
mitm=Truevà IO có khả năng. Nếu không, một kẻ tấn công trung gian đã chặn lần ghép nối ban đầu có thể đã tự chèn vào; không có bảo vệ MITM thì không có cách nào để hai bên biết được điều đó.
Đối với hầu hết các trường hợp sử dụng camera -- một điện thoại ghép nối với camera một lần, sau đó kết nối lại sau -- mitm=False thường là đủ, vì lần ghép nối ban đầu diễn ra trong môi trường có kiểm soát (người dùng cầm cả hai thiết bị trong cùng một phòng). Đối với các ứng dụng mà thiết bị đã ghép nối có thể lần đầu gặp camera từ xa hoặc qua một trung gian không đáng tin cậy, MITM là cài đặt phù hợp.
11.13.6. Khi ghép nối là câu trả lời sai¶
Ghép nối có chi phí thực sự: vài giây trao đổi trong lần kết nối đầu tiên, sử dụng flash liên tục cho mỗi thiết bị đã liên kết, và câu chuyện khôi phục là "quên liên kết" nếu có điều gì đó xảy ra. Đối với dữ liệu thực sự công khai -- số liệu đọc từ cảm biến môi trường được phát dưới dạng beacon, một biển hiệu hiển thị tên, bất cứ thứ gì không thay đổi thế giới khi được đọc hoặc ghi -- câu trả lời đúng là không mã hóa, và để bất kỳ máy quét nào gần đó đọc các giá trị.
Đối với mọi thứ còn lại, connection.pair(bond=True) trên central là thêm một dòng duy nhất để biến liên kết từ một kênh công khai thành một kênh riêng tư.