您的位置:首页 > 编程语言 > Delphi

Delphi AES加密

2014-02-26 00:00 766 查看
摘要: Delphi AES加密

(**************************************************************)
(*     Advanced Encryption Standard (AES)                     *)
(*     Interface Unit v1.3                                    *)
(*                                                            *)
(*     Copyright (c) 2002 Jorlen Young                        *)
(*                                                            *)
(* 说明:                                                     *)
(*    基于 ElASE.pas 单元封装                                 *)
(*                                                            *)
(*    这是一个 AES 加密算法的标准接口。                       *)
(* 调用示例:                                                 *)
(* if not EncryptStream(src, key, TStream(Dest), keybit) then *)
(*   showmessage('encrypt error');                            *)
(*                                                            *)
(* if not DecryptStream(src, key, TStream(Dest), keybit) then *)
(*   showmessage('encrypt error');                            *)
(*                                                            *)
(* *** 一定要对Dest进行TStream(Dest) ***                      *)
(* ========================================================== *)
(*                                                            *)
(*   支持 128 / 192 / 256 位的密匙                            *)
(*   默认情况下按照 128 位密匙操作                            *)
(*                                                            *)
(**************************************************************)

unit AES;

interface

{$IFDEF VER210}
{$WARN IMPLICIT_STRING_CAST OFF} //关闭警告
{$WARN IMPLICIT_STRING_CAST_LOSS OFF}
{$ENDIF}
uses
SysUtils, Classes, Math, ElAES;

const
SDestStreamNotCreated = 'Dest stream not created.';
SEncryptStreamError = 'Encrypt stream error.';
SDecryptStreamError = 'Decrypt stream error.';

type
TKeyBit = (kb128, kb192, kb256);

function StrToHex(Const str: AnsiString): AnsiString;
function HexToStr(const Str: AnsiString): AnsiString;

function EncryptString(Value: AnsiString; Key: AnsiString;
KeyBit: TKeyBit = kb128): AnsiString;
function DecryptString(Value: AnsiString; Key: AnsiString;
KeyBit: TKeyBit = kb128): AnsiString;

function EncryptStream(Src: TStream; Key: AnsiString;
var Dest: TStream; KeyBit: TKeyBit = kb128): Boolean;
function DecryptStream(Src: TStream; Key: AnsiString;
var Dest: TStream; KeyBit: TKeyBit = kb128): Boolean;

procedure EncryptFile(SourceFile, DestFile: String;
Key: AnsiString; KeyBit: TKeyBit = kb128);
procedure DecryptFile(SourceFile, DestFile: String;
Key: AnsiString; KeyBit: TKeyBit = kb128);

implementation

function StrToHex(Const str: Ansistring): Ansistring;
asm
push ebx
push esi
push edi
test eax,eax
jz   @@Exit
mov  esi,edx       //保存edx值,用来产生新字符串的地址
mov  edi,eax       //保存原字符串
mov  edx,[eax-4]  //获得字符串长度
test edx,edx      //检查长度
je   @@Exit      {Length(S) = 0}
mov  ecx,edx       //保存长度
Push ecx
shl  edx,1
mov  eax,esi
{$IFDEF VER210}
movzx ecx, word ptr [edi-12] {需要设置CodePage}
{$ENDIF}
call System.@LStrSetLength //设置新串长度
mov  eax,esi       //新字符串地址
Call UniqueString  //产生一个唯一的新字符串,串位置在eax中
Pop   ecx
@@SetHex:
xor  edx,edx       //清空edx
mov  dl, [edi]     //Str字符串字符
mov  ebx,edx       //保存当前的字符
shr  edx,4         //右移4字节,得到高8位
mov  dl,byte ptr[edx+@@HexChar] //转换成字符
mov  [eax],dl      //将字符串输入到新建串中存放
and  ebx,$0F       //获得低8位
mov  dl,byte ptr[ebx+@@HexChar] //转换成字符
inc  eax             //移动一个字节,存放低位
mov  [eax],dl
inc  edi
inc  eax
loop @@SetHex
@@Exit:
pop  edi
pop  esi
pop  ebx
ret
@@HexChar: db '0123456789ABCDEF'
end;

