**:
先搞定aes演算法,基本變換包括subbytes(位元組替代)、shiftrows(行移位)、mixcolumns(列混淆)、addroundkey(輪金鑰加)
其演算法一般描述為
明文及金鑰的組織排列方式
bytesubstitution(位元組替代)
非線性的位元組替代,單獨處理每個位元組:
求該位元組在有限域gf(28)上的乘法逆,"0"被對映為自身,即對於α∈gf(28),求β∈gf(28),
使得α·β=β·α=1mod(x8+x4+x2+x+1)。
對上一步求得的乘法逆作仿射變換
yi=xi + x(i+4)mod8 + x(i+6)mod8 + x(i+7)mod8 + ci
(其中ci是6310即011000112的第i位),用矩陣表示為
本來打算把求乘法逆和仿射變換演算法敲上去,最後還是放棄了...直接打置換表
unsigned char sbox =
;
下面是逆置換表,解密時使用
unsigned char invsbox[256] =
;
這裡遇到問題了,本來用純c初始化陣列很正常,封裝成類以後發現不能初始化,不管是宣告、建構函式都無法初始化,百歌谷度了一通後沒有任何答案,無奈只能在建構函式中宣告乙個區域性變數陣列並初始化,然後用memcpy,(成員變數名為sbox/invsbox,區域性變數名sbox/invsbox)
void aes::subbytes(unsigned char state[4]) } }
shiftrows(行移位變換)
行移位變換完成基於行的迴圈位移操作,變換方法:
即行移位變換作用於行上,第0行不變,第1行迴圈左移1個位元組,第2行迴圈左移2個位元組,第3行迴圈左移3個位元組。
void aes::shiftrows(unsigned char state[4])
for(c=0; c<4; c++) } }
mixcolumns(列混淆變換)
逐列混合,方法:
矩陣表示形式:
}其中ffmul為有限域gf(28)上的乘法,標準演算法應該是迴圈8次(b與a的每一位相乘,結果相加),但這裡只用到最低2位,解密時用到的逆列混淆也只用了低4位,所以在這裡高4位的運算是多餘的,只計算低4位。
addroundkey(輪金鑰加變換)
簡單來說就是逐字節相加,有限域gf(28)上的加法是模2加法,即異或
void aes::addroundkey(unsigned char state[4], unsigned char k[4]) } }
keyexpansion(金鑰擴充套件)將輸入的金鑰擴充套件為11組128位金鑰組,其中第0組為輸入金鑰本身
其後第n組第i列 為 第n-1組第i列 與 第n組第i-1列之和(模2加法,1<= i <=3)
對於每一組 第一列即i=0,有特殊的處理
將前一列即第n-1組第3列的4個位元組迴圈左移1個位元組,並對每個位元組進行位元組替代變換subbytes
將第一行(即第乙個位元組)與輪常量rc[n]相加
最後再與前一組該列相加
解密的基本運算aes解密演算法與加密不同,基本運算中除了addroundkey(輪金鑰加)不變外,其餘的都需要進行逆變換,即void aes::keyexpansion(unsigned char* key, unsigned char w[4][4])
; for(r=0; r<4; r++)
} for(i=1; i<=10; i++)
if(j == 0)
t[3] = sbox[temp];
t[0] ^= rc[i-1];
} for(r=0; r<4; r++)
} }
}
invsubbytes(逆位元組替代)、invshiftrows(逆行移位)、invmixcolumns(逆列混淆)
void aes::invsubbytes(unsigned char state[4])
} }
void aes::invshiftrows(unsigned char state[4])
for(c=0; c<4; c++)
} }
void aes::invmixcolumns(unsigned char state[4])
for(r=0; r<4; r++) } }
加密過程先將輸入的明文按列序組合成4*4的矩陣,直接與第0組金鑰(即輸入的金鑰)相加(異或),作為輪加密的輸入
然後迴圈10次進行subbytes、shiftrows、mixcolumns、addroundkey運算,最後恢復原序列
需要注意的是最後一輪並不進行mixcolumns(列混淆變換)
unsigned char* aes::cipher(unsigned char* input)
} addroundkey(state,w[0]);
for(i=1; i<=10; i++)
for(r=0; r<4; r++)
} return input;
解密過程
unsigned char* aes::invcipher(unsigned char* input)
} addroundkey(state, w[10]);
for(i=9; i>=0; i--)
for(r=0; r<4; r++)
} return input;
}
對外部資料的加密/解密至此已經實現了aes加密與解密的原型,在使用的時候一般處理的是字串等,而不是直接傳入128位的資料,所以要封裝一下對外部資料的加解密處理
void* aes::cipher(void* input, int length)
for(i=0; i
加密時預設引數length=0,為要加密的資料長度,如果使用預設值,則作為字串處理,以'\0'為結尾計算長度
加密時傳進的指標要預留夠16整數倍位元組的空間,因為加密操作直接修改原資料,不足128位可能造成記憶體溢位
AES加密演算法
aes加密演算法 加密模式 ecb模式 優點 1.簡單 2.有利於平行計算 3.誤差不會被傳送 缺點 1.不能隱藏明文的模式 2.可能對明文進行主動攻擊 cbc模式 優點 1.不容易主動攻擊,安全性好於ecb,適合傳輸長度長的報文,是ssl ipsec的標準。缺點 1.不利於平行計算 2.誤差傳遞 ...
AES加密演算法
aes對稱加密演算法下有好多種演算法,往往很難做到垮語言的加密解密,本文提供一套c 和node.js可以相互加密解密通用的 之aes 256 cbc演算法 1 aes所有的鑰匙必須 128位 16位元組 192位 24位元組 或256位 32位元組 長 2 有幾種操作模式,每個都有不同的優點和缺點。...
AES加密演算法
aes的基本要求是 比三重des快 至少與三重des一樣安全 資料分組長度為128 bit 金鑰長度為128 192 256 bit,對應於金鑰的不同長度,加密輪的次數也不盡相同。選定rijndael演算法為新的aes演算法。演算法的原型是square演算法,其設計策略為寬軌跡策略 針對差分分析和線...