You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中计算BLE Passkey Entry模式的配对确认值

蓝牙低功耗(BLE)配对确认值生成(Passkey认证场景)

背景说明

我正在Python中实现BLE相关功能,配对流程里需要按照《蓝牙核心规范5.3》第1604页和1562f节的定义生成Pairing Confirm Value。已有f4函数,当认证方式为“Password Entry”时,需将6位验证码纳入计算,给定该验证码后需要生成对应的确认值(存在多个对应值)。

已有可用函数

已实现generateConfirmValue函数,代码如下:

def generateConfirmValue(
        self, keyX=None, remoteKeyX=None, localNonce=None, rbi=b"\x00"
    ):
        """
        生成配对确认值的类方法
        :param rbi: Passkey字节
        :type rbi: Byte
        :return: 确认值
        :rtype: Bytes
        """
        if not (keyX and remoteKeyX and localNonce):
            if self.keyX == None or self.remoteKeyX == None:
                io.warning("请先生成DH密钥")
                return
            if self.localNonce == None:
                io.warning("请先生成本地随机数(Nonce)")
                return
            keyX = self.keyX
            remoteKeyX = self.remoteKeyX
            localNonce = self.localNonce
        localConfirm = BLECryptoSC.f4(keyX, remoteKeyX, localNonce, rbi)
        return CryptoUtils.reverseOrder(localConfirm.hex())

需要实现的函数

目标是实现generateConfirmValueForPasskey函数,将6位Passkey转换为f4函数所需的rbi参数:

def generateConfirmValueForPasskey(self, keyX, remoteKeyX, localNonce, passkey, counter):
    passkeyByteForF4 = ...
    return generateConfirmValue(keyX, remoteKeyX, localNonce, rbi=passkeyByteForF4)

参考反向逻辑(翻译整理)

找到一个与需求逻辑相反的函数,其功能是从rbi字节还原对应的Passkey数字位,原逻辑翻译整理后代码如下:

def extract_passkey_digit(rbi, counter):
    # 将rbi字节转换为无符号整数(小端序)
    rbi_int = int.from_bytes(rbi, byteorder='little')
    # 根据counter定位Passkey对应位:counter=0对应个位,counter=1对应十位,直到counter=5对应十万位
    digit = (rbi_int // (10 ** counter)) % 10
    return digit

该逻辑的核心是:把rbi转成小端序整数后,通过整除10的counter次方再取模10,得到Passkey对应位置的数字。反向推导可知,我们需要为Passkey的每一位生成对应范围的rbi字节——对于6位Passkey的第counter位,rbi的取值范围是digit * 10^counter到min((digit+1)*10^counter - 1, 0xFF)之间的任意单字节值(单字节上限为0xFF,部分高位的取值范围会被限制)。

最终实现代码

基于上述反向逻辑,generateConfirmValueForPasskey的实现如下:

def generateConfirmValueForPasskey(self, keyX, remoteKeyX, localNonce, passkey, counter):
    # 校验Passkey合法性:必须是000000到999999之间的整数
    if not (0 <= passkey <= 999999):
        raise ValueError("Passkey必须是6位数字(范围000000-999999)")
    # 提取Passkey对应counter位置的数字
    digit = (passkey // (10 ** counter)) % 10
    # 计算rbi的基础值
    base = digit * (10 ** counter)
    # 计算rbi的最大有效值(不超过单字节上限0xFF)
    max_rbi = min(base + (10 ** counter) - 1, 0xFF)
    # 生成对应rbi字节(示例取基础值,也可选择范围内任意合法值)
    passkeyByteForF4 = base.to_bytes(1, byteorder='little')
    return self.generateConfirmValue(keyX, remoteKeyX, localNonce, rbi=passkeyByteForF4)

内容的提问来源于stack exchange,提问作者Pascal Rockenstiehl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 00:50:15