function HexToStr(const Str: AnsiString): AnsiString;
asm
push ebx
push edi
push esi
test eax,eax //为空串
jz   @@Exit
mov  edi,eax
mov  esi,edx
mov  edx,[eax-4]
test edx,edx
je   @@Exit
mov  ecx,edx
push ecx
shr  edx,1
mov  eax,esi //开始构造字符串
{$IFDEF VER210}
movzx ecx, word ptr [edi-12] {需要设置CodePage}
{$ENDIF}
call System.@LStrSetLength //设置新串长度
mov  eax,esi       //新字符串地址
Call UniqueString  //产生一个唯一的新字符串,串位置在eax中
Pop   ecx
xor  ebx,ebx
xor  esi,esi
@@CharFromHex:
xor  edx,edx
mov  dl, [edi]     //Str字符串字符
cmp  dl, '0'  //查看是否在0到f之间的字符
JB   @@Exit   //小于0,退出
cmp  dl,'9'   //小于=9
ja  @@DoChar//CompOkNum
sub  dl,'0'
jmp  @@DoConvert
@@DoChar:
//先转成大写字符
and  dl,$DF
cmp  dl,'F'
ja   @@Exit  //大于F退出
add  dl,10
sub  dl,'A'
@@DoConvert: //转化
inc  ebx
cmp  ebx,2
je   @@Num1
xor  esi,esi
shl  edx,4
mov  esi,edx
jmp  @@Num2
@@Num1:
add  esi,edx
mov  edx,esi
mov  [eax],dl
xor  ebx,ebx
inc  eax
@@Num2:
dec  ecx
inc  edi
test ecx,ecx
jnz  @@CharFromHex
@@Exit:
pop  esi
pop  edi
pop  ebx
end;

{  --  字符串加密函数 默认按照 128 位密匙加密 --  }
function EncryptString(Value: AnsiString; Key: AnsiString;
KeyBit: TKeyBit = kb128): AnsiString;
var
{$IFDEF VER210}
SS,DS: TMemoryStream;
{$ELSE}
SS, DS: TStringStream;
{$ENDIF}
Size: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
st: AnsiString;
begin
Result := '';
{$IFDEF VER210}
ss := TMemoryStream.Create;
SS.WriteBuffer(PAnsiChar(Value)^,Length(Value));
DS := TMemoryStream.Create;
{$ELSE}
SS := TStringStream.Create(Value);
DS := TStringStream.Create('');
{$ENDIF}
try
Size := SS.Size;
DS.WriteBuffer(Size, SizeOf(Size));
{  --  128 位密匙最大长度为 16 个字符 --  }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), 0 );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
EncryptAESStreamECB(SS, 0, AESKey128, DS);
end;
{  --  192 位密匙最大长度为 24 个字符 --  }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), 0 );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
EncryptAESStreamECB(SS, 0, AESKey192, DS);
end;
{  --  256 位密匙最大长度为 32 个字符 --  }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), 0 );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
EncryptAESStreamECB(SS, 0, AESKey256, DS);
end;
{$IFDEF VER210}
SetLength(st,Ds.Size);
DS.Position := 0;
DS.ReadBuffer(PAnsiChar(st)^,DS.Size);
Result := StrToHex(st);
{$ELSE}
Result := StrToHex(DS.DataString);
{$ENDIF}
finally
SS.Free;
DS.Free;
end;
end;

{  --  字符串解密函数 默认按照 128 位密匙解密 --  }
function DecryptString(Value: AnsiString; Key: AnsiString;
KeyBit: TKeyBit = kb128): AnsiString;
var
SS, DS: TStringStream;
Size: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
begin
Result := '';
SS := TStringStream.Create(HexToStr(Value));
DS := TStringStream.Create('');
try
Size := SS.Size;
SS.ReadBuffer(Size, SizeOf(Size));
{  --  128 位密匙最大长度为 16 个字符 --  }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), 0 );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
DecryptAESStreamECB(SS, SS.Size - SS.Position, AESKey128, DS);
end;
{  --  192 位密匙最大长度为 24 个字符 --  }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), 0 );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
DecryptAESStreamECB(SS, SS.Size - SS.Position, AESKey192, DS);
end;
{  --  256 位密匙最大长度为 32 个字符 --  }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), 0 );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
DecryptAESStreamECB(SS, SS.Size - SS.Position, AESKey256, DS);
end;
Result := DS.DataString;
finally
SS.Free;
DS.Free;
end;
end;

{ 流加密函数, default keybit: 128bit }
function EncryptStream(Src: TStream; Key: AnsiString;
var Dest: TStream; KeyBit: TKeyBit = kb128): Boolean;
var
Count: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
begin
if Dest = nil then
begin
raise Exception.Create(SDestStreamNotCreated);
Result:= False;
Exit;
end;

try
Src.Position:= 0;
Count:= Src.Size;
Dest.Write(Count, SizeOf(Count));
{  --  128 位密匙最大长度为 16 个字符 --  }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), 0 );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
EncryptAESStreamECB(Src, 0, AESKey128, Dest);
end;
{  --  192 位密匙最大长度为 24 个字符 --  }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), 0 );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
EncryptAESStreamECB(Src, 0, AESKey192, Dest);
end;
{  --  256 位密匙最大长度为 32 个字符 --  }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), 0 );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
EncryptAESStreamECB(Src, 0, AESKey256, Dest);
end;

Result := True;
except
raise Exception.Create(SEncryptStreamError);
Result:= False;
end;
end;

{ 流解密函数, default keybit: 128bit }
function DecryptStream(Src: TStream; Key: AnsiString;
var Dest: TStream; KeyBit: TKeyBit = kb128): Boolean;
var
Count, OutPos: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
begin
if Dest = nil then
begin
raise Exception.Create(SDestStreamNotCreated);
Result:= False;
Exit;
end;

try
Src.Position:= 0;
OutPos:= Dest.Position;
Src.ReadBuffer(Count, SizeOf(Count));
{  --  128 位密匙最大长度为 16 个字符 --  }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), 0 );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
DecryptAESStreamECB(Src, Src.Size - Src.Position,
AESKey128, Dest);
end;
{  --  192 位密匙最大长度为 24 个字符 --  }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), 0 );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
DecryptAESStreamECB(Src, Src.Size - Src.Position,
AESKey192, Dest);
end;
{  --  256 位密匙最大长度为 32 个字符 --  }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), 0 );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
DecryptAESStreamECB(Src, Src.Size - Src.Position,
AESKey256, Dest);
end;
Dest.Size := OutPos + Count;
Dest.Position := OutPos;

Result := True;
except
raise Exception.Create(SDecryptStreamError);
Result:= False;
end;
end;

{  --  文件加密函数 默认按照 128 位密匙解密 --  }
procedure EncryptFile(SourceFile, DestFile: String;
Key: AnsiString; KeyBit: TKeyBit = kb128);
var
SFS, DFS: TFileStream;
Size: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
begin
SFS := TFileStream.Create(SourceFile, fmOpenRead);
try
DFS := TFileStream.Create(DestFile, fmCreate);
try
Size := SFS.Size;
DFS.WriteBuffer(Size, SizeOf(Size));
{  --  128 位密匙最大长度为 16 个字符 --  }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), 0 );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
EncryptAESStreamECB(SFS, 0, AESKey128, DFS);
end;
{  --  192 位密匙最大长度为 24 个字符 --  }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), 0 );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
EncryptAESStreamECB(SFS, 0, AESKey192, DFS);
end;
{  --  256 位密匙最大长度为 32 个字符 --  }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), 0 );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
EncryptAESStreamECB(SFS, 0, AESKey256, DFS);
end;
finally
DFS.Free;
end;
finally
SFS.Free;
end;
end;

{  --  文件解密函数 默认按照 128 位密匙解密 --  }
procedure DecryptFile(SourceFile, DestFile: String;
Key: AnsiString; KeyBit: TKeyBit = kb128);
var
SFS, DFS: TFileStream;
Size: Int64;
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
begin
SFS := TFileStream.Create(SourceFile, fmOpenRead);
try
SFS.ReadBuffer(Size, SizeOf(Size));
DFS := TFileStream.Create(DestFile, fmCreate);
try
{  --  128 位密匙最大长度为 16 个字符 --  }
if KeyBit = kb128 then
begin
FillChar(AESKey128, SizeOf(AESKey128), 0 );
Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
DecryptAESStreamECB(SFS, SFS.Size - SFS.Position, AESKey128, DFS);
end;
{  --  192 位密匙最大长度为 24 个字符 --  }
if KeyBit = kb192 then
begin
FillChar(AESKey192, SizeOf(AESKey192), 0 );
Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
DecryptAESStreamECB(SFS, SFS.Size - SFS.Position, AESKey192, DFS);
end;
{  --  256 位密匙最大长度为 32 个字符 --  }
if KeyBit = kb256 then
begin
FillChar(AESKey256, SizeOf(AESKey256), 0 );
Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
DecryptAESStreamECB(SFS, SFS.Size - SFS.Position, AESKey256, DFS);
end;
DFS.Size := Size;
finally
DFS.Free;
end;
finally
SFS.Free;
end;
end;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  AES