雙向遍歷加密算法

一、算法原理

我們可以將明文看成一個(gè)Byte數(shù)組A[N],加解密過程就是對(duì)這個(gè)數(shù)組的運(yùn)算。首先,我們從頭到尾對(duì)它進(jìn)行一次正向的遍歷,在遍歷的同時(shí)將每次遇到的元素的值與前一個(gè)元素的值疊加,并寫回到數(shù)組中。即A[i]+A[i-1]=>A[i](i從2遞增到N)。這樣執(zhí)行了遍歷相加運(yùn)算后,除了第一個(gè)元素之外,其余所有元素的值都會(huì)依賴于它之前的元素的值。不難發(fā)現(xiàn),進(jìn)行一遍遍歷,只能讓數(shù)組中下標(biāo)大的元素對(duì)下標(biāo)小的元素形成依賴,而反過來則不成立,而理想中的情況應(yīng)該是混合型的依賴。為了解決這個(gè)缺陷,我們可以使用反向遍歷——思路與正向遍歷相同,只是起止點(diǎn)對(duì)調(diào)了:A[i]+A[i+1]=>A[i](i從N-1遞減到1)。經(jīng)過了正反兩次疊加遍歷,數(shù)組中的每個(gè)元素的值都變得和其它所有元素的值相關(guān)了——由此,本算法也就相應(yīng)的具備了抗反向分析以及差分分析的能力。

在解決了信息相關(guān)性的問題之后,接下來要做的就是將密鑰置于在計(jì)算過程之中。首先,在正反遍歷的求和計(jì)算過程中加入了兩個(gè)長(zhǎng)度為一個(gè)字節(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)——在每次遍歷中,都有一個(gè)位于起點(diǎn)的元素的值不會(huì)發(fā)生變化(正向遍歷中的A[1]以及逆向遍歷中的A[N])——為了避免這兩個(gè)元素成為破解的切入點(diǎn),必須對(duì)其進(jìn)行進(jìn)一步處理。于是,我們對(duì)數(shù)組兩端的元素再進(jìn)行一次加密,讓它們?cè)谡磧纱伪闅v開始時(shí)分別作用于相應(yīng)的起始元素:

正向遍歷前:((A[1] XOR K31)+K32=>A[1]

反向遍歷前:((A[N] XOR K41)+K42=>A[N]

在完成了加密算法的設(shè)計(jì)后,接下來就是解密算法——上面的雙向遍歷疊加過程可以很容易的逆向?yàn)殡p向解密過程,具體見后面的代碼,在此不再贅述。同時(shí),不難發(fā)現(xiàn)解密密鑰就是加密密鑰,因此,本加密算法屬于對(duì)稱加密算法。

現(xiàn)在,密鑰的復(fù)雜度達(dá)到了8個(gè)字節(jié),即64Bits,能滿足一般的加解密要求。為了獲得更大的密鑰空間,用戶完全可以采用多次加密或者多層加密的方法。需要指出的是,由于本算法每次的加密對(duì)象都是整個(gè)明文,而不是某個(gè)定長(zhǎng)區(qū)塊,因此,多次嵌套加密后,所有的密鑰信息都會(huì)被密文均勻的包容,而不是在固定長(zhǎng)度的區(qū)塊中相互混迭。

二、算法實(shí)現(xiàn)

下面是算法的Pascal代碼實(shí)現(xiàn)(在此,我們使用字符串S作為加解密的對(duì)象):

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é)

通過實(shí)際測(cè)試,本算法在主頻為2.0GHz的CPU上完成對(duì)10MB文本的加密及解密運(yùn)算只需要0.11秒,平均每個(gè)字節(jié)的加密或解密運(yùn)算量小于11個(gè)時(shí)鐘周期,和得到廣泛應(yīng)用的加密算法相比,效率優(yōu)勢(shì)非常明顯(大多數(shù)對(duì)稱加密算法對(duì)每個(gè)字節(jié)的加解密都需要數(shù)十個(gè)時(shí)鐘周期,非對(duì)稱加密算法的耗時(shí)則更長(zhǎng))。基于這一點(diǎn),完全可以進(jìn)行多次加密運(yùn)算以獲得更高的安全性,而不會(huì)有太大的性能負(fù)擔(dān)。