Delphi互通的AES加解密程序源码
//**********************************************// 文件名: UnitAes.pas
// 作者: nanika
// 电子邮件: nanika@qq.com
// 日期: 2010年03月06日
// 声明: AES数据加密/解密类(可与小虫制作的Asp文件互相加解密)
// 本代码可以自由使用,但请保留此版权声明信息
// 如果您对本上传类进行修改增强,
// 请发送一份给我。
// 谢谢!^-^
//**********************************************
unit UnitAES;
interface
uses
SysUtils;
type
TIOArray=array 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 of byte;
FW:array of byte;
FState:array 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 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 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 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,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+Src*$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),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:=strtoint('$'+copy(Src,2*i+1,2));
for i:=(length(Src) div 2) to High(Out) do Out:=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:=byte(ord(key));
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:=Fstate xor Fw[(around*4)+c,r];
end;
procedure TAes.KeyExpansion;
var
row:integer;
temp:array of byte;
i:integer;
begin
for row:=0 to FNk-1 do
begin
FW:=Fkey;
FW:=Fkey;
FW:=FKey;
FW:=FKey;
end;
for row:=FNk to FNb*(FNr+1)-1 do
begin
for i:=0 to 3 do temp:=FW;
If (row mod Fnk)=0 then
begin
RotWord(temp,temp,temp,temp);
SubWord(temp,temp,temp,temp);
for i:=0 to 3 do temp:=temp xor FRcon;
end
else if (FNk>6) and ((row mod Fnk)=4) then
SubWord(temp,temp,temp,temp);
for i:=0 to 3 do
FW:=FW xor temp;
end;
end;
procedure TAes.SubBytes;
var
r,c:integer;
begin
for r:=0 to 3 do
for c:=0 to 3 do
FState:=FSBox div 16,FState and $0F];
end;
procedure TAes.InvSubBytes;
var
r,c:integer;
begin
for r:=0 to 3 do
for c:=0 to 3 do
FState:=FIsBox div 16,FState and $0F];
end;
procedure TAes.ShiftRows;
var
temp:array of byte;
r,c:integer;
begin
for r:=0 to 3 do
for c:=0 to 3 do
temp:=FState;
for r:=1 to 3 do
for c:=0 to 3 do
FState:=temp;
end;
procedure TAes.InvShiftRows;
var
temp:array of byte;
r,c:integer;
begin
for r:=0 to 3 do
for c:=0 to 3 do
temp:=FState;
for r:=1 to 3 do
for c:=0 to 3 do
FState:=temp;
end;
procedure TAes.MixColumns;
var
temp:array of byte;
r,c:integer;
begin
for r:=0 to 3 do
for c:=0 to 3 do
temp:=FState;
for c:=0 to 3 do
begin
FState:=gfmultby02(temp) xor gfmultby03(temp)
xor gfmultby01(temp) xor gfmultby01(temp);
FState:=gfmultby01(temp) xor gfmultby02(temp)
xor gfmultby03(temp) xor gfmultby01(temp);
FState:=gfmultby01(temp) xor gfmultby01(temp)
xor gfmultby02(temp) xor gfmultby03(temp);
FState:=gfmultby03(temp) xor gfmultby01(temp)
xor gfmultby01(temp) xor gfmultby02(temp);
end;
end;
procedure TAes.InvMixColumns;
var
temp:array of byte;
r,c:integer;
begin
for r:=0 to 3 do
for c:=0 to 3 do
temp:=FState;
for c:=0 to 3 do
begin
FState:=gfmultby0e(temp) xor gfmultby0b(temp)
xor gfmultby0d(temp) xor gfmultby09(temp);
FState:=gfmultby09(temp) xor gfmultby0e(temp)
xor gfmultby0b(temp) xor gfmultby0d(temp);
FState:=gfmultby0d(temp) xor gfmultby09(temp)
xor gfmultby0e(temp) xor gfmultby0b(temp);
FState:=gfmultby0b(temp) xor gfmultby0d(temp)
xor gfmultby09(temp) xor gfmultby0e(temp);
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;
B3:=FSbox;
B2:=FSbox;
B1:=FSbox;
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:=input;
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:=FState;
end;
procedure TAes.FInvCipher(input:TIOArray;var output:TIOArray);
var
i,around:integer;
begin
for i:=0 to 4*FNb-1 do FState:=input;
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:=FState;
end;
end.
这个加密方法貌似很难破解
页:
[1]