阿杰 发表于 2010-12-25 12:22:47

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.

upring 发表于 2015-4-26 10:08:46

这个加密方法貌似很难破解
页: [1]
查看完整版本: Delphi互通的AES加解密程序源码