- //**********************************************
- // 文件名: UnitAes.pas
- // 作者: nanika
- // 电子邮件: nanika@qq.com
- // 日期: 2010年03月06日
- // 声明: AES数据加密/解密类(可与小虫制作的Asp文件互相加解密)
- // 本代码可以自由使用,但请保留此版权声明信息
- // 如果您对本上传类进行修改增强,
- // 请发送一份给我。
- // 谢谢!^-^
- //**********************************************
- unit UnitAES;
- interface
- uses
- SysUtils;
- type
- TIOArray=array[0..15] of byte;
- TAes=class
- function EntryptString(const text,key:WideString;keysize:integer=128):WideString;
- function DecryptString(const text,key:WideString;keysize:integer=128):WideString;
- private
- FNb,FNk,FNr:byte;
- FKey:array[0..31] of byte;
- FW:array[0..59,0..3] of byte;
- FState:array[0..3,0..3] of byte;
- function ArrayToHexStr(Src:array of byte):WideString;
- function ArrayToStr(Src:array of byte):WideString;
- procedure HexStrToArray(Src:WideString;var Out:TIOArray);
- function HexStr(Src:widestring):WideString;
- procedure InitKey(const Key:WideString);
- procedure SetNbNkNr(keysize:integer);
- procedure AddRoundKey(around:integer);
- procedure KeyExpansion;
- procedure SubBytes;
- procedure InvSubBytes;
- procedure ShiftRows;
- procedure InvShiftRows;
- procedure MixColumns;
- procedure InvMixColumns;
- function gfmultby01(b:byte):byte;
- function gfmultby02(b:byte):byte;
- function gfmultby03(b:byte):byte;
- function gfmultby09(b:byte):byte;
- function gfmultby0b(b:byte):byte;
- function gfmultby0d(b:byte):byte;
- function gfmultby0e(b:byte):byte;
- procedure SubWord(var B1,B2,B3,B4:byte);
- procedure RotWord(var B1,B2,B3,B4:byte);
- procedure FCipher(input:TIOarray;var output:TIOarray);
- procedure FInvCipher(input:TIOarray;var output:TIOarray);
- public
- end;
- var
- AES:TAes;
- implementation
- var
- FSBox:array[0..15,0..15] of byte=(
- ($63,$7C,$77,$7B,$F2,$6B,$6F,$C5,$30,$01,$67,$2B,$FE,$D7,$AB,$76),
- ($CA,$82,$C9,$7D,$FA,$59,$47,$F0,$AD,$D4,$A2,$AF,$9C,$A4,$72,$C0),
- ($B7,$FD,$93,$26,$36,$3F,$F7,$CC,$34,$A5,$E5,$F1,$71,$D8,$31,$15),
- ($04,$C7,$23,$C3,$18,$96,$05,$9A,$07,$12,$80,$E2,$EB,$27,$B2,$75),
- ($09,$83,$2C,$1A,$1B,$6E,$5A,$A0,$52,$3B,$D6,$B3,$29,$E3,$2F,$84),
- ($53,$D1,$00,$ED,$20,$FC,$B1,$5B,$6A,$CB,$BE,$39,$4A,$4C,$58,$CF),
- ($D0,$EF,$AA,$FB,$43,$4D,$33,$85,$45,$F9,$02,$7F,$50,$3C,$9F,$A8),
- ($51,$A3,$40,$8F,$92,$9D,$38,$F5,$BC,$B6,$DA,$21,$10,$FF,$F3,$D2),
- ($CD,$0C,$13,$EC,$5F,$97,$44,$17,$C4,$A7,$7E,$3D,$64,$5D,$19,$73),
- ($60,$81,$4F,$DC,$22,$2A,$90,$88,$46,$EE,$B8,$14,$DE,$5E,$0B,$DB),
- ($E0,$32,$3A,$0A,$49,$06,$24,$5C,$C2,$D3,$AC,$62,$91,$95,$E4,$79),
- ($E7,$C8,$37,$6D,$8D,$D5,$4E,$A9,$6C,$56,$F4,$EA,$65,$7A,$AE,$08),
- ($BA,$78,$25,$2E,$1C,$A6,$B4,$C6,$E8,$DD,$74,$1F,$4B,$BD,$8B,$8A),
- ($70,$3E,$B5,$66,$48,$03,$F6,$0E,$61,$35,$57,$B9,$86,$C1,$1D,$9E),
- ($E1,$F8,$98,$11,$69,$D9,$8E,$94,$9B,$1E,$87,$E9,$CE,$55,$28,$DF),
- ($8C,$A1,$89,$0D,$BF,$E6,$42,$68,$41,$99,$2D,$0F,$B0,$54,$BB,$16));
- FIsBox:array[0..15,0..15] of byte=(
- ($52,$09,$6A,$D5,$30,$36,$A5,$38,$BF,$40,$A3,$9E,$81,$F3,$D7,$FB),
- ($7C,$E3,$39,$82,$9B,$2F,$FF,$87,$34,$8E,$43,$44,$C4,$DE,$E9,$CB),
- ($54,$7B,$94,$32,$A6,$C2,$23,$3D,$EE,$4C,$95,$0B,$42,$FA,$C3,$4E),
- ($08,$2E,$A1,$66,$28,$D9,$24,$B2,$76,$5B,$A2,$49,$6D,$8B,$D1,$25),
- ($72,$F8,$F6,$64,$86,$68,$98,$16,$D4,$A4,$5C,$CC,$5D,$65,$B6,$92),
- ($6C,$70,$48,$50,$FD,$ED,$B9,$DA,$5E,$15,$46,$57,$A7,$8D,$9D,$84),
- ($90,$D8,$AB,$00,$8C,$BC,$D3,$0A,$F7,$E4,$58,$05,$B8,$B3,$45,$06),
- ($D0,$2C,$1E,$8F,$CA,$3F,$0F,$02,$C1,$AF,$BD,$03,$01,$13,$8A,$6B),
- ($3A,$91,$11,$41,$4F,$67,$DC,$EA,$97,$F2,$CF,$CE,$F0,$B4,$E6,$73),
- ($96,$AC,$74,$22,$E7,$AD,$35,$85,$E2,$F9,$37,$E8,$1C,$75,$DF,$6E),
- ($47,$F1,$1A,$71,$1D,$29,$C5,$89,$6F,$B7,$62,$0E,$AA,$18,$BE,$1B),
- ($FC,$56,$3E,$4B,$C6,$D2,$79,$20,$9A,$DB,$C0,$FE,$78,$CD,$5A,$F4),
- ($1F,$DD,$A8,$33,$88,$07,$C7,$31,$B1,$12,$10,$59,$27,$80,$EC,$5F),
- ($60,$51,$7F,$A9,$19,$B5,$4A,$0D,$2D,$E5,$7A,$9F,$93,$C9,$9C,$EF),
- ($A0,$E0,$3B,$4D,$AE,$2A,$F5,$B0,$C8,$EB,$BB,$3C,$83,$53,$99,$61),
- ($17,$2B,$04,$7E,$BA,$77,$D6,$26,$E1,$69,$14,$63,$55,$21,$0C,$7D));
- FRcon:array[0..10,0..3] of byte=(
- ($00,$00,$00,$00),
- ($01,$00,$00,$00),
- ($02,$00,$00,$00),
- ($04,$00,$00,$00),
- ($08,$00,$00,$00),
- ($10,$00,$00,$00),
- ($20,$00,$00,$00),
- ($40,$00,$00,$00),
- ($80,$00,$00,$00),
- ($1B,$00,$00,$00),
- ($36,$00,$00,$00));
- //----------------------------------------------------------------------------
- function TAes.EntryptString(const text,key:WideString;keysize:integer=128):WideString;
- var
- i,iLen:integer;
- sLen,HexString:WideString;
- str32:WideString;
- input,output:TIOArray;
- begin
- SetNbNkNr(keysize);
- InitKey(key);
- iLen:=length(text);
- sLen:=inttohex(iLen,4);
- HexString:=sLen+HexStr(text);
- result:='';
- i:=0;
- str32:=copy(HexString,1,32);
- While length(str32)>0 do
- begin
- HexStrToArray(str32,input);
- FCipher(input,output);
- result:=result+ArrayToHexStr(output);
- i:=i+length(str32);
- str32:=copy(HexString,i+1,32);
- end;
- end;
- function TAes.DecryptString(const text,key:WideString;keysize:integer=128):WideString;
- var
- i,iLen:integer;
- sLen,HexString:WideString;
- Str32,str:WideString;
- input,output:TIOArray;
- begin
- SetNbNkNr(keysize);
- InitKey(key);
- HexString:=text;
- result:='';
- i:=0;
- str32:=copy(hexstring,1,32);
- i:=i+length(str32);
- HexStrToArray(str32,input);
- FInvCipher(input,output);
- str:=ArrayToHexStr(output);
- sLen:=Copy(str,1,4);
- iLen:=strtoint('$'+sLen);
- str:=ArrayToStr(output);
- result:=copy(str,length(str)-6,7);
- str32:=copy(HexString,i+1,32);
- while length(str32)>0 do
- begin
- HexStrToArray(str32,input);
- FInvCipher(input,output);
- result:=result+ArrayToStr(output);
- i:=i+ length(str32);
- str32:=copy(HexString,i+1,32);
- end;
- result:=copy(result,1,iLen);
- end;
- //----------------------------转换函数------------------------------
- function TAes.ArrayToHexStr(Src:array of byte):WideString;
- var
- i:integer;
- begin
- result:='';
- For i:=Low(Src) to High(Src) do
- result:=result+inttohex(Src[i],2);
- end;
- function TAes.ArrayToStr(Src:array of byte):WideString;
- var
- i:integer;
- begin
- result:='';
- For i:=Low(Src) to (High(Src) div 2) do
- result:=result+WideChar(Src[2*i]+Src[2*i+1]*$100);
- end;
- function TAes.HexStr(Src:WideString):WideString;
- var
- i:integer;
- temp:WideString;
- begin
- result:='';
- For i:=1 to length(Src) do
- begin
- temp:=inttohex(ord(Src[i]),4);
- temp:=copy(temp,3,2)+copy(temp,1,2);
- result:=result+temp;
- end;
- end;
- procedure TAes.HexStrToArray(Src:WideString;var Out:TIOArray);
- var
- i:integer;
- begin
- for i:=0 to (length(Src) div 2)-1 do
- Out[i]:=strtoint('$'+copy(Src,2*i+1,2));
- for i:=(length(Src) div 2) to High(Out) do Out[i]:=0;
- end;
- //------------------------初始化-------------------------------------
- procedure TAes.InitKey(const key:WideString);
- var
- i,count:integer;
- begin
- FillChar(FKey,32,0);
- If length(key)>FNk*4 then count:=FNk*4
- else count:=length(key);
- for i:=0 to count-1 do FKey[i]:=byte(ord(key[i+1]));
- KeyExpansion;
- end;
- procedure TAes.SetNbNkNr(keysize:integer);
- begin
- FNb:=4;
- Case KeySize of
- 192:
- begin
- FNk:=6;
- FNr:=12;
- end;
- 256:
- begin
- FNk:=8;
- FNr:=14;
- end;
- else
- begin
- FNk:=4;
- FNr:=10;
- end;
- end;
- end;
- procedure TAes.AddRoundKey(around:integer);
- var
- r,c:integer;
- begin
- For r:=0 to 3 do
- For c:=0 to 3 do
- Fstate[r,c]:=Fstate[r,c] xor Fw[(around*4)+c,r];
- end;
- procedure TAes.KeyExpansion;
- var
- row:integer;
- temp:array[0..3] of byte;
- i:integer;
- begin
- for row:=0 to FNk-1 do
- begin
- FW[row,0]:=Fkey[4*row];
- FW[row,1]:=Fkey[4*row+1];
- FW[row,2]:=FKey[4*row+2];
- FW[row,3]:=FKey[4*row+3];
- end;
- for row:=FNk to FNb*(FNr+1)-1 do
- begin
- for i:=0 to 3 do temp[i]:=FW[row-1,i];
- If (row mod Fnk)=0 then
- begin
- RotWord(temp[0],temp[1],temp[2],temp[3]);
- SubWord(temp[0],temp[1],temp[2],temp[3]);
- for i:=0 to 3 do temp[i]:=temp[i] xor FRcon[row div Fnk,i];
- end
- else if (FNk>6) and ((row mod Fnk)=4) then
- SubWord(temp[0],temp[1],temp[2],temp[3]);
- for i:=0 to 3 do
- FW[row,i]:=FW[row-FNk,i] xor temp[i];
- end;
- end;
- procedure TAes.SubBytes;
- var
- r,c:integer;
- begin
- for r:=0 to 3 do
- for c:=0 to 3 do
- FState[r,c]:=FSBox[FState[r,c] div 16,FState[r,c] and $0F];
- end;
- procedure TAes.InvSubBytes;
- var
- r,c:integer;
- begin
- for r:=0 to 3 do
- for c:=0 to 3 do
- FState[r,c]:=FIsBox[FState[r,c] div 16,FState[r,c] and $0F];
- end;
- procedure TAes.ShiftRows;
- var
- temp:array[0..3,0..3] of byte;
- r,c:integer;
- begin
- for r:=0 to 3 do
- for c:=0 to 3 do
- temp[r,c]:=FState[r,c];
- for r:=1 to 3 do
- for c:=0 to 3 do
- FState[r,c]:=temp[r,(c+r) mod FNb];
- end;
- procedure TAes.InvShiftRows;
- var
- temp:array[0..3,0..3] of byte;
- r,c:integer;
- begin
- for r:=0 to 3 do
- for c:=0 to 3 do
- temp[r,c]:=FState[r,c];
- for r:=1 to 3 do
- for c:=0 to 3 do
- FState[r,(c+r) mod FNb]:=temp[r,c];
- end;
- procedure TAes.MixColumns;
- var
- temp:array[0..3,0..3] of byte;
- r,c:integer;
- begin
- for r:=0 to 3 do
- for c:=0 to 3 do
- temp[r,c]:=FState[r,c];
- for c:=0 to 3 do
- begin
- FState[0,c]:=gfmultby02(temp[0,c]) xor gfmultby03(temp[1,c])
- xor gfmultby01(temp[2,c]) xor gfmultby01(temp[3,c]);
- FState[1,c]:=gfmultby01(temp[0,c]) xor gfmultby02(temp[1,c])
- xor gfmultby03(temp[2,c]) xor gfmultby01(temp[3,c]);
- FState[2,c]:=gfmultby01(temp[0,c]) xor gfmultby01(temp[1,c])
- xor gfmultby02(temp[2,c]) xor gfmultby03(temp[3,c]);
- FState[3,c]:=gfmultby03(temp[0,c]) xor gfmultby01(temp[1,c])
- xor gfmultby01(temp[2,c]) xor gfmultby02(temp[3,c]);
- end;
- end;
- procedure TAes.InvMixColumns;
- var
- temp:array[0..3,0..3] of byte;
- r,c:integer;
- begin
- for r:=0 to 3 do
- for c:=0 to 3 do
- temp[r,c]:=FState[r,c];
- for c:=0 to 3 do
- begin
- FState[0,c]:=gfmultby0e(temp[0,c]) xor gfmultby0b(temp[1,c])
- xor gfmultby0d(temp[2,c]) xor gfmultby09(temp[3,c]);
- FState[1,c]:=gfmultby09(temp[0,c]) xor gfmultby0e(temp[1,c])
- xor gfmultby0b(temp[2,c]) xor gfmultby0d(temp[3,c]);
- FState[2,c]:=gfmultby0d(temp[0,c]) xor gfmultby09(temp[1,c])
- xor gfmultby0e(temp[2,c]) xor gfmultby0b(temp[3,c]);
- FState[3,c]:=gfmultby0b(temp[0,c]) xor gfmultby0d(temp[1,c])
- xor gfmultby09(temp[2,c]) xor gfmultby0e(temp[3,c]);
- end;
- end;
- function TAes.gfmultby01(b:byte):byte;
- begin
- result:=b;
- end;
- function TAes.gfmultby02(b:byte):byte;
- begin
- if b<$80 then
- result:=b*2
- else
- result:=b*2 xor $1B;
- end;
- function TAes.gfmultby03(b:byte):byte;
- begin
- result:=gfmultby02(b) xor b;
- end;
- function TAes.gfmultby09(b:byte):byte;
- begin
- result:=gfmultby02(gfmultby02(gfmultby02(b))) xor b;
- end;
- function TAes.gfmultby0b(b:byte):byte;
- begin
- result:=gfmultby09(b) xor gfmultby02(b);
- end;
- function TAes.gfmultby0d(b:byte):byte;
- begin
- result:=gfmultby09(b) xor gfmultby02(gfmultby02(b));
- end;
- function TAes.gfmultby0e(b:byte):byte;
- begin
- result:=gfmultby02(gfmultby02(gfmultby02(b))) xor gfmultby02(gfmultby02(b))
- xor gfmultby02(b);
- end;
- procedure TAes.SubWord(var B1,B2,B3,B4:byte);
- begin
- B4:=FSbox[B4 div 16,B4 and $0F];
- B3:=FSbox[B3 div 16,B3 and $0F];
- B2:=FSbox[B2 div 16,B2 and $0F];
- B1:=FSbox[B1 div 16,B1 and $0F];
- end;
- procedure TAes.RotWord(var B1,B2,B3,B4:byte);
- var
- B:byte;
- begin
- B:=B1;
- B1:=B2;
- B2:=B3;
- B3:=B4;
- B4:=B;
- end;
- procedure TAes.FCipher(input:TIOArray;var output:TIOArray);
- var
- i,around:integer;
- begin
- for i:=0 to 4*FNb-1 do FState[i mod 4, i div 4]:=input[i];
- AddRoundKey(0);
- For around:=1 to FNr-1 do
- begin
- SubBytes;
- ShiftRows;
- MixColumns;
- AddRoundKey(around);
- end;
- SubBytes;
- ShiftRows;
- AddRoundKey(FNr);
- for i:=0 to FNb*4-1 do output[i]:=FState[i mod 4,i div 4];
- end;
- procedure TAes.FInvCipher(input:TIOArray;var output:TIOArray);
- var
- i,around:integer;
- begin
- for i:=0 to 4*FNb-1 do FState[i mod 4,i div 4]:=input[i];
- AddRoundKey(FNr);
- for around:=FNr-1 downto 1 do
- begin
- InvShiftRows;
- InvSubBytes;
- AddRoundKey(around);
- InvMixColumns;
- end;
- InvShiftRows;
- InvSubBytes;
- AddRoundKey(0);
- for i:=0 to FNb*4-1 do output[i]:=FState[i mod 4,i div 4];
- end;
- end.
复制代码 |