加密过程
先将输入的明文按列序组合成4*4的矩阵,直接与第0组密钥(即输入的密钥)相加(异或),作为轮加密的输入
然后循环10次进行SubBytes、ShiftRows、MixColumns、AddRoundKey运算,最后恢复原序列
需要注意的是最后一轮并不进行MixColumns(列混淆变换)
unsigned char* AES::Cipher(unsigned char* input) {
unsigned char state[4][4]; int i,r,c;
for(r=0; r<4; r++){
for(c=0; c<4 ;c++) {
state[r][c] = input[c*4+r]; } }
AddRoundKey(state,w[0]); for(i=1; i<=10; i++){ SubBytes(state); ShiftRows(state);
if(i!=10)MixColumns(state); AddRoundKey(state,w[i]); }
for(r=0; r<4; r++) { for(c=0; c<4 ;c++){
input[c*4+r] = state[r][c]; } }
return input; }
解密过程
unsigned char* AES::InvCipher(unsigned char* input) {
unsigned char state[4][4]; int i,r,c;
for(r=0; r<4; r++) {
for(c=0; c<4 ;c++) {
state[r][c] = input[c*4+r]; } }
AddRoundKey(state, w[10]); for(i=9; i>=0; i--) {
InvShiftRows(state); InvSubBytes(state); AddRoundKey(state, w[i]); if(i)InvMixColumns(state); }
for(r=0; r<4; r++) {
for(c=0; c<4 ;c++) {
input[c*4+r] = state[r][c]; } }
return input; }
对外部数据的加密/解密
至此已经实现了AES加密与解密的原型,在使用的时候一般处理的是字符串等,而不是直接传入128位的数据,所以要封装一下对外部数据的加解密处理
void* AES::Cipher(void* input, int length) {
unsigned char* in = (unsigned char*) input; int i; if(!length) {
while(*(in+length++)); in = (unsigned char*) input; }
for(i=0; i return input; } void* AES::InvCipher(void* input, int length){ unsigned char* in = (unsigned char*) input; int i; for(i=0; i return input; } 加密时默认参数length=0,为要加密的数据长度,如果使用默认值,则作为字符串处理,以'\\0'为结尾计算长度 加密时传进的指针要预留够16整数倍字节的空间,因为加密操作直接修改原数据,不足128位可能造成内存溢出