行移位(ShiftRows):第一行保持不变,第二行循环左移1位,第三行循环左移2位,第四行循环左移3位。这种操作增强了数据的扩散性。
列混合(MixColumns):将每列视为GF(2^8)上的多项式,与固定多项式{03}x^3 + {01}x^2 + {01}x + {02}相乘。矩阵形式为:
[s0,c] [02 03 01 01] [s0,c]
[s1,c] = [01 02 03 01] [s1,c]
[s2,c] = [01 01 02 03] [s2,c]
[s3,c] [03 01 01 02] [s3,c]
轮密钥加(AddRoundKey):将状态矩阵与轮密钥进行按位异或操作。
3.解密算法流程
解密过程执行加密的逆操作,使用逆S盒、逆行移位、逆列混合等操作。逆列混合使用不同的变换矩阵,其系数为:
[0e 0b 0d 09]
[09 0e 0b 0d]
[0d 09 0e 0b]
[0b 0d 09 0e]
这些系数是加密时使用的系数在GF(2^8)中的乘法逆元。
4.填充机制
由于AES是分组密码,要求输入数据长度必须是128位(16字节)的倍数。代码实现了PKCS7填充标准:当最后一块数据恰好为16字节时,需要添加一个额外的16字节块,其中每个字节的值都是16(十六进制0x10);当最后一块数据少于16字节时,用N个字节填充至16字节,每个填充字节的值都是N。这种填充方式确保了解密时能够正确识别和移除填充字节。
5.安全特性
AES算法的安全性基于多个设计原则:
混淆性:S盒提供强烈的非线性变换,使得密钥和密文之间的关系复杂化。
扩散性:行移位和列混合操作确保明文的任何变化都会影响整个密文块。
雪崩效应:明文或密钥的微小变化会导致密文的显著变化,平均50%的输出位会发生改变。
6.算法复杂度
AES-256的计算复杂度为O(n),其中n是数据长度。对于128位分组,每轮需要进行16次字节替换、16次异或操作、16次列混合操作等。整个加密过程包含14轮完整操作,提供足够的安全强度。
7.应用场景
AES-256被广泛应用于各种安全通信协议中,包括SSL/TLS、IPSec、WPA2等。其256位密钥长度提供了约2^256的密钥空间,即使在量子计算攻击面前仍具有相当的安全性。
该算法的实现充分体现了现代分组密码的设计理念,通过简单的代数运算构建复杂的安全机制,为信息安全提供了可靠的保障。
% AES256-ECB-PKCS7Paddingclcclear all;%% 最后一个数据块刚好为16字节,则需要多加一个16字节数据块结尾,%最后16字节的数据中每个BYTE的值是数据块大小即16,Plaintext ='00112233445566778899aabbccddeeff' Padding = '10101010101010101010101010101010';Key ='000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' Ciphertext1 = Cipher(Key, Plaintext)Ciphertext2 = Cipher(Key, Padding)Plaintext1 = InvCipher(Key,Ciphertext1)Plaintext2 = InvCipher(Key,Ciphertext2)%% 最后一个数据块小于16字节,则需用几个Padding字节补齐成16个字节,% Padding Byte的值为Padding Byte的个数,Plaintext ='00112233445566778899aabbccdd' ;Padding = '0202';Plaintext = strcat(Plaintext , Padding);Key ='000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f' Ciphertext1 = Cipher(Key, Plaintext)Plaintext1 = InvCipher(Key,Ciphertext1)function a = xtime(x,c)a=0;if bitget(x,1) a=c;endx=bitshift(x,-1);while x>0 c=bitshift(c,1); if bitget(c,9) c=bitset(c,9,0); c=bitxor(c,27); end if bitget(x,1) a=bitxor(a,c); end x=bitshift(x,-1);endend function state = SubBytes(state)Sbox=['637c777bf26b6fc53001672bfed7ab76';... 'ca82c97dfa5947f0add4a2af9ca472c0';... 'b7fd9326363ff7cc34a5e5f171d83115';... '04c723c31896059a071280e2eb27b275';... '09832c1a1b6e5aa0523bd6b329e32f84';... '53d100ed20fcb15b6acbbe394a4c58cf';... 'd0efaafb434d338545f9027f503c9fa8';... '51a3408f929d38f5bcb6da2110fff3d2';... 'cd0c13ec5f974417c4a77e3d645d1973';... '60814fdc222a908846eeb814de5e0bdb';... 'e0323a0a4906245cc2d3ac629195e479';... 'e7c8376d8dd54ea96c56f4ea657aae08';... 'ba78252e1ca6b4c6e8dd741f4bbd8b8a';... '703eb5664803f60e613557b986c11d9e';... 'e1f8981169d98e949b1e87e9ce5528df';... '8ca1890dbfe6426841992d0fb054bb16'];Sbox=reshape(hex2dec(reshape(Sbox',2,[])'),16,16); state=Sbox(state+1);endfunction state = ShiftRows(state)state(2,:)=circshift(state(2,:),[0,-1]);state(3,:)=circshift(state(3,:),[0,-2]);state(4,:)=circshift(state(4,:),[0,-3]);endfunction State = MixColumns(state)State=state;for a=1:4:13 State(a)=bitxor(bitxor(bitxor(xtime(state(a),2),xtime(state(a+1),3)),state(a+2)),state(a+3)); State(a+1)=bitxor(bitxor(bitxor(xtime(state(a+1),2),xtime(state(a+2),3)),state(a)),state(a+3)); State(a+2)=bitxor(bitxor(bitxor(xtime(state(a+2),2),xtime(state(a+3),3)),state(a)),state(a+1)); State(a+3)=bitxor(bitxor(bitxor(xtime(state(a+3),2),xtime(state(a),3)),state(a+1)),state(a+2));endendfunction w = KeyExpansion(key)key=hex2dec(reshape(key,2,[])');w=reshape(key,4,[]);for i=8:59 temp=w(:,i); if mod(i,8)==0 temp=SubBytes(circshift(temp,[-1,0])); temp=bitxor(temp,[2^(i/8-1),0,0,0]'); elseif mod(i,8)==4 temp=SubBytes(temp); end w(:,i+1)=bitxor(w(:,i-7),temp);endendfunction state = InvSubBytes(state)Sbox=['52096ad53036a538bf40a39e81f3d7fb';... '7ce339829b2fff87348e4344c4dee9cb';... '547b9432a6c2233dee4c950b42fac34e';... '082ea16628d924b2765ba2496d8bd125';... '72f8f66486689816d4a45ccc5d65b692';... '6c704850fdedb9da5e154657a78d9d84';... '90d8ab008cbcd30af7e45805b8b34506';... 'd02c1e8fca3f0f02c1afbd0301138a6b';... '3a9111414f67dcea97f2cfcef0b4e673';... '96ac7422e7ad3585e2f937e81c75df6e';... '47f11a711d29c5896fb7620eaa18be1b';... 'fc563e4bc6d279209adbc0fe78cd5af4';... '1fdda8338807c731b11210592780ec5f';... '60517fa919b54a0d2de57a9f93c99cef';... 'a0e03b4dae2af5b0c8ebbb3c83539961';... '172b047eba77d626e169146355210c7d'];Sbox=reshape(hex2dec(reshape(Sbox',2,[])'),16,16); state=Sbox(state+1);endfunction state = InvShiftRows(state)state(2,:)=circshift(state(2,:),[0,1]);state(3,:)=circshift(state(3,:),[0,2]);state(4,:)=circshift(state(4,:),[0,3]);endfunction State = InvMixColumns(state)State=state;for a=1:4:13 State(a)=bitxor(bitxor(bitxor(xtime(state(a),14),xtime(state(a+1),11)),xtime(state(a+2),13)),xtime(state(a+3),9)); State(a+1)=bitxor(bitxor(bitxor(xtime(state(a),9),xtime(state(a+1),14)),xtime(state(a+2),11)),xtime(state(a+3),13)); State(a+2)=bitxor(bitxor(bitxor(xtime(state(a),13),xtime(state(a+1),9)),xtime(state(a+2),14)),xtime(state(a+3),11)); State(a+3)=bitxor(bitxor(bitxor(xtime(state(a),11),xtime(state(a+1),13)),xtime(state(a+2),9)),xtime(state(a+3),14));endendfunction Out = InvCipher(key,In)%change key to w%AES-256 inverse cipher%Impliments FIBS-197, key is 256-bit hexidecimal input, % message (In) is 128-bit hexidecimal.%David Hill%Version 1.0.1%12-21-2019In=hex2dec(reshape(In,2,[])');%w=KeyExpansion(key);%state=reshape(In,4,[]);state=AddRoundKey(state,w(:,57:60));for k=14:-1:2 state=InvShiftRows(state); state=InvSubBytes(state); state=AddRoundKey(state,w(:,4*(k-1)+1:4*k)); state=InvMixColumns(state);endstate=InvShiftRows(state);state=InvSubBytes(state);state=AddRoundKey(state,w(:,1:4));Out=state(:)';Out=lower(dec2hex(Out(1:length(In)))');%Out=Out(:)';%endfunction Out = Cipher(key,In)%change key to w%AES-256 cipher%Impliments FIBS-197, key is 256-bit hexidecimal input, % message (In) is 128-bit hexidecimal.%David Hill%Version 1.0.1%12-21-2019In=hex2dec(reshape(In,2,[])');%w=KeyExpansion(key);%state=reshape(In,4,[]);state=AddRoundKey(state,w(:,1:4));for k=2:14 state=SubBytes(state); state=ShiftRows(state); state=MixColumns(state); state=AddRoundKey(state,w(:,4*(k-1)+1:4*k));endstate=SubBytes(state);state=ShiftRows(state);state=AddRoundKey(state,w(:,57:60));Out=state(:);Out=lower(dec2hex(Out(1:length(In)))');%Out=Out(:)';%endfunction state = AddRoundKey(state,w)for k=1:4 state(:,k)=bitxor(state(:,k),w(:,k));endend