Skip to main content

Synchronize Bluetooth LE and Classic bond keys between Windows and Linux in dual-boot setups

Project description

btkey_sync

Syncs Bluetooth LE bonding (LTK / EDIV / ERand) from BLE devices between any two "sides": dual-boot operating systems, two partitions/installs of the same OS, or two separate physical machines — without having to re-pair the physical device on every switch.

See REQUIREMENTS.md for the full functional scope and AGENTS.md if you're using an AI agent (Claude Code, etc.) to maintain/extend this project.

Why this exists

Some budget BLE devices (mice, keyboards) use private MAC addresses that rotate between pairing sessions (RPA). Windows and Linux store bonding data in completely different formats and paths:

Windows Linux (BlueZ)
Location HKLM\SYSTEM\CurrentControlSet\Services\BTHPORT\Parameters\Keys /var/lib/bluetooth/<adapter>/<device>/info
Required access SYSTEM account (Administrator is not enough) root
EDIV/ERand format Hexadecimal Decimal
Hot reload No: requires systemctl restart bluetooth

This project automates extraction, conversion, and writing on both sides, leaving the exchangeable files in an exports/ folder intended to be copied manually between partitions (there's no way to sync this live without a daemon running on both OSes simultaneously).

Installation

No external dependencies required for normal use (only Python ≥3.10 stdlib).

git clone <this-repo>
cd btkey_sync
# Optional, only if running tests with pytest:
pip install -e ".[dev]" --break-system-packages

Usage

Export (on the system where the device IS connecting successfully)

Linux:

sudo python3 -m btkey_sync

Windows (PowerShell or CMD as Administrator):

python -m btkey_sync

Interactive flow:

  1. Detects the OS automatically.
  2. Lists BLE devices with bonding found.
  3. You choose which one to export.
  4. Generates exports/<MAC>__<os>__<timestamp>.reg + .json with the same info in plain text.

Copy the file to the destination

Copy the generated .reg file (USB, shared partition, local network, whatever you have at hand) to the exports/ folder of the target installation — this can be the other OS (dual boot), another partition/install of the same OS, or the equivalent on another machine.

Import (on the system that needs the bonding)

sudo python3 -m btkey_sync --import filename.reg

Shows locally known devices, lets you confirm or change the destination MAC (important if the device rotated its RPA address since last time), writes the bonding, and automatically restarts the Bluetooth stack.

Project structure

btkey_sync/
├── cli.py                  # orchestrates the 4-step flow
├── models.py                # BondKey: OS-agnostic bonding representation
├── platform_detect.py       # Windows/Linux detection + environment validation
├── storage.py                # manages the exports/ folder and naming convention
├── backends/
│   ├── base.py                # interface all backends must implement
│   ├── windows_backend.py     # Windows registry via SYSTEM scheduled task
│   └── linux_backend.py       # BlueZ info files in /var/lib/bluetooth
├── exporters/reg_exporter.py  # BondKey -> .reg content
└── importers/reg_importer.py  # .reg -> BondKey

Testing

python3 tests/test_parsing.py
# or, if you installed pytest:
pytest

Tests use data from a real confirmed-working migration (tests/fixtures/sample_mouse.reg), including the round-trip case with a MAC change (rotated RPA).

To test a backend without touching your real system, inject a temporary directory:

from pathlib import Path
from btkey_sync.backends.linux_backend import LinuxBluetoothBackend

backend = LinuxBluetoothBackend(bluetooth_dir=Path("/tmp/fake_bluetooth"))

Known limitations

  • No automatic/live sync between the two sides — always requires a manual step of copying the exported file to the destination.
  • BLE only (SMP/LTK). Does not cover Bluetooth Classic (BR/EDR).
  • If the device uses RPA and rotates its address, the export→copy→import cycle must be repeated; this project does not resolve IRK automatically.
  • Windows and Linux only. No macOS backend (see AGENTS.md if you want to add one).

License / use

Personal project for managing your own equipment. Use at your own discretion; you are touching internal structures not officially documented by Microsoft or the BlueZ project.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

btkey_sync-0.1.1.tar.gz (42.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

btkey_sync-0.1.1-py3-none-any.whl (54.2 kB view details)

Uploaded Python 3

File details

Details for the file btkey_sync-0.1.1.tar.gz.

File metadata

  • Download URL: btkey_sync-0.1.1.tar.gz
  • Upload date:
  • Size: 42.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for btkey_sync-0.1.1.tar.gz
Algorithm Hash digest
SHA256 dd71c0dbc5e556b7d0b9f69c0b823ed437ff2e42b926d280d897697c85c4c506
MD5 9be822168b899dab514533c118f1d1b8
BLAKE2b-256 5703638ba67d3906473622acc9b56ce90e3bba882eee3a0788b09f8193db85c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for btkey_sync-0.1.1.tar.gz:

Publisher: workflow.yml on netssv/btkey_sync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file btkey_sync-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: btkey_sync-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 54.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for btkey_sync-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 61a16cb23d95b2d15b76c8f5990ff3fbdbbe16edc7dfc48e34fd570b8dc1be0c
MD5 98130a0f2f57b0fc1e67ace803f81770
BLAKE2b-256 5631f45c4a3936cd8b7246a5bf17000a28b5db04f6e80d30e490b1f2bef0737a

See more details on using hashes here.

Provenance

The following attestation bundles were made for btkey_sync-0.1.1-py3-none-any.whl:

Publisher: workflow.yml on netssv/btkey_sync

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page