物理安全设计:外壳防拆开关、螺丝防拆检测、光敏传感器布局

好,咱们接着聊物理安全设计。这一块说白了,就是给POS机穿上「铠甲」,再装上「警报器」。你想想看,攻击者想窃取密钥或者篡改固件,第一步肯定是拆机。所以,物理防拆就是第一道防线。

我个人习惯把物理安全分成三个层次:被动防御(让你拆起来费劲)、主动检测(你一拆我就知道)、响应销毁(知道了就立刻擦除敏感数据)。今天咱们重点讲主动检测这部分——外壳防拆开关、螺丝防拆检测、光敏传感器布局。

一、外壳防拆开关:最直接的「门禁」

外壳防拆开关,说白了就是一个微动开关或者弹片开关。正常合盖时,外壳压住开关,电路保持闭合状态。一旦开盖,开关弹起,触发中断。

这里有个关键点:开关的安装位置。我见过不少设计,把开关放在螺丝孔旁边。结果呢?攻击者用薄片从缝隙插进去,先顶住开关再拧螺丝,完美绕过检测。

避坑指南: 防拆开关必须安装在「开盖瞬间必然触发」的位置。比如外壳卡扣的正下方、电池仓的压合面。我曾经在一个项目里,把开关藏在屏幕排线下面——攻击者不拆排线根本碰不到开关,而拆排线本身就会触发另一个检测点。

电路设计上,我建议用常闭型开关。为什么?因为常开型开关一旦断线或者虚焊,系统就永远检测不到开盖了。常闭型则相反——断线等同于开盖,触发报警,这叫「故障安全」设计。

// 伪代码:防拆开关检测逻辑
#define TAMPER_SWITCH_PIN  GPIO_PIN_5

