Linux & Windows 双系统蓝牙设备共享(包括蓝牙 LE 设备)

Linux & Windows 双系统蓝牙设备共享(包括蓝牙 LE 设备)

环境

  1. 蓝牙设备:

蓝牙4.0 鼠标
低功耗蓝牙 4.0 LE 键盘

  1. 操作系统

Arch Linux;
KDE Plasma 版本: 5.23.5
KDE 程序框架版本: 5.90.0
内核版本: 5.16.5-arch1-1 (64-位)

Windows 10 或 Windows 11 (64-位)

准备

  1. 将蓝牙设备与 Linux 系统进行配对, 留下设备信息, 完成后重启系统引导至 Windows
  2. 将蓝牙设备与 Windows 系统进行配对, 留下设备信息

获取 Windows 下蓝牙设备信息

  1. 微软官方文档网站下载 PsExec. 我们使用这个工具来获得注册表内蓝牙设备信息
  2. 解压 PSTools.zip 压缩包至合适目录下, 如 C:\Program Files\PSTools
  3. 高级系统设置 - 环境变量 - 系统变量 在 Path 值下添加一个文件路径变量 C:\Program Files\PSTools
  4. 使用一款终端软件, 如 Windows Terminal ,以管理员身份打开,输入如下命令,将注册表内有关信息导出保存到 C:\BTKeys.reg 中
1
psexec -s -i regedit /e C:\BTKeys.reg HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys
  1. 复制 C:\BTKeys.reg 到 Linux 硬盘或 U盘 内

在 Linux 中修改蓝牙配置

在 Windows 中获取的 BTKeys.reg 文件格式如下例

命令行下使用 cat 查看文件内容

图形界面下这里使用 Kate 查看文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55

Windows Registry Editor Version 5.00



[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys]



[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\ffffffffffff]

"MasterIRK"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00



[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\ffffffffffff\00000000000]

"LTK"=hex:f3,13,02,86,20,9d,04,12,c0,1e,8e,cb,fb,e9,04,1b

"KeyLength"=dword:00000010

"ERand"=hex(b):18,57,93,eb,5f,b2,15,2e

"EDIV"=dword:0000ecb0

"IRK"=hex:a0,8d,5a,98,34,41,31,3f,00,72,c9,f8,95,5f,fa,d5

"Address"=hex(b):27,d5,bb,fc,5a,eb,00,00

"AddressType"=dword:00000001

"CSRK"=hex:bc,70,a8,79,7c,35,9e,9a,3f,0d,d7,f7,70,64,44,a4

"OutboundSignCounter"=dword:00000000

"MasterIRKStatus"=dword:00000001

"AuthReq"=dword:0000002d



[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\ffffffffffff\1111111111111]

"LTK"=hex:88,0f,f4,8d,11,db,33,28,36,54,06,cd,a6,27,a2,64

"KeyLength"=dword:00000010

"ERand"=hex(b):38,bb,05,08,11,91,f1,8b

"EDIV"=dword:0000882b

"MasterIRKStatus"=dword:00000001

"AuthReq"=dword:0000002d

从含有中括号 [ ] 的行至下一个含有中括号 [ ] 的行前是一个蓝牙设备的配置信息
如:

第 9 行 [ …\Keys\ffffffffffff] 的 ffffffffffff 就是该主机蓝牙控制器的十六位地址

第 15 行 [ …\Keys\ffffffffffff\000000000000] 的 000000000000 就是一个蓝牙设备的十六位地址,至第 40 行是该设备的配置信息

第 41 行 [ …\Keys\ffffffffffff\1111111111111] 的 1111111111111 就是另一个蓝牙设备的十六位地址,至第 53 行是该设备的配置信息

对应 Linux 下设备蓝牙信息

打开 Linux 任一终端,键入命令(以 root 用户身份)

1
2
3
4
5
6
7
8
[root@Linux ~]# cd /var/lib/bluetooth/

[root@Linux bluetooth]# ls
FF:FF:FF:FF:FF:FF // 该文件夹名称对应之前获取的该主机蓝牙控制器的十六位地址

[root@Linux bluetooth]# cd FF:FF:FF:FF:FF:FF //键入 cd 后按 Tab 键即可自动补全名称
[root@Linux FF:FF:FF:FF:FF:FF]# ls
00:00:00:00:00:01 11:11:11:11:11:12 cache settings

文件夹 00:00:00:00:00:01 和 11:11:11:11:11:12 则是 Linux 下两个蓝牙设备的十六位地址(有一位数字的偏差)

修改蓝牙配置文件夹名称

我们需要将两个文件夹的名称改为 Windows 下同一设备的地址

如:

00:00:00:00:00:01 -> 00:00:00:00:00:00

