第⼀层:编译期开关
4.1 启用Application Security
在对应芯片的da145xx_config_basic.h中:
#defineCFG_APP_SECURITY
该宏会使BLE_APP_SEC为1,把应⽤层安全任务、回调和BondDB支持编译进⼯程。若取消定义,安全相关应⽤代码会被裁剪。
只取消CFG_APP_SECURITY并不会⾃动把所有GATT服务改成明⽂访问;如果服务仍要求认证或加密,客⼾端访问可能失败。因此关闭安全时还要同步检查服务权限。
4.2启用LE Secure Connections
在对应芯片的da145xx_config_advanced.h中:
#defineCFG_ENABLE_SMP_SECURE
该宏映射为ENABLE_SMP_SECURE==1,让协议栈支持P-256 ECDH和LE SecureConnections。
如果不定义它,app_easy_security.c会主动清除GAP_AUTH_SEC位,强制使用Legacy Pairing。也就是说,仅在USER_CFG_FEAT_AUTH_REQ中写GAP_AUTH_SEC,但没有编译CFG_ENABLE_SMP_SECURE,不会得到Secure Connections。
SDK注释还说明:
DA14585/586/531启⽤后通常在系统启动后创建⼀次ECDH key pair;
DA14531-01/DA14535在收到配对请求后创建ECDH key pair;
只使⽤Legacy时可以关闭该功能,以减少启动时间和RAM占⽤。
4.3随机数配置
安全示例默认启⽤:
#defineCFG_TRNG #defineCFG_USE_CHACHA20_RAND
DA14585配置形式为:
#defineCFG_TRNG (1024)
本SDK调用链如下:
左右滑动查看完整内容
app_sec_gen_tk()/app_sec_gen_ltk() ->co_rand_word() ->dia_rand() ->csprng_get_next_uint32() (启用 ChaCha20 时)
系统初始化时,TRNG采样⽤于给标准PRNG或ChaCha20 CSPRNG播种。安全⼯程建议同时启⽤TRNG和ChaCha20,不应以固定常量、未初始化的rand()或可预测时间戳替代。
5
第⼆层:user_security_conf配置项
示例在
projects/target_apps/ble_examples/ble_app_security/src/config/user_config.h
中定义宏,最终填⼊:
左右滑动查看完整内容
staticconststructsecurity_configurationuser_security_conf = {
.iocap = USER_CFG_FEAT_IO_CAP,
.oob = USER_CFG_FEAT_OOB,
.auth = USER_CFG_FEAT_AUTH_REQ,
.key_size = USER_CFG_FEAT_KEY_SIZE,
.ikey_dist = USER_CFG_FEAT_INIT_KDIST,
.rkey_dist = USER_CFG_FEAT_RESP_KDIST,
.sec_req = USER_CFG_FEAT_SEC_REQ,
};
5.1iocap:本机真实输⼊输出能力
可选值定义在sdk/ble_stack/host/gap/gap.h:

