雙向遍歷加密算法
一、算法原理
我們可以將明文看成一個Byte數(shù)組A[N],加解密過程就是對這個數(shù)組的運算。首先,我們從頭到尾對它進(jìn)行一次正向的遍歷,在遍歷的同時將每次遇到的元素的值與前一個元素的值疊加,并寫回到數(shù)組中。即A[i]+A[i-1]=>A[i](i從2遞增到N)。這樣執(zhí)行了遍歷相加運算后,除了第一個元素之外,其余所有元素的值都會依賴于它之前的元素的值。不難發(fā)現(xiàn),進(jìn)行一遍遍歷,只能讓數(shù)組中下標(biāo)大的元素對下標(biāo)小的元素形成依賴,而反過來則不成立,而理想中的情況應(yīng)該是混合型的依賴。為了解決這個缺陷,我們可以使用反向遍歷——思路與正向遍歷相同,只是起止點對調(diào)了:A[i]+A[i+1]=>A[i](i從N-1遞減到1)。經(jīng)過了正反兩次疊加遍歷,數(shù)組中的每個元素的值都變得和其它所有元素的值相關(guān)了——由此,本算法也就相應(yīng)的具備了抗反向分析以及差分分析的能力。
在解決了信息相關(guān)性的問題之后,接下來要做的就是將密鑰置于在計算過程之中。首先,在正反遍歷的求和計算過程中加入了兩個長度為一個字節(jié)的密鑰,分別作用于求和前和求和后的數(shù)組元素值,于是,加密過程就變成了:
正向遍歷:((A[i]XOR K11)+A[i-1])XOR K12=>A[i]
反向遍歷:((A[i] XOR K21)+A[i+1])XOR K22=>A[i]
雖然有了上面的兩次遍歷過程,但是,不難發(fā)現(xiàn)——在每次遍歷中,都有一個位于起點的元素的值不會發(fā)生變化(正向遍歷中的A[1]以及逆向遍歷中的A[N])——為了避免這兩個元素成為破解的切入點,必須對其進(jìn)行進(jìn)一步處理。于是,我們對數(shù)組兩端的元素再進(jìn)行一次加密,讓它們在正反兩次遍歷開始時分別作用于相應(yīng)的起始元素:
正向遍歷前:((A[1] XOR K31)+K32=>A[1]
反向遍歷前:((A[N] XOR K41)+K42=>A[N]
在完成了加密算法的設(shè)計后,接下來就是解密算法——上面的雙向遍歷疊加過程可以很容易的逆向為雙向解密過程,具體見后面的代碼,在此不再贅述。同時,不難發(fā)現(xiàn)解密密鑰就是加密密鑰,因此,本加密算法屬于對稱加密算法。
現(xiàn)在,密鑰的復(fù)雜度達(dá)到了8個字節(jié),即64Bits,能滿足一般的加解密要求。為了獲得更大的密鑰空間,用戶完全可以采用多次加密或者多層加密的方法。需要指出的是,由于本算法每次的加密對象都是整個明文,而不是某個定長區(qū)塊,因此,多次嵌套加密后,所有的密鑰信息都會被密文均勻的包容,而不是在固定長度的區(qū)塊中相互混迭。
二、算法實現(xiàn)
下面是算法的Pascal代碼實現(xiàn)(在此,我們使用字符串S作為加解密的對象):
procedure TwoWayEnc(var S:String;const K1,K2:Integer);
var
i,n:Integer;
K11,K12,K21,K22,K31,K32,K41,K42:Byte;
begin
n:=Length(S);
if n=0 then exit;
K11:=K1;K12:=K1 shr 8;
K21:=K1 shr 16;K22:=K1 shr 24;
K31:=K2;K32:=K2 shr 8;
K41:=K2 shr 16;K42:=K2 shr 24;
S[1]:=Char(Byte(S[1])xor K31+K32);
for i:=2 to n do
S[i]:=Char((Byte(S[i])xor K11+Byte(S[i-1]))xor K12);
S[n]:=Char(Byte(S[n])xor K41+K42);
for i:=n-1 downto 1 do
S[i]:=Char((Byte(S[i])xor K21+Byte(S[i+1]))xor K22);
end;
procedure TwoWayDec(var S:String;const K1,K2:Integer);
var
i,n:Integer;
K11,K12,K21,K22,K31,K32,K41,K42:Byte;
begin
n:=Length(S);
if n=0 then exit;
K11:=K1;K12:=K1 shr 8;
K21:=K1 shr 16;K22:=K1 shr 24;
K31:=K2;K32:=K2 shr 8;
K41:=K2 shr 16;K42:=K2 shr 24;
for i:=1 to n-1 do
S[i]:=Char((Byte(S[i])xor K22-Byte(S[i+1]))xor K21);
S[n]:=Char((Byte(S[n])-K42)xor K41);
for i:=n downto 2 do
S[i]:=Char((Byte(S[i])xor K12-Byte(S[i-1]))xor K11);
S[1]:=Char((Byte(S[1])-K32)xor K31);
end;
三、總結(jié)
通過實際測試,本算法在主頻為2.0GHz的CPU上完成對10MB文本的加密及解密運算只需要0.11秒,平均每個字節(jié)的加密或解密運算量小于11個時鐘周期,和得到廣泛應(yīng)用的加密算法相比,效率優(yōu)勢非常明顯(大多數(shù)對稱加密算法對每個字節(jié)的加解密都需要數(shù)十個時鐘周期,非對稱加密算法的耗時則更長)?;谶@一點,完全可以進(jìn)行多次加密運算以獲得更高的安全性,而不會有太大的性能負(fù)擔(dān)。










