只要是做开发,加解密这关绕不开AES。但凡涉及敏感数据落库、接口传输、文件加密,第一反应都是上AES。但很多人只会调库,根本没搞懂它到底怎么把数据弄成乱码又还原回来的。AES的原理其实不复杂,拆开看就是几个变换反复转,懂了之后你调参、选模式、判断安不安全才有底气。
AES是什么、从哪来
AES全称高级加密标准,是2001年美国国家标准与技术研究院NIST发布的,标准号FIPS 197。它取代了老的DES。DES的密钥只有56位,算力上去后暴力破解不再是难事,1998年就有专门的机器几小时破掉DES,所以NIST搞了个全球征集,最后选了两个比利时人设计的Rijndael算法,改名AES。AES的分组固定128位,也就是16字节一次处理,密钥可选128、192、256位三档。
对称加密的意思是加密和解密用同一把密钥,跟RSA那种公钥私钥分开的非对称不一样。对称快,适合大数据量;非对称慢,适合传密钥。实际系统里常见组合是用非对称协商出AES密钥,再用AES加密正文,兼顾安全和速度。
轮数和密钥长度的关系
AES的轮数由密钥长度决定。128位密钥跑10轮,192位跑12轮,256位跑14轮。每一轮包括四个变换:字节替换SubBytes、行移位ShiftRows、列混淆MixColumns、轮密钥加AddRoundKey。这四步合起来叫轮函数,第一轮之前还有个初始的轮密钥加,最后一轮省略列混淆。
字节替换是用一个叫S盒的查表,把每个字节映射成另一个字节,引入非线性。行移位是把状态的行循环左移不同位数。列混淆是用有限域上的矩阵乘法把列里的字节混到一起。轮密钥加是把每轮派生出的子密钥和状态异或。这套设计叫替换置换网络SPN,特点是每一比特都迅速扩散到整个分组,几轮下来输入的每个比特都影响输出的每个字节,雪崩效应强。
密钥长度怎么选
三档密钥对应的安全强度不同。128位密钥提供128位安全强度,按当前算力暴力穷举2的128次方,现实不可行。192位和256位强度更高。一般应用128位已经够,性能也最好。金融、政务等高安全场景用256位。需要注意的是,256位不是因为快被破解才上的,是留余量。
密钥越长轮数越多,性能略降。实测256位比128位慢百分之二三十,看场景取舍。移动端、物联网设备资源紧张时,128位是更均衡的选择。别迷信无脑上256,多数场景下128位的安全余量足够。
分组模式才是关键
很多人用AES出问题不在算法本身,在分组模式。AES一次只处理16字节,数据长于16字节就得切分成多个块,怎么切怎么串就是模式的事。老模式ECB把相同明文块加密成相同密文块,会泄露数据模式,对着企鹅图加密还是能看出企鹅轮廓,所以ECB别用。
现在主流是GCM模式,带认证,加密同时产出认证标签,能防篡改,性能也好,硬件有专门指令加速。CBC模式也常见,但需要IV且要防重放,没认证的话容易遭填充攻击。CTR模式把AES当流密码用,并行友好。简单结论:能用GCM就GCM,需要认证选AEAD类模式,别再用ECB。
常见问题
【AES能被破解吗?】目前没有实用的攻击能破掉完整AES。理论攻击像 biclique对128位密钥也只把安全强度降到约126位,仍是天文数字。实际泄露多因密钥管理不当、IV复用、模式用错,不是算法本身。
【AES-256一定比128安全吗?】理论上安全强度更高,但256位的密钥扩展算法有个已知的弱密钥类相关攻击,理论意义大于实际。对绝大多数场景,128位已足够,256位是给未来的余量。
【密钥怎么生成和保存?】用密码学安全的随机源,Linux上读dev/urandom或用语言库的SecureRandom,别用普通随机。密钥别硬编码进代码、别进日志、别进版本库,用密钥管理服务或环境变量注入。
【AES和RSA怎么配合?】典型做法是随机生成一次性AES密钥加密数据,再用对方RSA公钥加密这个AES密钥一起传,对方用RSA私钥解出AES密钥再解数据。这样大数据用快的AES,小密钥用慢的RSA,各取所长。