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安全启动的完整流程,把这些密码学算法串起来。到时候你会看到,它们是怎么协同工作的。

嗯,今天就到这儿。有什么问题,咱们课后交流。