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.

 

你可能感兴趣的:(Delphi)