424 lines
10 KiB
Plaintext
424 lines
10 KiB
Plaintext
{*******************************************************}
|
|
{ }
|
|
{ Tocsg.DRM.Encrypt }
|
|
{ }
|
|
{ Copyright (C) 2022 kkuzil }
|
|
{ }
|
|
{*******************************************************}
|
|
|
|
unit Tocsg.DRM.Encrypt;
|
|
|
|
interface
|
|
|
|
uses
|
|
Tocsg.Obj, System.SysUtils, System.Classes, Winapi.Windows;
|
|
|
|
const
|
|
DRM_VER = 3; // 2 : 헤더 문자열 정보에 솔트 추가 22_1019 12:48:14 kku
|
|
MAX_HEAD_STR = 260;
|
|
|
|
type
|
|
TTgDrmHead = packed record // size = 1574
|
|
wVer: WORD;
|
|
dwCustomerCode: DWORD;
|
|
sEmpNo,
|
|
sHostName,
|
|
sPartName,
|
|
sPgName,
|
|
sReserve1,
|
|
sReserve2: array [0..MAX_HEAD_STR-1] of UTF8Char;
|
|
dtEnc: TDateTime;
|
|
// ullEncTS: ULONGLONG; // DRM_VER 3 이상
|
|
// sReserve3: array [0..17] of AnsiChar; // DRM_VER 3 이상
|
|
end;
|
|
|
|
TTgDrmBase = class(TTgObject)
|
|
protected
|
|
bFreeStream_: Boolean;
|
|
Stream_: TStream;
|
|
Head_: TTgDrmHead;
|
|
public
|
|
Constructor Create(aStream: TStream; bFreeStream: Boolean = true);
|
|
Destructor Destroy; override;
|
|
end;
|
|
|
|
TTgDrmEnc = class(TTgDrmBase)
|
|
public
|
|
Constructor Create(sPath: String);
|
|
|
|
function SetHaed(sKey, sSig, sEmpNo, sHostName, sPartName, sPgName: UTF8String; dwCode: DWORD): Boolean;
|
|
function EncryptFromFile(sKey: String; sPath: String): Boolean;
|
|
function EncryptFromStream(sKey: String; aSrcStream: TStream): Boolean;
|
|
end;
|
|
|
|
TTgDrmDec = class(TTgDrmBase)
|
|
private
|
|
sEmpNo_,
|
|
sHostName_,
|
|
sPartName_,
|
|
sPgName_: String;
|
|
public
|
|
Constructor Create(sEncPath: String); overload;
|
|
Constructor Create(aStream: TStream; bFreeStream: Boolean = true); overload;
|
|
|
|
function CheckSig(sSig: AnsiString): Boolean;
|
|
function ExtrHead(sKey: String): Boolean;
|
|
|
|
function DecryptToFile(sKey: String; sPath: String): Boolean;
|
|
function DecryptToStream(sKey: String; aDecStream: TStream): Boolean;
|
|
|
|
property Head: TTgDrmHead read Head_;
|
|
property EmpNo: String read sEmpNo_;
|
|
property HostName: String read sHostName_;
|
|
property PartName: String read sPartName_;
|
|
property PolicyGroup: String read sPgName_;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
Tocsg.Encrypt, Tocsg.Safe, Tocsg.Exception, Tocsg.Strings;
|
|
|
|
{ TTgDrmBase }
|
|
|
|
Constructor TTgDrmBase.Create(aStream: TStream; bFreeStream: Boolean = true);
|
|
begin
|
|
Inherited Create;
|
|
ZeroMemory(@Head_, SizeOf(Head_));
|
|
Head_.wVer := DRM_VER;
|
|
Stream_ := aStream;
|
|
bFreeStream_ := bFreeStream;
|
|
end;
|
|
|
|
Destructor TTgDrmBase.Destroy;
|
|
begin
|
|
if bFreeStream_ and (Stream_ <> nil) then
|
|
FreeAndNil(Stream_);
|
|
Inherited;
|
|
end;
|
|
|
|
{ TTgDrmEnc }
|
|
|
|
Constructor TTgDrmEnc.Create(sPath: String);
|
|
var
|
|
fs: TFileStream;
|
|
begin
|
|
try
|
|
fs := TFileStream.Create(sPath, fmCreate);
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
Inherited Create(nil, false);
|
|
ETgException.TraceException(Self, E, 'Fail .. Create(Path)');
|
|
exit;
|
|
end;
|
|
end;
|
|
Inherited Create(fs);
|
|
end;
|
|
|
|
function TTgDrmEnc.SetHaed(sKey, sSig, sEmpNo, sHostName, sPartName, sPgName: UTF8String; dwCode: DWORD): Boolean;
|
|
var
|
|
enc: TTgEncrypt;
|
|
nLen: Integer;
|
|
pEncBuf: TBytes;
|
|
begin
|
|
Result := false;
|
|
|
|
try
|
|
{$IFDEF DEBUG}
|
|
ASSERT(Stream_ <> nil);
|
|
{$ENDIF}
|
|
if Stream_ = nil then
|
|
begin
|
|
_Trace('Fail .. SetHaed() .. Stream is nil');
|
|
exit;
|
|
end;
|
|
|
|
Stream_.Position := 0;
|
|
if sSig <> '' then
|
|
Stream_.Write(sSig[1], Length(sSig));
|
|
if Length(sEmpNo) < 250 then
|
|
sEmpNo := sEmpNo + '§+' + GetRandomStr(5, 8);
|
|
if Length(sHostName) < 250 then
|
|
sHostName := sHostName + '§+' + GetRandomStr(5, 8);
|
|
if Length(sPartName) < 250 then
|
|
sPartName := sPartName + '§+' + GetRandomStr(5, 8);
|
|
if Length(sPgName) < 250 then
|
|
sPgName := sPgName + '§+' + GetRandomStr(5, 8);
|
|
|
|
StrCopy(Head_.sEmpNo, PUTF8Char(sEmpNo));
|
|
StrCopy(Head_.sHostName, PUTF8Char(sHostName));
|
|
StrCopy(Head_.sPartName, PUTF8Char(sPartName));
|
|
StrCopy(Head_.sPgName, PUTF8Char(sPgName));
|
|
Head_.dwCustomerCode := dwCode;
|
|
// Head_.dtEnc := Now;
|
|
|
|
Guard(enc, TTgEncrypt.Create(sKey, ekAes256cbc));
|
|
nLen := SizeOf(Head_);
|
|
enc.InitEncrypt;
|
|
pEncBuf := enc.EncryptBuffer(@Head_, nLen);
|
|
{$IFDEF DEBUG}
|
|
ASSERT(Length(pEncBuf) = nLen);
|
|
{$ELSE}
|
|
if Length(pEncBuf) <> nLen then
|
|
begin
|
|
_Trace('Fail .. Encrypt Head .. HeadLen=%d, OutLen=%d', [nLen, Length(pEncBuf)]);
|
|
exit;
|
|
end;
|
|
{$ENDIF}
|
|
Stream_.Write(pEncBuf[0], nLen);
|
|
Result := true;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. SetHaed()');
|
|
end;
|
|
end;
|
|
|
|
function TTgDrmEnc.EncryptFromFile(sKey: String; sPath: String): Boolean;
|
|
var
|
|
fs: TFileStream;
|
|
begin
|
|
Result := false;
|
|
|
|
try
|
|
Guard(fs, TFileStream.Create(sPath, fmOpenRead));
|
|
Result := EncryptFromStream(sKey, fs);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. EncryptFromFile()');
|
|
end;
|
|
end;
|
|
|
|
function TTgDrmEnc.EncryptFromStream(sKey: String; aSrcStream: TStream): Boolean;
|
|
var
|
|
enc: TTgEncrypt;
|
|
sDateTime: String;
|
|
begin
|
|
Result := false;
|
|
{$IFDEF DEBUG}
|
|
ASSERT(Stream_ <> nil);
|
|
{$ENDIF}
|
|
if Stream_ = nil then
|
|
begin
|
|
_Trace('Fail .. EncryptFromStream() .. Stream is nil');
|
|
exit;
|
|
end;
|
|
|
|
try
|
|
if Head_.dtEnc <> 0 then
|
|
sDateTime := FormatDateTime('yyyymmddhhnnss', Head_.dtEnc)
|
|
else
|
|
sDateTime := '';
|
|
Guard(enc, TTgEncrypt.Create(sDateTime + sKey, ekAes256cbc));
|
|
Result := enc.EncryptStream(aSrcStream, Stream_, '', phNone);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. EncryptFromStream()');
|
|
end;
|
|
end;
|
|
|
|
{ TTgDrmDec }
|
|
|
|
Constructor TTgDrmDec.Create(sEncPath: String);
|
|
var
|
|
fs: TFileStream;
|
|
begin
|
|
try
|
|
fs := TFileStream.Create(sEncPath, fmOpenRead or fmShareDenyNone);
|
|
except
|
|
on E: Exception do
|
|
begin
|
|
Create(nil, false);
|
|
ETgException.TraceException(Self, E, 'Fail .. Create(Path)');
|
|
exit;
|
|
end;
|
|
end;
|
|
Create(fs);
|
|
end;
|
|
|
|
Constructor TTgDrmDec.Create(aStream: TStream; bFreeStream: Boolean = true);
|
|
begin
|
|
Inherited Create(aStream, bFreeStream);
|
|
end;
|
|
|
|
function TTgDrmDec.CheckSig(sSig: AnsiString): Boolean;
|
|
var
|
|
nLen: Integer;
|
|
pBuf: TBytes;
|
|
begin
|
|
Result := false;
|
|
{$IFDEF DEBUG}
|
|
ASSERT(Stream_ <> nil);
|
|
{$ENDIF}
|
|
if Stream_ = nil then
|
|
begin
|
|
if Stream_ is TFileStream then
|
|
_Trace('Fail .. CheckSig() .. Stream is nil, FileName=%s', [TFileStream(Stream_).FileName])
|
|
else
|
|
_Trace('Fail .. CheckSig() .. Stream is nil');
|
|
exit;
|
|
end;
|
|
|
|
try
|
|
nLen := Length(sSig);
|
|
if Stream_.Size <= nLen then
|
|
begin
|
|
if Stream_ is TFileStream then
|
|
_Trace('Fail .. CheckSig() .. Stream size not enouth, FileName=%s, StreamSize=%d', [TFileStream(Stream_).FileName, Stream_.Size])
|
|
else
|
|
_Trace('Fail .. CheckSig() .. Stream size not enouth, StreamSize=%d', [Stream_.Size]);
|
|
exit;
|
|
end;
|
|
|
|
Stream_.Position := 0;
|
|
if nLen > 0 then
|
|
begin
|
|
SetLength(pBuf, nLen);
|
|
Stream_.Read(pBuf[0], nLen);
|
|
Result := CompareMem(@pBuf[0], @sSig[1], nLen);
|
|
end else
|
|
Result := true;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. CheckSig()');
|
|
end;
|
|
end;
|
|
|
|
function TTgDrmDec.ExtrHead(sKey: String): Boolean;
|
|
|
|
function GetStr(var arrStr: array of UTF8Char): String;
|
|
var
|
|
nPos: Integer;
|
|
begin
|
|
Result := UTF8String(arrStr);
|
|
if Head_.wVer <= 1 then
|
|
exit;
|
|
|
|
nPos := Pos('§+', Result);
|
|
if nPos = 0 then
|
|
exit;
|
|
|
|
SetLength(Result, nPos - 1);
|
|
FillChar(arrStr[nPos - 1], MAX_HEAD_STR - nPos, #0);
|
|
end;
|
|
|
|
var
|
|
nLen: Integer;
|
|
enc: TTgEncrypt;
|
|
pEncBuf, pBuf: TBytes;
|
|
// bRetry: Boolean;
|
|
//Label
|
|
// LB_Retry;
|
|
begin
|
|
Result := false;
|
|
{$IFDEF DEBUG}
|
|
ASSERT(Stream_ <> nil);
|
|
{$ENDIF}
|
|
if Stream_ = nil then
|
|
begin
|
|
_Trace('Fail .. ExtrHead() .. Stream is nil');
|
|
exit;
|
|
end;
|
|
|
|
// bRetry := false;
|
|
try
|
|
nLen := SizeOf(Head_);
|
|
if (Stream_.Size - Stream_.Position) <= nLen then
|
|
begin
|
|
_Trace('Fail .. CheckSig() .. Stream size not enouth, StreamSize=%d', [Stream_.Size]);
|
|
exit;
|
|
end;
|
|
|
|
// LB_Retry :
|
|
SetLength(pEncBuf, nLen);
|
|
Stream_.Read(pEncBuf[0], nLen);
|
|
|
|
enc := TTgEncrypt.Create(sKey, ekAes256cbc);
|
|
try
|
|
enc.InitDecrypt;
|
|
pBuf := enc.DecryptBuffer(@pEncBuf[0], nLen);
|
|
if Length(pBuf) <> nLen then
|
|
begin
|
|
_Trace('Fail .. ExtrHead() .. DecryptBufferEx()');
|
|
exit;
|
|
end;
|
|
finally
|
|
enc.Free;
|
|
end;
|
|
|
|
// var fs: TFileStream;
|
|
// Guard(fs, TFileStream.Create('C:\taskToCSG\eCrmHE\Utils\EXE_Bs1Drm4c\x64\Debug\test_d.dat', fmCreate));
|
|
// fs.Write(pBuf[0], nLen);
|
|
|
|
CopyMemory(@Head_, @pBuf[0], nLen);
|
|
Result := Head_.wVer <> 0;
|
|
sEmpNo_ := GetStr(Head_.sEmpNo);
|
|
sHostName_ := GetStr(Head_.sHostName);
|
|
sPartName_ := GetStr(Head_.sPartName);
|
|
sPgName_ := GetStr(Head_.sPgName);
|
|
|
|
// if not bRetry and (Head_.wVer < 3) then
|
|
// begin
|
|
// ZeroMemory(@Head_, SizeOf(Head_));
|
|
// nLen := 1574; // 구버전 헤더 크기
|
|
// Stream_.Position := 5;
|
|
// bRetry := true;
|
|
// goto LB_Retry;
|
|
// end;
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. ExtrHead()');
|
|
end;
|
|
end;
|
|
|
|
function TTgDrmDec.DecryptToFile(sKey: String; sPath: String): Boolean;
|
|
var
|
|
fs: TFileStream;
|
|
begin
|
|
Result := false;
|
|
|
|
try
|
|
Guard(fs, TFileStream.Create(sPath, fmCreate));
|
|
Result := DecryptToStream(sKey, fs);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. DecryptToFile()');
|
|
end;
|
|
end;
|
|
|
|
function TTgDrmDec.DecryptToStream(sKey: String; aDecStream: TStream): Boolean;
|
|
var
|
|
enc: TTgEncrypt;
|
|
sDateTime: String;
|
|
begin
|
|
Result := false;
|
|
{$IFDEF DEBUG}
|
|
ASSERT(Stream_ <> nil);
|
|
{$ENDIF}
|
|
if Stream_ = nil then
|
|
begin
|
|
_Trace('Fail .. DecryptToStream() .. Stream is nil');
|
|
exit;
|
|
end;
|
|
|
|
try
|
|
if Head_.wVer = 0 then
|
|
begin
|
|
_Trace('Fail .. DecryptToStream() .. No Extract headInfo');
|
|
exit;
|
|
end;
|
|
|
|
if Head_.dtEnc <> 0 then
|
|
sDateTime := FormatDateTime('yyyymmddhhnnss', Head_.dtEnc)
|
|
else
|
|
sDateTime := '';
|
|
Guard(enc, TTgEncrypt.Create(sDateTime + sKey, ekAes256cbc));
|
|
Result := enc.DecryptStream(Stream_, aDecStream, '', phNone);
|
|
except
|
|
on E: Exception do
|
|
ETgException.TraceException(Self, E, 'Fail .. DecryptToStream()');
|
|
end;
|
|
end;
|
|
|
|
end.
|