主页 > 编程资料 > Delphi >
发布时间:2015-09-22 作者:网络 阅读:110次

(**************************************************************)(*     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  ebxend;
{  --  字符串加密函数 默认按照 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.
关键字词: