蓝牙设备虽然很方便,不需要专门的接收器。但对使用多系统的用户来说,每次使用都需要重新配对十分麻烦,即使设备能够记住多个配对配置,但对于同一台电脑来说,因为系统不同就切换配置也实在是不够优雅。
那么,有没有方法可以在多个系统间共享配对的方法呢?
其实蓝牙配对就是生成了一个随机的key,只要想办法让不同系统里保存的key一致就行了。
因为不同蓝牙版本有所差异,下面分开来说。
在Ubuntu shell里转换key的表示方法
Windows下和Ubuntu下的key的表示方法不一样,所以需要进行转换。下面给出用Shell命令进行转换的方法,可以先略过,后面需要用到再回来看:
- 十六进制转为小写并加逗号分隔(Ubuntu –> Windows)(
AA5AB39BA3590E11D491B7993610F720
替换为你自己的内容):
echo $(echo AA5AB39BA3590E11D491B7993610F720|tr A-F a-f|sed -r 's/(..)/\1\n/g')|sed -r 's/\ /,/g'
- 十六进制去除逗号并转换为大写(Windows –> Ubuntu)(
09,be,cd,1f,b3,16,d0,e8,e6,7b,24,de,9f,8b,a0,80
替换为你自己的内容):
echo 09,be,cd,1f,b3,16,d0,e8,e6,7b,24,de,9f,8b,a0,80|tr a-f A-F|tr -d ,
- 十进制转换为8位十六进制(Ubuntu –> Windows)(
32527
替换为你自己的内容):
echo $(printf "%08x" 32527)
- 十六进制转换为十进制(Windows –> Ubuntu)(
00007f0f
替换为你自己的内容):
echo $((16#00007f0f))
- 十进制转换为16位十六进制、逗号分隔并倒序(Ubuntu –> Windows)(
885403952940349154
替换为你自己的内容):
echo $(printf "%016x" 885403952940349154|sed -r 's/(..)/\1\n/g'|tac)|sed -r 's/\ /,/g'
- 十六进制倒序并转换为十进制(Windows –> Ubuntu)(
e2,76,bc,41,34,96,49,0c
替换为你自己的内容):
echo $((16#$(echo e2,76,bc,41,34,96,49,0c|tac -s ','|tr -d ',')))
蓝牙3.0设备
分别配对设备
首先,我们需要将蓝牙设备分别在不同系统下(下面以Ubuntu和Windows为例)与电脑配对(如果有多配置切换功能的蓝牙设备,需要用同一个配置配对),以生成配置文件。然后在最后配对的系统里获取key,再到另一个系统里写入这个key就可以了。
Ubuntu
获得设备地址
首先,在系统设置中,点击已配对的蓝牙设备,查看设备的地址。
获得key
打开终端,用cat
查看设备信息:
cat /var/lib/bluetooth/xx:xx:xx:xx:xx:xx/yy:yy:yy:yy:yy:yy/info
其中xx:xx:xx:xx:xx:xx
是蓝牙适配器的设备地质,可以在输入的过程中使用Tab补全。yy:yy:yy:yy:yy:yy
是上面在设置中看到的设备地址。
你会看到类似如下内容:
[General]
Name=ALT Bluetooth keyboard
Class=0x002540
SupportedTechnologies=BR/EDR;
Trusted=true
Blocked=false
WakeAllowed=true
Services=00001000-0000-1000-8000-00805f9b34fb;00001124-0000-1000-8000-00805f9b34fb;00001200-0000-1000-8000-00805f9b34fb;
[LinkKey]
Key=BD735AA0061A72C57E7FF906FA664538
Type=4
PINLength=0
[DeviceID]
Source=2
Vendor=1452
Product=544
Version=1
其中[LinkKey]
下的Key
就是我们需要的内容。
修改key
Windows下获得key后(必要时用第1节方法2转换),直接修改/var/lib/bluetooth/xx:xx:xx:xx:xx:xx/yy:yy:yy:yy:yy:yy/info
文件中[LinkKey]
下的Key
的内容即可。如使用vim
修改(注意需要root权限):
sudo vim /var/lib/bluetooth/xx:xx:xx:xx:xx:xx/yy:yy:yy:yy:yy:yy/info
Windows
获得设备地址
首先我们还是要获得蓝牙设备地址,可以打开设备管理器,找到蓝牙下的对应设备,双击打开属性,然后在详细信息选项卡中属性下选择设备实例路径,并在下方找到BTHENUM\DEV_yyyyyyyyyyyy&...
这样的内容,yyyyyyyyyyyy
就是我们要找到的设备地址。
使用系统管理员权限运行注册表编辑器
Windows下蓝牙配置保存在注册表中,并且由于权限较高,直接运行注册表编辑器并不能访问,所以需要一个提权工具PsExec,其为PsTools的一部分,可以在微软Sysinternals下载得到(页面中的Download PsTools Suite)。
下载后解压,假设解压到X:\path\to\PSTools
。先在开始按钮上点右键,选择终端管理员,以管理员身份打开终端。然后在终端中执行如下命令:
X:\path\to\PSTools\PsExec.exe -s -i regedit
就可以以系统管理员身份打开注册表编辑器了。
获得key
在注册表编辑器中导航到HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\xxxxxxxxxxxx
,其中xxxxxxxxxxxx
和上面Ubuntu下类似,是蓝牙适配器地址(Windows下没有冒号:
)。然后在右边可以找到设备地址yyyyyyyyyyyy
的REG_BINARY
类型的键,其值就是对应的key了。
可以用下面的命令直接导出(假设导出文件路径为X:\path\to\BT.reg
):
X:\path\to\PSTools\PsExec.exe -s -i regedit /e X:\path\to\BT.reg HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys
然后用文本编辑器打开X:\path\to\BT.reg
,找到[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\xxxxxxxxxxxx]
下的"yyyyyyyyyyyy"=hex:bd,73,5a,a0,06,1a,72,c5,7e,7f,f9,06,fa,66,45,38
这样的内容,hex:
后面的就是我们需要的key。
修改key
可以直接在系统管理员权限的注册编辑器中直接编辑HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\xxxxxxxxxxxx
下的设备地址yyyyyyyyyyyy
的REG_BINARY
类型的键,双击打开然后把所有内容删除,然后把Ubuntu下获得的十六进制key填入即可。
亦或者可以新建一个注册表文件(假设保存为X:\path\to\BT.reg
),内容如下:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\xxxxxxxxxxxx]
"yyyyyyyyyyyy"=hex:bd,73,5a,a0,06,1a,72,c5,7e,7f,f9,06,fa,66,45,38
xxxxxxxxxxxx
是蓝牙适配器地址,yyyyyyyyyyyy
是设备地址,bd,73,5a,a0,06,1a,72,c5,7e,7f,f9,06,fa,66,45,38
替换为Ubuntu下获得的key(必要时用第1节方法1转换)。
然后在终端管理员中使用如下命令导入:
X:\path\to\PSTools\PsExec.exe -s -i regedit /s X:\path\to\BT.reg
蓝牙4.0及以后设备
蓝牙4.0设备与3.0设备类似,也是先分别配对设备,然后再从最后配对的系统里获取key,写入另一个系统。只是key的内容有所差异。
Ubuntu
首先用上述第2.2.1节方法获得设备地址。
获得key
和上面第2.2.2节方法一样,也是在/var/lib/bluetooth/xx:xx:xx:xx:xx:xx/yy:yy:yy:yy:yy:yy/info
中,只不过内容有所差异,例如:
[General]
Name=BT5.0 KB
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;
[DeviceID]
Source=2
Vendor=9639
Product=64020
Version=26369
[IdentityResolvingKey]
Key=09BECD1FB316D0E8E67B24DE9F8BA080
[RemoteSignatureKey]
Key=78077D26D601957D869EDBA71E3E74A2
Counter=0
Authenticated=false
[LocalSignatureKey]
Key=D31B8B98D59A387D83B0D55C2C5057B8
Counter=0
Authenticated=false
[LongTermKey]
Key=AA5AB39BA3590E11D491B7993610F720
Authenticated=0
EncSize=16
EDiv=25496
Rand=4689627501084073450
[PeripheralLongTermKey]
Key=B98F17E1D08C3E23580135A9EFF5A996
Authenticated=0
EncSize=16
EDiv=32527
Rand=885403952940349154
[SlaveLongTermKey]
Key=B98F17E1D08C3E23580135A9EFF5A996
Authenticated=0
EncSize=16
EDiv=32527
Rand=885403952940349154
[ConnectionParameters]
MinInterval=12
MaxInterval=12
Latency=32
Timeout=300
Ubuntu和Windows下键名的对应关系如下(转换方法为上面第1节中所描述方法):
Ubuntu下info文件中的内容 | Windows注册表中的键名 | Windows –> Ubuntu 转换方法 | Ubuntu –> Windows 转换方法 |
---|---|---|---|
[IdentityResolvingKey] 下的Key |
IRK |
2 | 1 |
[LocalSignatureKey] 下的Key |
CSRK |
2 | 1 |
[LongTermKey] 下的Key |
LTK |
2 | 1 |
[LongTermKey] 下的EDiv |
EDIV |
4 | 3 |
[LongTermKey] 下的Rand |
ERand |
6 | 5 |
修改key
Windows下获得key后(必要时用上一节表格中的转换方法转换),直接修改/var/lib/bluetooth/xx:xx:xx:xx:xx:xx/yy:yy:yy:yy:yy:yy/info
文件中对应的内容即可。如使用vim
修改(注意需要root权限):
sudo vim /var/lib/bluetooth/xx:xx:xx:xx:xx:xx/yy:yy:yy:yy:yy:yy/info
Windows
首先用上述第2.3.1节方法获得设备地址。
获得key
按第2.3.2节方法用系统管理员权限打开注册表编辑器。导航到HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\xxxxxxxxxxxx\yyyyyyyyyyyy
,其中xxxxxxxxxxxx
和yyyyyyyyyyyy
即蓝牙适配器地址和设备地址(Windows下没有冒号:)。然后在右边就可以找到类型为REG_BINARY
的CSRK
、IRK
和LTK
,以及类型为RED_DWORD
的EDIV
,以及类型为REG_QWORD
的ERand
。EDIV
和ERand
可以直接获取十进制的值用于Ubuntu下修改,免去转换。
同样也可以直接用如下命令导出:
X:\path\to\PSTools\PsExec.exe -s -i regedit /e X:\path\to\BT.reg HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys
然后用文本编辑器打开X:\path\to\BT.reg
,找到[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\xxxxxxxxxxxx\yyyyyyyyyyyy]
下的对应内容,如:
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\04ed33eaf253\f4ee25fe2468]
"LTK"=hex:aa,5a,b3,9b,a3,59,0e,11,d4,91,b7,99,36,10,f7,20
"KeyLength"=dword:00000010
"ERand"=hex(b):ea,dd,04,93,5d,e7,14,41
"EDIV"=dword:00006398
"IRK"=hex:09,be,cd,1f,b3,16,d0,e8,e6,7b,24,de,9f,8b,a0,80
"Address"=hex(b):68,24,fe,25,ee,f4,00,00
"AddressType"=dword:00000001
"CSRKInbound"=hex:ab,90,f2,4a,89,fe,5e,d1,fc,d4,ea,df,1e,01,14,15
"InboundSignCounter"=hex(b):ff,ff,ff,ff,ff,ff,ff,ff
"CSRK"=hex:d3,1b,8b,98,d5,9a,38,7d,83,b0,d5,5c,2c,50,57,b8
"OutboundSignCounter"=dword:00000000
"CEntralIRKStatus"=dword:00000001
"AuthReq"=dword:0000002d
其中键名后的等号=
后即是键的类型(hex
、dword
、hex(b)
),紧接着冒号:
之后的就是对应的值。
修改key
可以直接在系统管理员权限的注册编辑器中直接编辑HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\xxxxxxxxxxxx\yyyyyyyyyyyy
下对应的键的值。对于REG_BINARY
类型的CSRK
、IRK
和LTK
,直接双击打开然后把所有内容删除,然后把Ubuntu下获得的十六进制key填入即可。对于REG_DWORD
类型的EDIV
和REG_QWORD
类型的ERand
,双击打开后,把基数切换为十进制,然后对应填入Ubuntu下获得的数值即可。
亦或者可以新建一个注册表文件(假设保存为X:\path\to\BT.reg
),内容如下:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\BTHPORT\Parameters\Keys\xxxxxxxxxxxx\yyyyyyyyyyyy]
"LTK"=hex:aa,5a,b3,9b,a3,59,0e,11,d4,91,b7,99,36,10,f7,20
"ERand"=hex(b):ea,dd,04,93,5d,e7,14,41
"EDIV"=dword:00006398
"IRK"=hex:09,be,cd,1f,b3,16,d0,e8,e6,7b,24,de,9f,8b,a0,80
"CSRK"=hex:d3,1b,8b,98,d5,9a,38,7d,83,b0,d5,5c,2c,50,57,b8
xxxxxxxxxxxx
是蓝牙适配器地址,yyyyyyyyyyyy
是设备地址,对应的值替换为Ubuntu下获得的key(必要时用第3.1.1节表格中提到的转换方法转换)。
然后在终端管理员中使用如下命令导入:
X:\path\to\PSTools\PsExec.exe -s -i regedit /s X:\path\to\BT.reg
总结
在修改完成后,蓝牙设备可以立即连上使用。
简单流程:
- 在一个系统A里按正常配对方式连接蓝牙设备
- 到另一个系统B里同样按正常配对方式连接蓝牙设备
- 在最后连接的系统B里获取蓝牙设备对应的key
- 到系统A里修改对应的key
本方法除了可以用于同一台电脑共用蓝牙设备之外,在不同电脑上、不同系统上都可以共用,只要蓝牙适配器地址和设备地址正确即可,具体方法请自行举一反三。