11:11:11:11:11:12 -> 11:11:11:11:11:11

1
2
3
4
5
6
7
[root@Linux FF:FF:FF:FF:FF:FF]# mv 00:00:00:00:00:01 00:00:00:00:00:00

[root@Linux FF:FF:FF:FF:FF:FF]# mv 11:11:11:11:11:12 11:11:11:11:11:11

[root@Linux FF:FF:FF:FF:FF:FF]# ls
00:00:00:00:00:00 11:11:11:11:11:11 cache settings //再次查看文件夹名称确认

查看 Linux 蓝牙配置

进入一个蓝牙设备的文件夹,查看 info 文件

1
2
3
4
5
6
7
[root@Linux FF:FF:FF:FF:FF:FF]# cd 11:11:11:11:11:11

[root@Linux 11:11:11:11:11:11]# ls
attributes info

[root@Linux 11:11:11:11:11:11]# cat info

info 文件格式如下
例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[General]
Name=Ergonomic Keyboard
Appearance=0x03c1
AddressType=static
SupportedTechnologies=LE;
Trusted=true
Blocked=false
WakeAllowed=true
Services=00001800-0000-1000-8000-00805f9b34fb;00001801-0000-1000-8000-00805f9b34fb;0000180a-0000-1000-8000-00805f9b34fb;0000180f-0000-1000-8000-00805f9b34fb;00001812-0000-1000-8000-00805f9b34fb;
Alias=Ergonomic Keyboard

[ConnectionParameters]
MinInterval=12
MaxInterval=12
Latency=20
Timeout=200

[DeviceID]
Source=2
Vendor=1118
Product=2071
Version=308

[IdentityResolvingKey]
Key=A08D5A983441313F0072C9F8955FFAD5

[LocalSignatureKey]
Key=BC70A8707C359E9A3F0DD7F770444A04
Counter=0
Authenticated=true

[LongTermKey]
Key=F3130286209D0412C01E8ECBFBE9041B
Authenticated=1
EncSize=16
EDiv=60592
Rand=3320756425299547928

配置项中, Linux 下名称和 Windows 下名称对应为

[IdentityResolvingKey] <=> “IRK”

[LocalSignatureKey] <=> “CSRK”

[LongTermKey] <=> “LTK”

EncSize ([LongTermKey]下) <=> “KeyLength”

EDiv ([LongTermKey]下) <=> “EDIV”

Rand ([LongTermKey]下) <=> “ERand”

对应数值转换

使用 BTKeys.reg 内的数值转换后修改对应 info 文件下的数值

  • “LTK”项 只保留字母数字,且字母小写转大写
1
echo "f3,13,02,86,20,9d,04,12,c0,1e,8e,cb,fb,e9,04,1b" | tr a-z A-Z | sed "s/[[:punct:]]//g"
  • “KeyLength”项 只保留数字,且十六进制转十进制
1
echo $((16#00000010))
  • “ERand”项 只保留字母数字,且以逗号相隔为一组,各组逆序排列后所得十六进制转十进制
1
echo $((16#2e15b25feb935718))
  • “EDIV”项 只保留字母数字,且十六进制转十进制
1
echo $((16#0000ecb0))
  • “IRK”项 只保留字母数字,且字母小写转大写
1
echo "a0,8d,5a,98,34,41,31,3f,00,72,c9,f8,95,5f,fa,d5" | tr a-z A-Z | sed "s/[[:punct:]]//g"
  • “CSRK”项 只保留字母数字,且字母小写转大写
1
echo "bc,70,a8,79,7c,35,9e,9a,3f,0d,d7,f7,70,64,44,a4" | tr a-z A-Z | sed "s/[[:punct:]]//g"

修改蓝牙配置

根据上述步骤得到的数值,对应修改 info 文件中的数值

1
[root@Linux 11:11:11:11:11:11]# nano info

“IRK”的数值需修改 [IdentityResolvingKey] 下一行的 key

同理修改 [LocalSignatureKey] 和 [LongTermKey]

EncSize ,EDIV 和 Rand 找到其对应名称修改即可

若未在 BTKeys.reg 的某一设备中发现某一配置,不用着急,找出其存在的配置即可。因为 Linux 下 info 文件里也不需要该未出现的配置

修改完一个蓝牙设备后,进入另外一个目录修改另一个蓝牙设备的 info 文件

1
2
3
[root@Linux 11:11:11:11:11:11]# cd ../00:00:00:00:00:00

[root@Linux 00:00:00:00:00:00]# nano info

重启蓝牙服务

修改完毕后,重启蓝牙服务,此时蓝牙设备应该能够正常在 Linux 系统下使用且不用重新配对也能够在重启后引导至 Windows 系统下使用

1
systemctl restart bluetooth