这⾥必须填写产品的真实能⼒。例如硬件没有按键,却声明DISPLAY_YES_NO并在代码中⾃动确认,会让协议栈认为已经获得用户确认,但实际上没有提供预期的MITM防护。
模式由双方IO Capability联合决定,不能只看本机。例如本机DISPLAY_ONLY:
对端为KB_ONLY或KB_DISPLAY:通常是本机显⽰、对端输⼊Passkey;
对端为NO_INPUT_NO_OUTPUT:只能退化为Just Works;
在LESC中,DISPLAY_ONLY没有Yes/No输⼊,因此不能进⾏Numeric Comparison。
5.2oob:是否已有对端OOB数据
左右滑动查看完整内容
#defineUSER_CFG_FEAT_OOB GAP_OOB_AUTH_DATA_NOT_PRESENT
或:
左右滑动查看完整内容
#defineUSER_CFG_FEAT_OOB GAP_OOB_AUTH_DATA_PRESENT
SDK 6.0.24的应⽤层明确把OOB限定为Legacy Pairing:⼀旦本地配置OOB present,app_easy_security.c会清除GAP_AUTH_SEC,强制⾛Legacy。
安全示例中的OOB值是固定演示数据:
左右滑动查看完整内容
#defineAPP_SECURITY_OOB_TK_VAL
{0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}
量产时必须替换为通过真实OOB信道获得的数据,并保证OOB信道本⾝具备所需的机密性和防篡改能⼒。
5.3auth:请求的认证特性
USER_CFG_FEAT_AUTH_REQ是位组合:
| 位 | 含义 |
| GAP_AUTH_BOND | 请求绑定,成功后保存密钥 |
| GAP_AUTH_MITM | 请求具备MITM防护的关联模式 |
| GAP_AUTH_SEC | 表示支持并请求Secure Connections |
| GAP_AUTH_KEY | Keypress Notification; 示例注释说明未⽀持 |
常见写法:
左右滑动查看完整内容
// Legacy Just Works + Bonding #defineUSER_CFG_FEAT_AUTH_REQ GAP_AUTH_BOND // Legacy Passkey/OOB + Bonding #defineUSER_CFG_FEAT_AUTH_REQ (GAP_AUTH_BOND | GAP_AUTH_MITM) // 优先 Secure Connections,要求 MITM,并绑定 #defineUSER_CFG_FEAT_AUTH_REQ (GAP_AUTH_BOND | GAP_AUTH_MITM | GAP_AUTH_SEC)
auth表⽰本机提出的能⼒和要求,但不⼀定等于最终结果。是否会回退、是否必须拒绝较低安全级别,还要看sec_req。
5.4sec_req:本机可接受的最低安全级别
这是SDK配置中最容易忽略、也最重要的⼀项:
| 值 | 含义 |
| GAP_NO_SEC | 不要求安全 |
| GAP_SEC1_NOAUTH_PAIR_ENC | ⾄少加密,但允许未经认证的配对,例如Just Works |
| GAP_SEC1_AUTH_PAIR_ENC | ⾄少为经过认证的配对 和加密 |
| GAP_SEC1_SEC_PAIR_ENC | 要求经过认证的LE Secure Connections和加密 |
| GAP_SEC2_NOAUTH_DATA_SGN | 未认证的数据签名模式 |
| GAP_SEC2_AUTH_DATA_SGN | 认证的数据签名模式 |
例如:
左右滑动查看完整内容
.auth = GAP_AUTH_BOND | GAP_AUTH_MITM | GAP_AUTH_SEC, .sec_req = GAP_SEC1_NOAUTH_PAIR_ENC,
这表⽰本机请求SC和MITM,但最低只要求“加密即可”。当对端能⼒不⾜时,仍可能接受Legacy或Just Works。
若产品明确禁⽌降级,应使⽤:
左右滑动查看完整内容
#defineUSER_CFG_FEAT_SEC_REQ GAP_SEC1_SEC_PAIR_ENC
并确保双⽅IO能⼒可以完成认证,否则配对会失败。对于⽆输入无输出的LESC Just Works,本SDK没有单独表示“必须是SC、但允许unauthenticated”的 sec_req枚举值;GAP_SEC1_SEC_PAIR_ENC表⽰认证的SC,不能与⽆MITM的Just Works等同。
5.5key_size:加密密钥长度
左右滑动查看完整内容
#defineUSER_CFG_FEAT_KEY_SIZE KEY_LEN// 16 bytes
允许范围是7〜16字节。最终使用双方支持值中较小者。除非必须兼容特殊旧设备,建议保持16字节,并让受保护服务的策略拒绝过短密钥。
6位Passkey只有约20bit信息量;把key_size设成16并不会提升Legacy Passkey本⾝的熵,但会避免额外截短最终密钥。
5.6ikey_dist与rkey_dist:密钥分发
ikey_dist表示initiator分发的集合,rkey_dist表示responder分发的集合。外设示例通常处于responder⻆⾊,因此本地需要发送哪些密钥主要体现在RESP_KDIST,但实际结果仍由双方协商。
LESC在LE传输上直接派生LTK,EncKey分发位不会像Legacy那样发送LTK/EDIV/Rand;本SDK通过EDIV==0识别LESC LTK。
如果产品使用RPA隐私地址,应保留GAP_KDIST_IDKEY并正确保存IRK。若不使用signedwrite,可考虑不分发GAP_KDIST_SIGNKEY,减少无用状态。




