AES算法及具体步骤
AES 高级加密标准前言AES背景算法描述算法流程图State MatrixKey Expansiong函数
AddRoundKeyRound Function1. SubBytes2. ShiftRows3. MixColumns4. Add round key
Final Round
AES 高级加密标准
前言
之前一直想写CSDN博客但是没有找到可以写的内容,趁着最近刚好在学密码学就可以把自己学习时候的笔记贴上来啦。因为比较菜…所以内容几乎都是参考了教材、百度和wiki里面的,自己整理重述了一下~
AES背景
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,结合两位作者的名字,以Rijndael为名投稿高级加密标准的甄选流程。(Rijndael的发音近于"Rhine doll")
算法描述
在原始的Rijndael算法中分组长度和密钥长度都可变,各自可以独立的指定为128 bit、192 bit、256 bit。在AES中,分组长度只能是128 bit,也就是16个字节。(1个字节等于8位,1 Byte = 8 Bit)。密钥长度可以为三者中的任意一种。最广泛 的使用是密钥128 bit,迭代轮数10轮。
AES算法密钥长度(32 bit)分组长度(32 bit)加密和解密轮数AES-1284410AES-1926412AES-2568414
对称密钥使用相同的密钥进行加密和解密,因此发送者和接受者都必须知道并使用相同的秘密密钥。 本文主要基于AES-128。
算法流程图
这个流程图是在github上看到的,自己画的有点简陋,这个图非常清晰就拿来了2333 (后面有几张图好像也是,我把原链接贴在这里) 图源 link 自己重新整理了一下画的流程图大概长这样:
Round Function
9 times
Final Round
PlainText
AddRoundKey
Key
KeyExpansion
SubBytes
ShiftRows
MixColumns
AddRoundKey
SubBytes
ShiftRows
AddRoundKey
CipherText
下面就详细的讲一些流程图里面的每一个部分
State Matrix
Block cipher is a cryptosystem which encrypts data not by bit but by block,which is group of bits,applying algorithm per block.
分组密码不是按位对数据进行加密,而是按每一组对数据进行整体加密算法。所以首先对明文、密钥进行分组,每一组为1 byte(8 bit),16 x 8=128 bit,因此一共分成了16组,用 4 x 4矩阵表示,该矩阵就称为状态矩阵(State Matrix)。对应上图AddRoundKey和Key Expansion上方的矩阵。 用C++实现如下:
//将明文分组拷贝到状态矩阵中
unsigned char state[16];
for (int i = 0; i
//roundkey 和 state XOR!
for (int i = 0; i
//S盒字节替换
for (int i = 0; i
unsigned char tmp[16];
//tmp暂存行位移的结果
tmp[0] = state[0];
tmp[1] = state[5];
tmp[2] = state[10];
tmp[3] = state[15];
tmp[4] = state[4];
tmp[5] = state[9];
tmp[6] = state[14];
tmp[7] = state[3];
tmp[8] = state[8];
tmp[9] = state[13];
tmp[10] = state[2];
tmp[11] = state[7];
tmp[12] = state[12];
tmp[13] = state[1];
tmp[14] = state[6];
tmp[15] = state[11];
//行位移
for (int i = 0; i
unsigned char tmp[16];
//用临时数组保存
tmp[0] = (unsigned char)(mul2[state[0]] ^ mul3[state[1]] ^ state[2] ^ state[3]);
tmp[1] = (unsigned char)(state[0] ^ mul2[state[1]] ^ mul3[state[2]] ^ state[3]);
tmp[2] = (unsigned char)(state[0] ^ state[1] ^ mul2[state[2]] ^ mul3[state[3]]);
tmp[3] = (unsigned char)(mul3[state[0]] ^ state[1] ^ state[2] ^ mul2[state[3]]);
tmp[4] = (unsigned char)(mul2[state[4]] ^ mul3[state[5]] ^ state[6] ^ state[7]);
tmp[5] = (unsigned char)(state[4] ^ mul2[state[5]] ^ mul3[state[6]] ^ state[7]);
tmp[6] = (unsigned char)(state[4] ^ state[5] ^ mul2[state[6]] ^ mul3[state[7]]);
tmp[7] = (unsigned char)(mul3[state[4]] ^ state[5] ^ state[6] ^ mul2[state[7]]);
tmp[8] = (unsigned char)(mul2[state[8]] ^ mul3[state[9]] ^ state[10] ^ state[11]);
tmp[9] = (unsigned char)(state[8] ^ mul2[state[9]] ^ mul3[state[10]] ^ state[11]);
tmp[10] = (unsigned char)(state[8] ^ state[9] ^ mul2[state[10]] ^ mul3[state[11]]);
tmp[11] = (unsigned char)(mul3[state[8]] ^ state[9] ^ state[10] ^ mul2[state[11]]);
tmp[12] = (unsigned char)(mul2[state[12]] ^ mul3[state[13]] ^ state[14] ^ state[15]);
tmp[13] = (unsigned char)(state[12] ^ mul2[state[13]] ^ mul3[state[14]] ^ state[15]);
tmp[14] = (unsigned char)(state[12] ^ state[13] ^ mul2[state[14]] ^ mul3[state[15]]);
tmp[15] = (unsigned char)(mul3[state[12]] ^ state[13] ^ state[14] ^ mul2[state[15]]);
//将数据复制到state
for (int i = 0; i |