void TamperSwitch_Init(void) {
    GPIO_Init(TAMPER_SWITCH_PIN, GPIO_MODE_IT_FALLING_EDGE);
    HAL_NVIC_SetPriority(EXTI5_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(EXTI5_IRQn);
}

void EXTI5_IRQHandler(void) {
    if (__HAL_GPIO_EXTI_GET_IT(TAMPER_SWITCH_PIN) != RESET) {
        // 检测到开盖!立即触发安全擦除
        SecureErase_KeyMaterial();
        // 记录日志,不可擦除
        WriteTamperLog(TAMPER_SOURCE_SWITCH);
        __HAL_GPIO_EXTI_CLEAR_IT(TAMPER_SWITCH_PIN);
    }
}

二、螺丝防拆检测:别小看那颗螺丝

普通螺丝刀就能拆的螺丝,对攻击者来说毫无难度。真正的防拆螺丝,你得用专用工具才能拧。但光靠螺丝本身不够——你得检测它「有没有被拧动」。

我常用的方案有两种:

  • 导电螺丝+PCB焊盘:螺丝拧紧后,螺帽接触PCB上的两个焊盘,形成回路。一旦螺丝松动,回路断开,触发报警。
  • 磁性螺丝+霍尔传感器:螺丝头部嵌有磁铁,PCB上对应位置放霍尔传感器。螺丝拧紧时,磁场强度固定;螺丝松动或更换,磁场变化,触发检测。

这里有个坑:导电螺丝方案里,焊盘容易氧化。我遇到过一批设备,出厂时好好的,放了半年后焊盘氧化,螺丝拧紧也接触不良,天天误报。后来我改成了镀金焊盘+弹簧顶针,再也没出过问题。

方案 优点 缺点 适用场景
导电螺丝+焊盘 成本低、电路简单 焊盘易氧化、接触不可靠 低成本产品、短期使用
磁性螺丝+霍尔 非接触、寿命长、抗污染 成本稍高、需校准阈值 高安全等级、长期部署
我的经验: 如果预算允许,优先选磁性螺丝方案。霍尔传感器可以同时检测「螺丝松动」和「螺丝被替换」——因为不同磁铁的磁场强度不一样。我曾经用这个特性抓到一个试图用普通螺丝替换防拆螺丝的攻击者。

三、光敏传感器布局:防「开天窗」

光敏传感器,用来检测「有没有不该有的光」。攻击者有时候不拆外壳,而是用激光或者X射线从外壳缝隙照射进去,试图读取存储器内容。或者,他们在外壳上钻一个小孔,伸入光纤探头。

光敏传感器的布局,我总结了三原则:

  1. 覆盖所有关键区域:主控芯片、加密芯片、存储器附近必须放。
  2. 避免死角:传感器之间距离不要超过5cm,确保任何位置的光线都能被至少一个传感器捕捉。
  3. 考虑环境光干扰:别一有光就触发,得设置合理的阈值。

嗯,这里要注意:光敏传感器不能直接暴露在外壳上,否则正常使用时的环境光就会触发报警。我一般会在传感器上方加一个遮光罩,只留一个小孔对准外壳内壁。这样,只有外壳被打开或钻孔时,光线才能进入。

// 光敏传感器阈值设置示例
#define LIGHT_SENSOR_THRESHOLD  50  // 根据实际环境标定

uint32_t ReadLightSensor(ADC_HandleTypeDef* hadc) {
    HAL_ADC_Start(hadc);
    if (HAL_ADC_PollForConversion(hadc, 100) == HAL_OK) {
        return HAL_ADC_GetValue(hadc);
    }
    return 0xFFFF;  // 读取失败,按最坏情况处理
}

void CheckLightTamper(ADC_HandleTypeDef* hadc) {
    uint32_t light_val = ReadLightSensor(hadc);
    if (light_val > LIGHT_SENSOR_THRESHOLD) {
        // 检测到异常光照
        SecureErase_KeyMaterial();
        WriteTamperLog(TAMPER_SOURCE_LIGHT);
    }
}
关键提醒: 光敏传感器的ADC采样要定期做,但不能太频繁——频繁采样会增加功耗,也容易被攻击者预测时序。我一般用「随机间隔采样」,比如每100ms到300ms之间随机取一个时间点。这样攻击者很难找到「无采样窗口」来打激光。

四、三种检测机制的联动

单独用任何一种,都有被绕过的风险。真正的安全设计,是让它们协同工作

举个例子:攻击者想从外壳钻孔。他先得避开螺丝防拆检测(磁性螺丝方案),然后在不触发外壳开关的情况下钻孔(几乎不可能),最后还得躲过光敏传感器(钻孔瞬间光线进入)。三重检测,只要触发任何一个,系统就立刻擦除密钥。

我习惯在固件里做一个防拆状态机

  • 正常状态:所有传感器都正常,系统正常运行。
  • 警告状态:某个传感器触发,但可能是误报(比如用户不小心碰了一下)。系统记录日志,但不立即擦除,而是启动一个「确认计时器」。
  • 锁定状态:计时器到期前再次触发,或者多个传感器同时触发。系统立即擦除密钥,并进入不可恢复的锁定状态。

这个状态机的好处是:既能防止误报导致的数据丢失,又能对真正的攻击做出快速响应。我曾经在一个项目里,用户把POS机摔了一下,外壳开关瞬间触发又复位。状态机只记录了警告,没有擦除数据——用户重启后一切正常。要是没有这个状态机,那台机器就得返厂了。

小技巧: 防拆日志要存储在「不可篡改」的区域,比如OTP存储器或者外部安全芯片。这样即使攻击者成功读取了Flash,也无法抹去被拆过的痕迹。审计时一看日志,就知道这台机器被「动过手脚」。

好了,物理安全设计这块,核心就是「让攻击者无处下手」。外壳开关、螺丝检测、光敏传感器,这三样东西组合起来,基本能挡住90%的物理攻击。剩下的10%,就得靠更高级的「主动屏蔽层」和「自毁电路」了——那是后面章节的内容。