第2章 物理不可克隆函数(PUF):芯片的“基因指纹”

各位同学,今天我们来聊聊PUF。说实话,我第一次接触这个概念时,觉得它像科幻小说里的东西——利用芯片制造过程中的微小差异来生成唯一指纹?听起来不太靠谱对吧?

但后来我在一个安全芯片项目中真正用上了PUF,才发现这东西确实有两把刷子。嗯,让我慢慢道来。

2.1 什么是PUF?

物理不可克隆函数,英文叫Physically Unclonable Function。说白了,就是利用芯片制造时不可避免的工艺偏差,给每颗芯片生成一个独一无二的“指纹”。

你想想看,即使是同一片晶圆上相邻的两颗芯片,它们的晶体管阈值电压、线宽、氧化层厚度都会有细微差别。这些差别在宏观上可能无关紧要,但在微观层面,它们就是每颗芯片的“基因”。

核心思想:PUF不是把密钥存进芯片,而是从芯片的物理特性中“提取”出密钥。这意味着即使攻击者拿到芯片,也无法通过逆向工程读出密钥——因为密钥根本不存在于任何存储单元中。

2.2 PUF的工作原理

PUF的工作流程其实很简单:

  1. 激励输入:给PUF电路一个输入信号(称为挑战)
  2. 物理响应:芯片内部的物理差异会生成一个独特的输出信号(称为响应)
  3. 挑战-响应对:一组挑战和对应的响应就构成了CRP(Challenge-Response Pair)

我在一个物联网安全项目中,就用PUF来生成设备唯一ID。当时甲方要求每颗芯片的密钥必须不同,而且不能存储在Flash里。PUF正好解决了这个痛点。

个人经验:PUF的响应并不是100%稳定的。温度变化、电压波动、芯片老化都会影响输出。所以实际应用中需要配合纠错电路(ECC)来保证可靠性。我曾经因为忽略了这一点,导致一批芯片在高温下认证失败...嗯,教训深刻。

2.3 常见的PUF结构

目前业界主流的PUF结构有几种,我挑三个最常用的讲讲:

类型 原理 优点 缺点
环形振荡器PUF 利用振荡器频率差异 实现简单,数字友好 功耗较高,面积大
SRAM PUF 利用SRAM上电时的随机状态 零额外面积(复用SRAM) 需要上电序列,易受环境干扰
仲裁器PUF 利用路径延迟差异 速度快,CRP数量多 对建模攻击敏感

我个人比较喜欢SRAM PUF,因为它不需要额外电路。你想想看,芯片里本来就有SRAM,上电时每个bit的初始值都是随机的——这不就是现成的PUF吗?

2.4 PUF的应用场景

PUF在安全领域的应用主要有两个方向:

2.4.1 身份认证

服务器事先记录芯片的CRP数据库。认证时,服务器发送一个挑战,芯片返回响应。如果匹配,就证明芯片是正品。这有点像生物识别中的指纹验证。

我在一个防伪溯源项目中就用过这个方案。每颗芯片出厂前,我们都会采集100组CRP存入服务器。后续产品流通中,扫码就能验证真伪。效果还不错,至少客户没再抱怨被山寨货坑了。

2.4.2 密钥生成

这是PUF更重要的应用。把PUF的响应经过哈希和纠错处理后,直接作为加密密钥。好处很明显:密钥不存储在任何非易失性存储器中,只在需要时临时生成。

注意:PUF生成的密钥不能直接使用。因为响应有噪声,每次生成的密钥可能略有不同。必须配合模糊提取器(Fuzzy Extractor)和纠错码来稳定输出。我见过有人直接拿PUF响应当AES密钥,结果芯片一发热就解密失败...千万别这么干。

2.5 PUF的安全性与挑战

PUF也不是万能的。我总结几个关键问题:

  • 建模攻击:如果攻击者收集到足够多的CRP,可以用机器学习模型来预测响应。仲裁器PUF尤其容易中招。
  • 环境敏感性:温度从-40°C到125°C,PUF响应可能变化10%-20%。需要精心设计纠错电路。
  • 老化效应:芯片用久了,物理特性会漂移。我做过加速老化测试,10年后PUF的误码率可能翻倍。

那怎么应对呢?我的建议是:

  1. 使用强PUF结构(如基于哈希的PUF)来抵抗建模攻击
  2. 设计宽温度范围的纠错方案
  3. 定期校准和刷新PUF参考值

2.6 知识体系总览

下面这张图总结了PUF的核心知识结构,我画了很久才满意:

物理不可克隆函数(PUF)知识体系 PUF核心原理 工作原理:激励→响应 常见结构:RO/SRAM/仲裁器 应用场景:认证/密钥生成 CRP数据库 物理不可克隆性 环形振荡器PUF SRAM PUF 仲裁器PUF 设备身份认证 安全密钥生成 主要挑战:建模攻击/环境敏感/老化 应对策略:强PUF结构 + 纠错电路 + 定期校准 图:PUF知识体系总览

2.7 代码示例:PUF响应提取流程

下面是一个简化的PUF响应提取伪代码,实际项目中会复杂得多:

// PUF响应提取流程(伪代码)
function extractPUFResponse(challenge):
    // 1. 施加挑战
    applyChallenge(challenge)
    
    // 2. 读取原始PUF响应
    raw_response = readPUFCircuit()
    
    // 3. 纠错处理(使用BCH码)
    corrected_response = BCH_decode(raw_response, reference_code)
    
    // 4. 哈希压缩
    final_key = SHA256(corrected_response)
    
    return final_key

这段代码看着简单,但实际调试时坑不少。我记得有一次,纠错码的参数没调好,导致误码率高达5%。后来花了整整一周才找到最优的BCH码参数组合。

2.8 小结

PUF是个好东西,但也不是银弹。它解决了密钥存储的安全问题,却引入了可靠性和环境敏感性的新挑战。做PUF设计时,我建议你记住三点:

  • 选对PUF结构:根据应用场景选,别盲目追求高熵
  • 做好纠错设计:这是PUF落地的关键
  • 考虑全生命周期:从出厂到老化,都要测试

好了,这一章就到这里。PUF的内容其实很深,我们后面还会在安全架构章节中继续讨论。


公众号:蓝海资料掘金营,微信deep3321