(**************************************************************)(* 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.
关键字词: