【LMP】规范精讲[6]: 从陌生到互信——安全简单配对(SSP)的四步握手

上一篇讲加密时多次提到一个前提:链路钥匙从哪来。旧版蓝牙用 PIN 码配对,安全性堪忧;4.2 规范中安全简单配对(Secure Simple Pairing,SSP)才是答案。这次把 SSP 完整流程拆开,看看两台陌生设备如何在几秒内建立起密码学信任。


目录

一、四阶段总览

[二、阶段一:IO 能力交换------摸清对方家底](#二、阶段一:IO 能力交换——摸清对方家底)

[2.1 三要素一次报清](#2.1 三要素一次报清)

[2.2 OOB 数据的矩阵](#2.2 OOB 数据的矩阵)

[2.3 碰撞消解](#2.3 碰撞消解)

[三、阶段二:公钥交换------ECDH 的底座](#三、阶段二:公钥交换——ECDH 的底座)

[3.1 分片传输](#3.1 分片传输)

[3.2 P-192 与 P-256 的选择](#3.2 P-192 与 P-256 的选择)

[3.3 公钥验证](#3.3 公钥验证)

四、阶段三:认证之一------三种关联模型

[4.1 数值比对](#4.1 数值比对)

[4.2 密码输入](#4.2 密码输入)

[4.3 带外](#4.3 带外)

[4.4 按键通知](#4.4 按键通知)

[4.5 失败处理](#4.5 失败处理)

[五、阶段四:DH Key 校验------最后一道关卡](#五、阶段四:DH Key 校验——最后一道关卡)

[5.1 双向校验](#5.1 双向校验)

[5.2 链路钥匙生成](#5.2 链路钥匙生成)

[5.3 无效公钥的防御](#5.3 无效公钥的防御)

[5.4 校验失败:两种结局与一条铁律](#5.4 校验失败:两种结局与一条铁律)

[5.5 配对完成后的认证与加密](#5.5 配对完成后的认证与加密)

六、代码理解两处关键

[6.1 承诺-揭示防篡改](#6.1 承诺-揭示防篡改)

[6.2 密码输入的逐位验证](#6.2 密码输入的逐位验证)

[七、SSP 的设计哲学](#七、SSP 的设计哲学)

八、测验


先看空口抓包记录下 SSP 完整四阶段,八条消息走完从陌生到互信的全过程:

八条消息分四个阶段:IO 能力交换打前站,双方各发一轮 Encapsulated 公钥分片,认证阶段一先发承诺再揭示随机数,认证阶段二双向 DH Key 校验。1.77 秒走完全程,中间 1.42 秒的空档是用户确认和协议栈做 ECDH 计算的时间。主机侧的配对产物也能对上:

Key Type 标着 Unauthenticated-192,正是 P-192 曲线数值比对关联模型的直接产物。

一、四阶段总览

规范把 SSP 定义为四个阶段, IO capabilities exchange、 Public key **exchange、Authentication stage 1、Authentication stage 2。**阶段一决定走哪条认证路线,阶段二交换公钥搭好 DH 密钥协商的底座,阶段三在两条路线中选择一条完成用户参与的关联验证,阶段四用 DH Key 做最终密码学校验并生成链路钥匙。

发起 IO 能力请求的设备叫 Initiator,这个身份贯穿 SSP 全流程不变。阶段一之前,双方先确认 Simple_Pairing_Mode 是否都开启。只有双方都开启,SSP 才走得下去。

二、阶段一: IO 能力交换------摸清对方家底

2.1 三要素一次报清

Initiator 发 LMP_IO_CAPABILITY_REQ,Responder 回 LMP_IO_CAPABILITY_RES。两个 PDU 各带三个参数:IO_Capabilities(输入输出能力)、OOB_Auth_Data(带外认证数据状态)、Authentication_Requirements(认证需求)。

IO 能力分五档 :DisplayOnly、DisplayYesNo、KeyboardOnly、NoInputNoOutput、KeyboardDisplay。

认证需求分四档:MITM Protection Not Required -- No Bonding、MITM Protection Not Required -- Dedicated Bonding、MITM Protection Required -- No Bonding、MITM Protection Required -- Dedicated Bonding。Bonding 指是否把配对结果存下来供后续连接复用。MITM 指是否需要防中间人攻击。

2.2 OOB 数据的矩阵

OOB_Auth_Data 参数的设置规则藏着一个精巧的矩阵。带外数据有两种:P-192 的和 P-256 的。不支持安全连接的设备只能生成 P-192 OOB 数据。矩阵的设计目的是:双方各自报告自己的 OOB 数据拥有情况,协议据此决定是否走 OOB 认证路线。

关键规则在阶段三的选择逻辑中:只要有一方声明 OOB Data Received,就走 OOB 路线。双方都没收到 OOB 数据时,看 MITM 需求:都不要求 MITM 走数值比对;至少一方要求 MITM 且有一方是 KeyboardOnly 走密码输入,否则仍走数值比对。

2.3 碰撞消解

如果双方同时发 LMP_IO_CAPABILITY_REQ,Central 侧收到后回 LMP_NOT_ACCEPTED_EXT,错误码 0x23 事务碰撞。Peripheral 侧随后正常回 LMP_IO_CAPABILITY_RES,Central 继续担任 Initiator。和认证那篇的碰撞消解思路一致:Central 在碰撞中总是赢家。

三、阶段二:公钥交换------ECDH 的底座

3.1 分片传输

公钥太长,一个 DM1 包装不下。规范用 LMP_ENCAPSULATED_HEADER 加 LMP_ENCAPSULATED_PAYLOAD 的分片机制传输。HEADER 声明载荷类型和总长度,PAYLOAD 逐段搬运。Initiator 先发自己的公钥,Responder 回自己的公钥。双方收完最后一帧 PAYLOAD 并回 ACCEPTED 后,就可以开始算 DH Key。

空口工具把分片过程聚合为单条 LMP Encapsulated P-192 Public Key,底层实际是多帧分片往返。抓包里 Central 发公钥耗时 90ms(50.798-50.889),Peripheral 回公钥耗时 46ms。

3.2 P-192 与 P-256 的选择

规范原文:

When at least one device does not support Secure Connections, the P-192 curve shall be used for calculating the public and private keys. When both devices support Secure Connections, the P-256 curve shall be used.

木桶效应第三次出现。认证那篇决定降级用 E0 还是 AES-CCM;加密那篇决定降级用 f5/f6 还是 h4/h5/h6;这篇决定降级用 P-192 还是 P-256。同一个 SC 特性位,三处影响。P-192 是 192 位椭圆曲线,P-256 是 256 位。安全等级差异明显。抓包里对端缺 SC Host 支持,走 P-192,主机侧记录 Key Type=Unauthenticated-192 直接印证。

3.3 公钥验证

收到的公钥不是拿来就用,要验。Part H 7.6 定义了验证规则:

公钥 Q = (XQ, YQ) 合法的条件是 XQ 和 YQ 都在 0 到 p-1 范围内,并且满足椭圆曲线方程 YQ^2 = XQ^3 + aXQ + b (mod p)。验证方法可以是直接检查曲线方程,也可以通过在正确曲线上实现点加和点倍来间接验证。如果发现公钥非法,阶段四的 DHKey Check 会故意发一个错误值让对方校验失败,从而终止配对。这是 SSP 防御恶意公钥注入的机制。

四、阶段三:认证之一------三种关联模型

规范定义了三种关联模型(Association Model),选择逻辑在阶段一完成后自动确定:

  • OOB:任一方声明 OOB Data Received 时启用

  • 数值比对:双方都不要求 MITM 时启用

  • 密码输入:至少一方要求 MITM 且一方是 KeyboardOnly 时启用,否则仍走数值比对

关联模型的核心目的:给用户一个区分真假对端的机会。ECDH 本身能防被动窃听,但无法防主动中间人------攻击者可以分别与双方完成 DH 交换。关联模型引入用户参与,用低带宽的人机交互通道验证对端身份。

4.1 数值比对

公钥交换完成后,双方各生成一个 128 位随机数 Na 和 Nb。Responder 用 f1 算出承诺值 Cb 发给 Initiator。Initiator 收到后发自己的随机数 Na,Responder 验证后回 Nb。双方再用 g 函数算出六位数字,显示给用户比对。

f1 函数的定义在 Part H 7.7.1:

f1(U, V, X, Z) = HMAC-SHA-256X(U || V || Z) ÷ 2^128,取 HMAC 输出的最高 128 位。U 和 V 是双方公钥的 x 坐标,X 是随机数,Z 是 8 位协议标识。数值比对和 OOB 场景下 Z 全零;密码输入场景下 Z 的最高位恒为 1,最低位取 passkey 的一位(1→0x81,0→0x80),这个设计让 f1 的每一轮输出都和 passkey 的当前位绑定。

g 函数的定义在 Part H 7.7.2:

g(U, V, X, Y) = SHA-256(U || V || X || Y) mod 2^32,取 SHA-256 输出的最低 32 位,转十进制后取最低六位作为用户比对值。六位数字是安全性与可用性的折中:太短容易碰撞,太长用户读不完。

承诺-揭示(commit-disclose)是防止攻击者事后篡改随机数的经典手法。Responder 先发承诺值 Cb,这个值绑定了 Nb 但不泄露 Nb。Initiator 发 Na 后,Responder 揭示 Nb,Initiator 用 f1 验证 Nb 确实对应 Cb。如果攻击者想伪造 Nb 使 g 输出特定值,必须在看到 Cb 之前算出一个满足条件的 Nb,这在计算上不可行。

空口正好对上:Peripheral 先发 Simple Pairing Confirmation(承诺值 Cb),Central 随后发 Simple Pairing Number(Na),Peripheral 回 Nb,Central 验证后回 Accepted。标准数值比对流程。

抓包还有个细节值得注意:从 Simple Pairing Number 到 DH Key Check 之间有 1.42 秒的空档。这段时间用户在看屏幕上显示的六位数字并按确认键,同时控制器在算 ECDH 共享密钥。HCI 侧的 User Confirmation Request 就在这段空档内上下交互。

4.2 密码输入

密码输入的安全等级更高,代价是流程重得多。一个六位密码有 20 位,协议把密码拆成 20 个比特,每个比特跑一轮完整的承诺-揭示。20 轮循环,每轮双方各生成新随机数、算 f1 承诺(这次 Z 里的 passkey 位每轮不同)、交换承诺、交换随机数、互相验证。

为什么逐位验证?如果一轮验证整个密码,攻击者可以离线暴力破解。逐位验证意味着攻击者每轮只能猜一个比特,猜错就被踢出局。20 轮中攻击者必须每轮都猜对,概率是 1/2^20 ≈ 1/1048576。这是 SSP 最精妙的安全设计之一。

每轮的 f1 输入稍有不同:U 和 V 仍是双方公钥 x 坐标,X 是本轮随机数,Z 的最低位取当前轮的 passkey 位。20 轮跑完,双方各自持有 20 对随机数(Na1..Na20, Nb1..Nb20),供阶段四的 f3 校验使用。

4.3 带外

OOB 模式跳过用户交互,用带外信道(NFC、二维码等)传递认证信息。设备从 Host 拿到 OOB 数据后,用收到的秘密数和远端公钥计算承诺值,与 Host 提供的承诺值比对。如果本地没有 OOB 数据,远端秘密数置零继续计算。

OOB 的安全假设是带外信道不被中间人劫持。如果攻击者能同时篡改蓝牙信道和带外信道,OOB 也防不住。但实际场景中,NFC 的近场特性或二维码的视觉验证天然限制了攻击者的能力。

4.4 按键通知

当 IO 能力设为 KeyboardOnly 且双方支持 SSP 时,控制器通过 LMP_KEYPRESS_NOTIFICATION 通知远端按键事件。这个机制让远端可以在密码输入过程中实时显示已输入位数,提升用户体验。不影响安全模型,只是交互优化。

4.5 失败处理

三种关联模型的失败处理有一个共同原则:认证失败不等于断连。规范反复强调 The Link Managers shall not disconnect the connection。数值比对失败发 LMP_NUMERIC_COMPARISON_FAILED,密码输入失败发 LMP_PASSKEY_ENTRY_FAILED,OOB 失败发 LMP_OOB_FAILED。配对中止但链路保留,给上层重试的机会。

五、阶段四:DH Key 校验------最后一道关卡

5.1 双向校验

阶段三验证了用户的参与,阶段四验证密码学计算的正确性。双方用 DH Key、阶段三交换的随机数、IO 能力等参数,通过 f3 函数计算校验值 Ea 和 Eb。Initiator 先发 LMP_DHKEY_CHECK 携带 Ea,Responder 验证后回 Eb,Initiator 再验证。双向校验确保双方持有相同的 DH Key,且都正确完成了阶段三。

规范的原始描述值得细读,两个方向的校验各有一段:

The Initiator shall send an LMP_DHKEY_CHECK PDU to the Responder... Upon reception, if the received value is not equal to the one calculated according to Vol 2 Part H, Section 7.7.4, or if the received public key is invalid, then the Responder shall follow the procedure in Section 4.2.7.4.1. Otherwise it shall reply with an LMP_ACCEPTED PDU.

注意校验的条件是复合的:确认值不等或者公钥非法,任一条件命中都走失败流程。Responder 验证通过后角色反转,Responder 发自己的校验值,Initiator 做同样的复合校验。两次校验全过,阶段四才算走完,Sequence 73 画的正是这个对称的双向流程:

f3 函数定义在 Part H 7.7.4:

f3(W, N1, N2, R, IOcap, A1, A2) = HMAC-SHA-256W(N1 || N2 || R || IOcap || A1 || A2) ÷ 2^128。W 是 DH Key,N1/N2 是阶段三的随机数,R 在数值比对场景为零、OOB 场景为对方的随机数、密码输入场景为最后一轮的随机数,IOcap 是 24 位 IO 能力摘要(认证需求、OOB 状态、IO 能力各 8 位),A1/A2 是双方地址。

IOcap 这个设计很巧妙。把阶段一交换的 IO 能力信息纳入 f3 的输入,意味着如果攻击者在阶段一和阶段四之间篡改了某方的 IO 能力声明,f3 校验值就对不上。整个 SSP 的四阶段通过 f3 被绑定成一个不可分割的整体。

5.2 链路钥匙生成

DHKey Check 双向通过后,双方用 f2 函数生成链路钥匙:

LK = f2(DHKey, Nc, Np, "btlk", BD_ADDR_C, BD_ADDR_P)

f2 定义在 Part H 7.7.3,HMAC-SHA-256 以 DHKey 为密钥,输入两段随机数、固定字符串 btlk(ASCII 0x62746C6B)和双方地址。输出取最高 128 位作为链路钥匙。Nc 是 Central 生成的随机数,Np 是 Peripheral 的,确保钥匙与角色绑定。

5.3 无效公钥的防御

如果 Initiator 发现 Responder 的公钥非法,阶段四会发一个故意错误的 DHKey Check 值(比如用随机数替代),让 Responder 校验失败并中止配对。规范原文:

If the Initiator has determined that the received public key is invalid, the PDU shall include a confirmation value that is different from the computed confirmation value (for example, substituting a randomly generated number).

不直接报错而是发错误值,这是为了不向攻击者暴露检测到非法公钥的信息------攻击者只看到配对失败,无法确定是公钥校验阶段还是 DHKey 校验阶段挂掉的。

5.4 校验失败:两种结局与一条铁律

失败处理单列一节,因为这里的细节容易被忽略。失败可能发生在两个位置:Responder 校验 Initiator 的值时挂掉,或者 Initiator 校验 Responder 回传的值时挂掉。两种场景的时序不同:

第一种,Responder 侧失败:Initiator 发出 DHKEY_CHECK,Responder 算出值对不上,直接回 LMP_NOT_ACCEPTED,流程就此打住------Responder 根本不会发自己的校验值。Sequence 74 画的这条短路径只有两条消息。

**第二种,Initiator 侧失败:**第一轮校验顺利通过,Responder 回 ACCEPTED 并发出自己的 DHKEY_CHECK,Initiator 算完发现对不上,回 NOT_ACCEPTED。Sequence 75 的路径多出一对交互。

失败原因规范分了两类:收到无效公钥(Part H 7.6 的曲线方程校验不过),或者确认值与本地计算不一致。两类原因殊途同归,都回 LMP_NOT_ACCEPTED 并附 Authentication Failure 理由。而且规范在此处钉了一条总原则:

A device that detects an invalid public key from the peer at any point during the Secure Simple Pairing process shall fail the pairing process and therefore not create a link key.

公钥检查不必等到阶段四才做,任何时点发现对端公钥非法都立即判配对失败,链路钥匙绝不落盘。这是防御的最后底线------宁可配对失败,不让一把基于污染密钥材料的钥匙存活。

失败后的处置和阶段三的原则一脉相承:The Link Managers shall not disconnect the connection。配对中止,链路保留,上层可以择机重试。

5.5 配对完成后的认证与加密

链路钥匙到手不代表 SSP 收工,规范紧接着安排了两件事。

第一,启动互认证,走哪条路由 SC 特性位决定,木桶效应第四次登场:

If at least one device does not support both the Secure Connections (Controller Support) and Secure Connections (Host Support) features, the Initiator shall then start standard mutual authentication as described in Section 4.2.1.1. If both devices support both... the Initiator shall then start secure authentication as described in Section 4.2.1.4.

第二,安全认证完成后如果链路已启用加密,Initiator 要暂停并立即恢复加密。规范特意加了一条 Note 解释这么做的用意:

Note: This will cause a new encryption key to be generated using the h3 function including the ACO created during the secure authentication process.

新链路钥匙配新 ACO,h3 重新计算加密密钥,旧的加密上下文彻底作废。这段流程和上一篇加密暂停/恢复完美衔接:SSP 产出链路钥匙,认证产出 ACO,暂停恢复用 h3 生成新加密密钥,三条线在这里交汇。抓包里 DH Key Check 通过后紧跟 Authentication Transaction 和 Encryption Mode,正是这条收尾链路在空口上的投影。

六、代码理解两处关键

6.1 承诺-揭示防篡改

cpp 复制代码
import hmac, hashlib, secrets

def hmac_sha256_x(key_x, msg):
    # key_x: 128-bit key, msg: bytes
    full = hmac.new(key_x, msg, hashlib.sha256).digest()
    return full[:16]  # 取最高128位

def f1(pkax, pkbx, nonce, z):
    # pkax, pkbx: 公钥x坐标(各192/256位), nonce: 128位随机数, z: 8位协议标识
    return hmac_sha256_x(nonce, pkax + pkbx + z)

# 数值比对: Responder先发承诺Cb=f1(PKbx,PKax,Nb,0), Initiator后发Na,
# Responder揭示Nb, Initiator验证f1(PKbx,PKax,Nb,0)==Cb

承诺值 Cb 绑定了 Nb 但不泄露 Nb。攻击者要在看到 Cb 前伪造一个满足条件的 Nb,等于在攻破 HMAC-SHA-256 的抗原像性,计算上不可行。

6.2 密码输入的逐位验证

cpp 复制代码
def passkey_round(passkey_bit, pkax, pkbx, nonce):
    # passkey_bit: 0或1, 每轮取密码的一位
    z = 0x81 if passkey_bit else 0x80  # 最高位恒1, 最低位取passkey位
    return f1(pkax, pkbx, nonce, bytes([z]))

# 20轮循环, 每轮z不同, 攻击者每轮只能猜1个比特
# 20轮全猜对的概率 = 1/2^20 ≈ 1/1048576
for i in range(20):
    bit = (passkey >> (19 - i)) & 1  # 从高位到低位逐位验证
    commitment = passkey_round(bit, pkax, pkbx, secrets.token_bytes(16))
    # ... 承诺-揭示流程

每轮 Z 的值不同,f1 输出就不同。攻击者每轮只能猜一个比特,猜错立即出局。20 轮全过的概率约百万分之一,这就是 SSP 密码输入抗中间人攻击的数学基础。

七、SSP 的设计哲学

回看整个 SSP,设计者面临的核心矛盾是:蓝牙设备输入输出能力参差不齐,有的有屏幕有键盘,有的什么都没有,但所有设备组合都要能用且安全。SSP 的解法是分层:ECDH 提供被动机密性(防窃听),关联模型提供主动防御(防中间人),f2/f3 把各阶段信息绑定成不可分割的整体。

数值比对面向有屏幕的设备,密码输入面向有键盘的设备,OOB 面向有 NFC 等带外信道的设备。三种模型覆盖了现实中的设备组合,而选择逻辑完全由 IO 能力和认证需求自动决定,用户不需要理解密码学细节。

失败不断连是另一处值得品味的设计。配对失败原因可能是用户按错、密码输错、信号干扰、甚至对端固件 bug。保留链路让上层可以重试,避免因一次配对失败就断开所有服务。这和认证那篇的 detach 策略形成对比:认证失败(身份伪造嫌疑)直接断连,配对失败(流程异常)保留链路。安全等级决定后果严重程度。

最后看 HCI 侧的配对产物。Key Type=Unauthenticated-192 这个标记说明配对走的是 P-192 曲线的数值比对(数值比对在无 MITM 场景下产出 Unauthenticated 钥匙)。重连时控制器直接上报 Link Key Request,Host 回钥匙即可,配对不再重来------这就是 Bonding 的意义:配对一次,信任存续。

八、测验

问题一:SSP 数值比对模式中,为什么 Responder 要先发承诺值再揭示随机数,而不是直接发随机数?如果直接发会怎样?

答案:

这是承诺方案的经典应用。如果直接发随机数,攻击者可以等待双方都发完随机数后,计算 g 函数的结果,然后篡改其中一方的随机数使 g 输出攻击者期望的六位数字。承诺-揭示流程中,Responder 先发 Cb = f1(PKbx, PKax, Nb, 0),这个值绑定 Nb 但不泄露 Nb(HMAC 的单向性保证)。Initiator 必须在看到 Cb 后就发 Na,此时 Nb 还未揭示。攻击者无法在知道 Nb 的情况下篡改 Na 使 g 输出特定值。等 Responder 揭示 Nb 后,Initiator 用 f1 验证 Nb 确实对应之前收到的 Cb,篡改行为会被发现。简言之,承诺值锁死了 Nb,攻击者失去事后调整的窗口。

问题二:SSP 密码输入模式为什么要跑 20 轮而不是一次性验证整个密码?这样做的安全收益和代价分别是什么?

答案:

安全收益是抗主动中间人的逐位验证。一次性验证整个密码时,攻击者可以记录认证流量后离线暴力破解,六位密码只有一百万种组合。逐位验证时,攻击者每轮只能猜一个比特,猜错立即被踢出局。20 轮全猜对的概率为 1/2^20 ≈ 百万分之一,且每轮失败都会中止配对,攻击者没有多次尝试的机会。f1 的 Z 参数设计是关键:每轮 Z 的最低位取 passkey 的当前位(1→0x81, 0→0x80),使每轮的承诺值与当前 passkey 位绑定,攻击者无法重放或跳过某一轮。代价是流程重------20 轮承诺-揭示往返,消息量是数值比对的数十倍,配对时间长。因此密码输入只在有键盘但无屏幕的设备组合下使用。

问题三:SSP 阶段四的 DHKey Check 如果发现对端公钥非法,为什么不直接报错而是发一个故意错误的校验值?

答案:

为了不向攻击者暴露检测到非法公钥的信息。如果直接发错误码,攻击者知道是公钥验证阶段挂掉的,可以调整策略重试,比如换一个合法但精心构造的公钥继续探测。发故意错误的校验值让攻击者看到的是和正常校验失败一样的结果------配对失败、流程中止,无法区分是公钥非法还是 DHKey 计算不一致。这种设计遵循安全协议的不泄露原则:不给攻击者提供额外的信息来区分失败原因。另外规范要求配对失败不断连,攻击者无法通过连接是否断开来判断失败阶段,进一步减少了侧信道信息。


相关推荐
2301_777998344 小时前
ARP协议进阶:ARP缓存、RARP与ARP欺骗原理解析
linux·服务器·网络·网络协议·缓存
昂好的day12 小时前
VisionMaster 通信模块实战(上):Modbus、TCP 收发、协议组装解析
开发语言·网络·网络协议·tcp/ip·c#
盛世宏博智慧档案16 小时前
算力机房多协议融合:Modbus TCP 温湿度变送器与 SNMP 设备混合组网方案
网络·网络协议·tcp/ip·传感器·温湿度
川石课堂软件测试18 小时前
涨薪技术|0到1学会性能测试第9课-HTTP响应统计
数据库·功能测试·网络协议·http·kubernetes·单元测试·测试用例
可信时间戳19 小时前
原创作品怎么申请版权?草稿、定稿、已发布、已授权,四个阶段四个做法
网络协议·http·https
话梅姐姐呀19 小时前
TCP/IP 架构各层的协议概述
人工智能·物联网·网络协议·tcp/ip·iot
husterlichf20 小时前
网关、掩码、子网、vlan、交换机
网络·网络协议
斌糖雪梨1 天前
registerListeners(); 方法详解
网络·网络协议·rpc
福芯微电子有限公司nfc1 天前
国产收音芯片 FSV4755:多波段调谐与高集成设计,赋能多种音频终端
网络协议·网络安全·音视频·信息与通信·信号处理