2、密码学基础回顾:对称加密(AES)、非对称加密(RSA/ECC)、哈希函数(SHA-256)、HMAC
好,咱们正式开始讲密码学基础。说实话,很多做FPGA的工程师一听到「密码学」三个字就头大,觉得那是软件工程师的事。但我得说,在硬件安全领域,你不懂这些基本算法,连芯片怎么被攻破的都不知道。
这一节我会把四个核心概念讲透:AES、RSA/ECC、SHA-256、HMAC。不扯虚的,直接说它们在FPGA里怎么用、有什么坑。
2.1 对称加密:AES
对称加密,说白了就是加密和解密用同一把钥匙。你想想看,就像你家大门,用一把钥匙锁上,也用同一把钥匙打开。AES是目前最主流的对称加密算法,没有之一。
AES支持三种密钥长度:128位、192位、256位。在FPGA安全启动场景里,我个人习惯用AES-256,虽然面积大一点,但安全余量足。128位也不是不行,只是万一哪天量子计算真来了,128位就悬了。
核心要点:AES在FPGA里通常用ECB或CBC模式。但ECB模式有安全缺陷——同样的明文块会生成同样的密文块。我建议用CBC模式,加一个初始向量(IV),安全性高很多。
我在项目中遇到过一件事:有个同事为了省资源,在FPGA里用了ECB模式加密启动镜像。结果攻击者通过分析密文块重复模式,直接猜出了部分明文内容。嗯,从那以后,我坚决不用ECB。
AES的硬件实现,一般包含这几个步骤:
- 字节代换(SubBytes):用S盒做非线性替换
- 行移位(ShiftRows):矩阵行循环移位
- 列混合(MixColumns):矩阵列混合运算
- 轮密钥加(AddRoundKey):与轮密钥异或
在FPGA里,S盒通常用LUT实现,或者用Block RAM查表。我个人偏好用BRAM,因为速度快、时序好控制。
小技巧:如果你用Xilinx的FPGA,可以调用AES的硬核IP。但注意,有些低端芯片没有硬核,只能用LUT拼。这时候面积会大不少,要做好心理准备。
2.2 非对称加密:RSA与ECC
非对称加密,就是加密和解密用不同的钥匙。一把公钥公开,一把私钥自己藏好。你想想看,这就像个信箱——谁都能往里面投信(公钥加密),但只有你有钥匙能打开(私钥解密)。
在FPGA安全启动里,非对称加密主要用来做数字签名验证和密钥交换。最常见的两个算法是RSA和ECC。
2.2.1 RSA
RSA基于大整数分解的数学难题。简单说:两个大质数相乘很容易,但把乘积分解回两个质数极难。RSA的密钥长度通常是2048位或4096位。
我记得有一次做项目,需要在FPGA里实现RSA-2048签名验证。一开始我用软件实现,结果一次签名验证要好几秒。后来改成硬件加速,用Montgomery模乘器,速度才提上来。
RSA在FPGA里的实现,核心是模幂运算:
// 伪代码:RSA模幂运算
result = 1;
base = message;
exp = public_exponent;
mod = modulus;
while (exp > 0) {
if (exp & 1) {
result = (result * base) % mod;
}
base = (base * base) % mod;
exp = exp >> 1;
}
但注意,直接这么写会有时序问题。实际工程里要用Montgomery模乘,把取模运算变成移位和加法,硬件实现才高效。
避坑指南:我曾经在RSA实现里忘了做侧信道防护。结果攻击者通过分析功耗曲线,直接恢复了私钥。后来我加了随机延时和掩码技术,才堵住这个漏洞。记住:在FPGA里做密码,光算法对还不够,还得防物理攻击。
2.2.2 ECC(椭圆曲线密码学)
ECC用更短的密钥提供和RSA相当的安全性。比如256位的ECC,安全性和3072位的RSA差不多。在FPGA里,ECC的优势是面积小、速度快。
ECC的核心是椭圆曲线上的点乘运算:Q = k * P。其中k是私钥,P是基点,Q是公钥。这个运算在硬件里实现,主要靠点加和点倍两个操作。
我个人觉得,ECC比RSA更适合FPGA。为什么?因为ECC的运算主要是模加、模乘、模逆,这些在FPGA里用DSP48和BRAM就能高效实现。而RSA的大数模幂,对资源消耗更大。
| 算法 | 密钥长度 | 安全等级 | FPGA资源消耗 | 典型应用 |
|---|---|---|---|---|
| RSA-2048 | 2048位 | 112位 | 高(需大量DSP) | 数字签名、密钥交换 |
| ECC-256 | 256位 | 128位 | 中(DSP+BRAM) | 签名验证、密钥协商 |
| AES-256 | 256位 | 256位 | 低(LUT+BRAM) | 数据加密 |
2.3 哈希函数:SHA-256
哈希函数,说白了就是数据指纹。不管输入多长,输出固定长度(SHA-256输出256位)。而且,哪怕输入只改一个比特,输出也会面目全非。
在FPGA安全启动里,SHA-256用来校验镜像完整性。比如你烧录一个启动镜像,先算它的哈希值存起来。下次启动时重新算一遍,对比一下就知道镜像有没有被篡改。
SHA-256的硬件实现,核心是压缩函数。它把512位的消息块,压缩成256位的摘要。过程包括:
- 消息扩展:把16个32位字扩展到64个
- 64轮迭代:每轮用不同的常数和逻辑函数
- 最终加和:把中间结果加到初始值上
我在项目中实现SHA-256时,发现一个常见问题:时序收敛困难。因为64轮迭代的路径太长,频率上不去。后来我用了流水线结构,把64轮拆成4级流水,每级16轮,频率从100MHz提到了250MHz。
注意:SHA-256是单向函数,不可逆。你不能从哈希值反推出原始数据。所以它只能用来校验完整性,不能用来加密。
2.4 HMAC:带密钥的哈希
HMAC,全称是Hash-based Message Authentication Code。它就是在哈希函数的基础上,加了一把密钥。你想想看,普通哈希只能防篡改,但防不了伪造。因为谁都能算哈希值。而HMAC只有知道密钥的人才能算,所以能同时保证完整性和真实性。
HMAC的计算公式(简化版):
HMAC(K, M) = H( (K' ⊕ opad) || H( (K' ⊕ ipad) || M ) )
其中:
- K' 是经过填充的密钥
- opad 是外填充(0x5c重复)
- ipad 是内填充(0x36重复)
- H 是哈希函数(比如SHA-256)
在FPGA里实现HMAC,其实就是两次调用SHA-256。第一次算内层哈希,第二次算外层哈希。但要注意,两次哈希的初始值不同,需要重新加载。
我曾经犯过一个低级错误:在HMAC实现里,把密钥直接暴露在了总线上。结果攻击者通过探测总线信号,直接拿到了密钥。后来我改成密钥只在安全区内使用,用寄存器存着,不经过总线传输。
经验之谈:在FPGA安全启动里,HMAC通常用来做固件签名验证。比如你烧录一个固件,先用HMAC算一个标签存起来。启动时重新算标签,对比一致才允许加载。这样既能防篡改,又能防伪造。
2.5 小结
好了,这一节的内容就这些。咱们回顾一下:
- AES:对称加密,速度快,适合大量数据加密。FPGA里用CBC模式,别用ECB。
- RSA/ECC:非对称加密,适合密钥交换和数字签名。ECC在FPGA里更省资源。
- SHA-256:哈希函数,校验数据完整性。FPGA实现注意流水线设计。
- HMAC:带密钥的哈希,同时保证完整性和真实性。密钥要藏好。
下一节,咱们会讲FPGA安全启动的完整流程,把这些密码学算法串起来。到时候你会看到,它们是怎么协同工作的。
嗯,今天就到这儿。有什么问题,咱们课后交流。