RTFormwork/项目代码/RTBasicsV1/F05染色检验/JDAESExtend.pas

296 lines
8.4 KiB
ObjectPascal
Raw Normal View History

2024-07-07 09:35:27 +08:00
(**************************************************)
(* *)
(* Advanced Encryption Standard (AES) Extend *)
(* *)
(* Copyright (c) 2005-2016 *)
(* aisino, qiaobu@139.com qiaohaidong@aisino.com *)
(* *)
(**************************************************)
unit JDAESExtend;
interface
{$WARN IMPLICIT_STRING_CAST OFF} // <20>رվ<D8B1><D5BE><EFBFBD>
{$WARN IMPLICIT_STRING_CAST_LOSS OFF}
uses
SysUtils, Classes, Math, ElAES, System.Generics.Collections, Soap.EncdDecd;
type
TPaddingType = (PKCS5Padding { , PKCS7Padding } );
TKeyBit = (kb128, kb192, kb256);
TalgoMode = (amECB, amCBC { , amCFB, amOFB, amCTR } );
TCipherType = (ctBase64, ctHex);
TArrayPadding = array of Byte;
TArrayByte = array of Byte;
var
AESKey128: TAESKey128;
AESKey192: TAESKey192;
AESKey256: TAESKey256;
InitVector: TAESBuffer;
function EncryptString(Value: AnsiString; Key: AnsiString; KeyBit: TKeyBit = kb128; algoMode: TalgoMode = amECB; padding: TPaddingType = PKCS5Padding; sInitVector: AnsiString = '0000000000000000';
CipherType: TCipherType = ctHex): AnsiString;
function DecryptString(Value: AnsiString; Key: AnsiString; KeyBit: TKeyBit = kb128; algoMode: TalgoMode = amECB; padding: TPaddingType = PKCS5Padding; sInitVector: AnsiString = '0000000000000000';
CipherType: TCipherType = ctHex): AnsiString;
implementation
//<2F>ַ<EFBFBD><D6B7><EFBFBD>ת16<31><36><EFBFBD>ƣ<EFBFBD><C6A3>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>
function StrToHex(Value: AnsiString): string;
var
i: Integer;
begin
Result := '';
for i := 1 to Length(Value) do
Result := Result + IntToHex(Ord(Value[i]), 2);
end;
//16<31><36><EFBFBD>ƣ<EFBFBD><C6A3>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD>ַ<EFBFBD><D6B7><EFBFBD>
function HexToStr(Value: AnsiString): AnsiString;
var
i: Integer;
begin
Result := '';
for i := 1 to Length(Value) do
begin
if ((i mod 2) = 1) then
Result := Result + ansichar(StrToInt('0x' + Copy(Value, i, 2)));
end;
end;
//PKCS5<53><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
function PKCS5_Padding(Value: AnsiString; out arrayValue: TArrayByte): Int64;
var
Valueutf8: UTF8String;
BytesValue: array of Byte;
intMod: Byte;
valueLen: Integer;
i: Integer;
begin
Valueutf8 := Value;
SetLength(BytesValue, Length(Valueutf8));
Move(Valueutf8[1], BytesValue[0], Length(Valueutf8));
intMod := 16 - Length(BytesValue) mod 16;
valueLen := Length(BytesValue);
SetLength(BytesValue, valueLen + intMod);
for i := 0 to intMod - 1 do
begin
BytesValue[valueLen + i] := intMod;
end;
SetLength(arrayValue, Length(BytesValue));
Move(BytesValue[0], arrayValue[0], Length(BytesValue));
Result := Length(BytesValue);
end;
//PKCS5<53><35><EFBFBD><EFBFBD>ȥ<EFBFBD><C8A5><EFBFBD><EFBFBD>
function PKCS5_DePadding(bytes: TBytes): string;
var
Encoding: TEncoding;
size: Integer;
paddingByte: Byte;
tmpBytes: TBytes;
begin
paddingByte := bytes[Length(bytes) - 1];
SetLength(tmpBytes, Length(bytes) - paddingByte);
Move(bytes[0], tmpBytes[0], Length(tmpBytes));
Encoding := TEncoding.UTF8;
size := TEncoding.GetBufferEncoding(tmpBytes, Encoding);
Result := Encoding.GetString(tmpBytes, size, Length(tmpBytes) - size)
end;
//<2F><>Կ<EFBFBD><D4BF><EFBFBD><EFBFBD>λ<EFBFBD><CEBB>0<EFBFBD><30><EFBFBD><EFBFBD>
procedure ZeroPadding(KeyBit: TKeyBit);
begin
case KeyBit of
kb128:
FillChar(AESKey128, SizeOf(AESKey128), 0);
kb192:
FillChar(AESKey192, SizeOf(AESKey192), 0);
kb256:
FillChar(AESKey256, SizeOf(AESKey256), 0);
end;
end;
function EncryptString(Value: AnsiString; Key: AnsiString; KeyBit: TKeyBit = kb128; algoMode: TalgoMode = amECB; padding: TPaddingType = PKCS5Padding; sInitVector: AnsiString = '0000000000000000';
CipherType: TCipherType = ctHex): AnsiString;
var
SS, DS: TMemoryStream;
str: AnsiString;
byteContent: TArrayByte;
begin
Result := '';
PKCS5_Padding(Value, byteContent);
SS := TMemoryStream.Create;
SS.WriteBuffer(byteContent[0], Length(byteContent));
SS.Position := SS.size;
DS := TMemoryStream.Create;
try
case KeyBit of
kb128:
begin
ZeroPadding(kb128);
Move(PAnsiChar(Key)^, AESKey128, Length(Key));
case algoMode of
amECB:
begin
EncryptAESStreamECB(SS, 0, AESKey128, DS);
end;
amCBC:
begin
// <20><><EFBFBD><EFBFBD>16λ<36><CEBB>0<EFBFBD><30><EFBFBD><EFBFBD>
FillChar(InitVector, SizeOf(InitVector), 0);
Move(PAnsiChar(sInitVector)^, InitVector, Length(sInitVector));
EncryptAESStreamCBC(SS, 0, AESKey128, InitVector, DS);
end;
end;
end;
kb192:
begin
ZeroPadding(kb192);
Move(PAnsiChar(Key)^, AESKey192, Length(Key));
case algoMode of
amECB:
begin
EncryptAESStreamECB(SS, 0, AESKey192, DS);
end;
amCBC:
begin
FillChar(InitVector, SizeOf(InitVector), 0);
Move(PAnsiChar(sInitVector)^, InitVector, Length(sInitVector));
EncryptAESStreamCBC(SS, 0, AESKey192, InitVector, DS);
end;
end;
end;
kb256:
begin
ZeroPadding(kb256);
Move(PAnsiChar(Key)^, AESKey256, Length(Key));
case algoMode of
amECB:
begin
EncryptAESStreamECB(SS, 0, AESKey256, DS);
end;
amCBC:
begin
FillChar(InitVector, SizeOf(InitVector), 0);
Move(PAnsiChar(sInitVector)^, InitVector, Length(sInitVector));
EncryptAESStreamCBC(SS, 0, AESKey256, InitVector, DS);
end;
end;
end;
end;
SetLength(str, DS.size);
DS.Position := 0;
DS.ReadBuffer(PAnsiChar(str)^, DS.size);
if CipherType = ctHex then
Result := StrToHex(str)
else
Result := EncodeBase64(PChar(str),Length(str));
finally
SS.Free;
DS.Free;
end;
end;
function DecryptString(Value: AnsiString; Key: AnsiString; KeyBit: TKeyBit = kb128; algoMode: TalgoMode = amECB; padding: TPaddingType = PKCS5Padding; sInitVector: AnsiString = '0000000000000000';
CipherType: TCipherType = ctHex): AnsiString;
var
SS,DS: TMemoryStream;
str: AnsiString;
byteContent: TBytes;
BytesValue: TBytes;
begin
Result := '';
// pcharValue := pchar(Value);
if CipherType = ctHex then
begin
str := HexToStr(Value);
SetLength(byteContent, Length(str));
Move(str[1], byteContent[0], Length(str));
end
else
byteContent:= DecodeBase64(Value);
SS := TMemoryStream.Create;
SS.WriteBuffer(byteContent[0], Length(byteContent));
DS := TMemoryStream.Create;
try
case KeyBit of
kb128:
begin
ZeroPadding(kb128);
Move(PAnsiChar(Key)^, AESKey128, Length(Key));
case algoMode of
amECB:
begin
DecryptAESStreamECB(SS, 0, AESKey128, DS);
end;
amCBC:
begin
// <20><><EFBFBD><EFBFBD>16λ<36><CEBB>0<EFBFBD><30><EFBFBD><EFBFBD>
FillChar(InitVector, SizeOf(InitVector), 0);
Move(PAnsiChar(sInitVector)^, InitVector, Length(sInitVector));
DecryptAESStreamCBC(SS, 0, AESKey128, InitVector, DS);
end;
end;
end;
kb192:
begin
ZeroPadding(kb192);
Move(PAnsiChar(Key)^, AESKey192, Length(Key));
case algoMode of
amECB:
begin
DecryptAESStreamECB(SS, 0, AESKey192, DS);
end;
amCBC:
begin
FillChar(InitVector, SizeOf(InitVector), 0);
Move(PAnsiChar(sInitVector)^, InitVector, Length(sInitVector));
DecryptAESStreamCBC(SS, 0, AESKey192, InitVector, DS);
end;
end;
end;
kb256:
begin
ZeroPadding(kb256);
Move(PAnsiChar(Key)^, AESKey256, Length(Key));
case algoMode of
amECB:
begin
DecryptAESStreamECB(SS, 0, AESKey256, DS);
end;
amCBC:
begin
FillChar(InitVector, SizeOf(InitVector), 0);
Move(PAnsiChar(sInitVector)^, InitVector, Length(sInitVector));
DecryptAESStreamCBC(SS, 0, AESKey256, InitVector, DS);
end;
end;
end;
end;
DS.Position := 0;
SetLength(BytesValue, DS.size);
DS.ReadBuffer(BytesValue[0], DS.size);
Result := PKCS5_DePadding(BytesValue);
finally
SS.Free;
DS.Free;
end;
end;
END.