能力值:
( LV9,RANK:610 )
6 楼
偶不懂Delphi,胡乱整理个。。。
unit tianyi_love;
interfaceuses Windows, SysUtils, Forms, Controls, ComCtrls, Classes, ExtCtrls, StdCtrls;
type TFormAES = class(TForm)
btnEnc: TButton;
btnDec: TButton;
Button1: TButton;
ledKey: TLabeledEdit;
memSrcStr: TMemo;
memEncStr: TMemo;
procedure btnDecClick(Sender: TObject);
procedure btnEncClick(Sender: TObject);
procedure Button1Click(Sender: TObject);
private { Private declarations }
public { Public declarations } end;
type EAESError = class(Exception);
TAESBuffer = array [0..15] of byte;
TAESKey128 = array [0..15] of byte;
TAESExpandedKey128 = array [0..43] of longword;
TS_BOX = array[0..255] of byte;
PAESBuffer =^TAESBuffer;resourcestring
SInvalidInBufSize = 'Invalid buffer size for decryption';
SReadError = 'Stream read error';
SWriteError = 'Stream write error';
const S: TS_BOX = ( $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 );
Si: TS_BOX = ( $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
);
Rcon: array [1..30] of longword = ( $00000001, $00000002, $00000004, $00000008, $00000010, $00000020,
$00000040, $00000080, $0000001B, $00000036, $0000006C, $000000D8,
$000000AB, $0000004D, $0000009A, $0000002F, $0000005E, $000000BC,
$00000063, $000000C6, $00000097, $00000035, $0000006A, $000000D4,
$000000B3, $0000007D, $000000FA, $000000EF, $000000C5, $00000091
);
shift: array [0..3] of byte=(0, 3, 2, 1);
Inv_shift: array [0..3] of byte=(0, 1, 2, 3);
var FormAES: TFormAES;
implementation{$R *.DFM}
function Min(A, B: integer): integer;
begin
if A < B then
Result := A
else Result := B;
end;
function StrToHex(Value: string): string;
var I: Integer;
begin
Result := '';
for I := 1 to Length(Value) do
Result := Result + IntToHex(Ord(Value[I]), 2);
end;
function HexToStr(Value: string): string;
var I: Integer;
begin
Result := '';
for I := 1 to Length(Value) do
begin
if ((I mod 2) = 1) then
Result := Result + Chr(StrToInt('0x'+ Copy(Value, I, 2)));
end;
end;
procedure KeyExpansion(const Key:TAESKey128; var ExpandedKey:TAESExpandedKey128);
var I, J,k: byte;
T,tmp: longword;
begin
for I := 0 to 3 do
ExpandedKey[i] := PLongWord(@Key[4*i])^;
I := 0; J := 1;
repeat T := (ExpandedKey[I + 3] shl 8) or (ExpandedKey[I + 3] shr 24);
for k := 0 to 3 do
begin
tmp:=T;
pbyte(@tmp)^:=S[Byte(T shr 8*k)];
inc(tmp);
end;
ExpandedKey[I + 4] := ExpandedKey[I] xor T xor Rcon[J];
Inc(J);
ExpandedKey[I + 5] := ExpandedKey[I + 4] xor ExpandedKey[I + 1];
ExpandedKey[I + 6] := ExpandedKey[I + 5] xor ExpandedKey[I + 2];
ExpandedKey[I + 7] := ExpandedKey[I + 6] xor ExpandedKey[I + 3];
Inc(I, 4);
until I >= 40;
end;
procedure AddRoundKey(var state:TAESBuffer;ExpandedKey:TAESExpandedKey128;index:byte);
var i:integer;
begin
for I := 0 to 3 do
PLongWord(@state[4*i])^:=PLongWord(@state[4*i])^ xor ExpandedKey[4*index+i];
end;
procedure SubBytes(var state:TAESBuffer;box:TS_BOX);
var i:integer;
begin
for i:=0 to 15 do
state[i]:=box[state[i]];
end;
procedure ShiftRows(var state:TAESBuffer;d:byte);
var i,j:byte;
tmp:TAESBuffer;
begin
if d=0 then
begin
for i:=0 to 3 do
for j:=0 to 3 do
tmp[4*((j+shift[i]) mod 4)+i]:=state[4*j+i];
end
else
begin
for i:=0 to 3 do
for j:=0 to 3 do
tmp[4*((j+Inv_shift[i]) mod 4)+i]:=state[4*j+i];
end;
state:=tmp;
end;
function xtime(a:byte):byte;
begin
result:= 0;
if a<>0 then
begin
if (a and $80)>0 then
result:=(a shl 1) xor $1b
else
result:=a shl 1;
end;
end;
function mul(c,b:byte):byte;
var t1,t2,t3:byte;
begin
t1:=0; t2:=0; t3:=0;
if ((c shr 1) and $01)>0 then
t1:=xtime(b);
if ((c shr 2) and $01)>0 then
t2:=xtime(xtime(b));
if ((c shr 3) and $01)>0 then
t3:=xtime(xtime(xtime(b)));
t1:=t1 xor t2 xor t3;
if (c and $01)=1 then
result:=t1 xor b
else
result:=t1;
end;
procedure MixColumns(var state: TAESBuffer);
var i,j:byte;
tmp:TAESBuffer;
begin
tmp:=state;
for j:=0 to 3 do
begin
for i:=0 to 3 do
state[i+4*j]:=mul(2,tmp[i]) xor mul(3,tmp[(i+1) mod 4]) xor tmp[(i+2) mod 4] xor tmp[(i+3) mod 4];
for i:=0 to 3 do
tmp[i]:=tmp[i+4*(j+1)];
end;
end;
procedure InvMixColumns(var state: TAESBuffer);
var i,j:byte;
tmp:TAESBuffer;
begin
tmp:=state;
for j:=0 to 3 do
begin
for i:=0 to 3 do
state[i+4*j]:=mul($e,tmp[i]) xor mul($b, tmp[(i+1) mod 4]) xor mul($d, tmp[(i+2) mod 4]) xor mul($9, tmp[(i+3) mod 4]);
for i:=0 to 3 do
tmp[i]:=tmp[i+4*(j+1)];
end;
end;
procedure Encrypt(input:TAESBuffer; ExpandedKey: TAESExpandedKey128;var OutBuf: TAESBuffer);
var r:byte;
state: TAESBuffer;
begin
state:=input;
AddRoundKey(state, ExpandedKey,0);
for r:=1 to 9 do
begin
SubBytes(state, S);
ShiftRows(state,0);
MixColumns(state);
AddRoundKey(state,ExpandedKey,r);
end;
SubBytes(state, S);
ShiftRows(state, 0);
AddRoundKey(state,ExpandedKey,10);
OutBuf:=state;
end;
procedure Decrypt(input:TAESBuffer; iExpandedKey: TAESExpandedKey128;var OutBuf: TAESBuffer);
var r:byte;
state: TAESBuffer;
begin
state:=input;
AddRoundKey(state,iExpandedKey,10);
for r:=9 downto 1 do
begin
SubBytes(state, Si);
ShiftRows(state,1);
InvMixColumns(state);
AddRoundKey(state,iExpandedKey,r);
end;
SubBytes(state, Si);
ShiftRows(state, 1);
AddRoundKey(state,iExpandedKey,0);
OutBuf:=state;
end;
procedure EncryptAESStream(Source: TStream; Count: cardinal; const Key: TAESKey128; Dest: TStream);
var TempIn, TempOut: TAESBuffer;
Done: cardinal;
ExpandedKey: TAESExpandedKey128;
begin
KeyExpansion(Key, ExpandedKey);
if Count = 0 then
begin
Source.Position := 0;
Count := Source.Size;
end
else
Count := Min(Count, Source.Size - Source.Position);
if Count = 0 then
exit;
while Count >= SizeOf(TAESBuffer) do
begin
Done := Source.Read(TempIn, SizeOf(TempIn));
if Done < SizeOf(TempIn) then
raise EStreamError.Create(SReadError);
Encrypt(TempIn, ExpandedKey, TempOut);
Done := Dest.Write(TempOut, SizeOf(TempOut));
if Done < SizeOf(TempOut) then
raise EStreamError.Create(SWriteError);
Dec(Count, SizeOf(TAESBuffer));
end;
if Count > 0 then
begin
Done := Source.Read(TempIn, Count);
if Done < Count then
raise EStreamError.Create(SReadError);
FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0);
Encrypt(TempIn, ExpandedKey, TempOut);
Done := Dest.Write(TempOut, SizeOf(TempOut));
if Done < SizeOf(TempOut) then
raise EStreamError.Create(SWriteError);
end;
end;
procedure TFormAES.btnEncClick(Sender: TObject);
var SS, DS: TStringStream;
Size: Int64;
AESKey128: TAESKey128;
begin
SS := TStringStream.Create(memSrcStr.Text);
DS := TStringStream.Create('');
try
Size := SS.Size-2;
DS.WriteBuffer(Size, SizeOf(Size));
FillChar(AESKey128, SizeOf(AESKey128), 0 );
Move(PChar(ledKey.Text)^, AESKey128, Min(SizeOf(AESKey128), Length(ledKey.Text)));
EncryptAESStream(SS, 0, AESKey128, DS);
memEncStr.Text :=StrToHex(DS.DataString);
finally
SS.Free;
DS.Free;
end;
end;
procedure DecryptAESStream(Source: TStream; Count: cardinal;const Key: TAESKey128; Dest: TStream);
var TempIn, TempOut: TAESBuffer;
Done: cardinal;
iExpandedKey: TAESExpandedKey128;
i:byte;
begin
KeyExpansion(Key, iExpandedKey);
for i:=1 to 9 do
InvMixColumns(PAESBuffer(@iExpandedKey[4*i])^);
if Count = 0 then
begin
Source.Position := 0;
Count := Source.Size;
end
else
Count := Min(Count, Source.Size - Source.Position);
if Count = 0 then
exit;
if (Count mod SizeOf(TAESBuffer)) > 0 then
raise EAESError.Create(SInvalidInBufSize);
while Count >= SizeOf(TAESBuffer) do
begin
Done := Source.Read(TempIn, SizeOf(TempIn));
if Done < SizeOf(TempIn) then
raise EStreamError.Create(SReadError);
Decrypt(TempIn, iExpandedKey, TempOut);
Done := Dest.Write(TempOut, SizeOf(TempOut));
if Done < SizeOf(TempOut) then
raise EStreamError.Create(SWriteError);
Dec(Count, SizeOf(TAESBuffer));
end;
end;
procedure TFormAES.btnDecClick(Sender: TObject);
var SS, DS: TStringStream;
Size: Int64;
AESKey128: TAESKey128;
begin
if Length(memEncStr.Text) > 0 then
begin
SS := TStringStream.Create(HexToStr(memEncStr.Text));
DS := TStringStream.Create('');
try
Size := SS.Size;
SS.ReadBuffer(Size, SizeOf(Size));
FillChar(AESKey128, SizeOf(AESKey128), 0 );
Move(PChar(ledKey.Text)^, AESKey128, Min(SizeOf(AESKey128), Length(ledKey.Text)));
DecryptAESStream(SS, SS.Size - SS.Position, AESKey128, DS);
memEncStr.Text:= DS.DataString;
finally
SS.Free;
DS.Free;
end;
end;
end;
procedure TFormAES.Button1Click(Sender: TObject);
begin
memEncStr.Text:='';
end;
end.