, , . . . () . .
2016
Firebird 3. , , . , , , . Firebird. ,
. , , , , - ++ Firebird API.
,
Windows x64.
Triple DES (3DES). . 4 .
|
|
CiKeyHolder.dll |
Firebird |
CiDbCrypt.dll |
Firebird |
CiFbEnc_x86.dll |
32 bit. |
CiFbEnc_x86-64.dll |
64 bit. |
ICiFbEncActivator.h |
++ |
CI.ICiFbEncActivator.pas |
Delphi |
, , ( ), . , .
, , , , , .
Windows 10 x64, IDE Embarcadero RAD Studio ( 10.2 Tokyo 30- ), Firebird (
)
Firebird 3.0.2 x64,
https://www.firebirdsql.org/en/firebird-3-0-2 . , , .
SYSDBA
masterkey
.
, Firebird, . Firebird Embedded , , fbclient.dll. Firebird
%ProgramW6432%\Firebird\Firebird_3_0
.
() databases.conf, :
TESTDB = C:\TESTAPP\DB\TESTDB.FDB
, Firebird , ,
KeyHolderPlugin
. firebird.conf. firebird.conf, :
KeyHolderPlugin = CiKeyHolder
Firebird . plugins.conf, :
Plugin = CiKeyHolder {
#
Module = $(dir_plugins)/CiKeyHolder
}
Plugin = CiDbCrypt {
#
Module = $(dir_plugins)/CiDbCrypt
}
$(dir_plugins) plugins Firebird. CiKeyHolder.dll CiDbCrypt.dll.
, , Firebird, , isql.
Win + R
:
%ProgramW6432%\Firebird\Firebird_3_0\isql -q -user SYSDBA -password masterkey
- - isql, , Far.
TESTDB, :
SQL> create database 'TESTDB';
SQL> create table t_1 (i1 int, s1 varchar(15), s2 varchar(15));
SQL> insert into t_1 values (1,'value 1-1','value 1-2');
SQL> insert into t_1 values (2,'value 2-1','value 2-2');
SQL> commit;
SQL> select * from t_1;
I1 S1 S2
============ =============== ===============
1 value 1-1 value 1-2
2 value 2-1 value 2-2
SQL> show db;
Database: TESTDB
Owner: SYSDBA
PAGE_SIZE 8192
Number of DB pages allocated = 196
Number of DB pages used = 184
Number of DB pages free = 12
Sweep interval = 20000
Forced Writes are ON
Transaction - oldest = 4
Transaction - oldest active = 5
Transaction - oldest snapshot = 5
Transaction - Next = 9
ODS = 12.0
Database not encrypted
Default Character set: NONE
SQL> quit;
show db;
,
Database not encrypted
.
.
VCL Forms Application IDE Embarcadero RAD Studio. , , testapp C:\TESTAPP.
, . , . , . Firebird FireDAC. .
,
|
|
|
|
TFDPhysFBDriverLink |
FDPhysFBDriverLink1 |
- |
- |
TFDConnection |
FDConnection1 |
DriverName |
FB |
LoginPrompt |
False |
Params\Database |
TESTDB |
Params\UserName |
SYSDBA |
Params\Password |
masterkey |
Params\Protocol |
ipTCPIP |
Params\Server |
localhost |
TFDGUIxWaitCursor |
FDGUIxWaitCursor1 |
- |
- |
TFDTransaction |
FDTransaction1 |
- |
- |
TFDTable |
FDTable1 |
TableName |
T_1 |
TDataSource |
DataSource1 |
DataSet |
FDTable1 |
TDBGrid |
DBGrid1 |
DataSource |
DataSource1 |
TDBNavigator |
DBNavigator1 |
DataSource |
DataSource1 |
TButton |
Button1 |
Caption |
Connect |
TButton |
Button2 |
Caption |
Disconnect |
.
Connect:
FDConnection1->Connected = true;
FDTable1->Active = true;
Disconnect:
FDTable1->Active = false;
FDConnection1->Connected = false;
Delphi :
FDConnection1.Connected := True;
FDTable1.Active := True;
. . .
FDConnection1.Connected := False;
FDTable1.Active := False;
, . :
Win + X -> ()
:
%ProgramW6432%\Firebird\Firebird_3_0\firebird a
. .
. .
. CiFbEnc_x86.dll ICiFbEncActivator.h, CI.ICiFbEncActivator.pas C:\TESTAPP. , 32-bit Windows , - CiFbEnc_x86.dll.
:
#include "ICiFbEncActivator.h"
Ci.ICiFbEncActivator.pas Delphi.
uses
. . . , CI.ICiFbEncActivator;
: Encrypt, Decrypt Get State.
Get State. , .
, . , . -, , . .
// C++ Builder
//
std::unique_ptr mHandle(
::LoadLibraryEx(L"C:\\TESTAPP\\CiFbEnc_x86.dll",0,LOAD_WITH_ALTERED_SEARCH_PATH),
&::FreeLibrary);
if (!mHandle)
{
MessageBox(
NULL,
L" CiFbEnc_x86.dll fbclient.dll",
L" ",
MB_OK|MB_ICONERROR);
return;
}
//
typedef CALL_CONV int(__stdcall *CREATEFUNCPTR)(CI::ICiFbEncActivator**);
CREATEFUNCPTR GetActivator =
(CREATEFUNCPTR)::GetProcAddress(mHandle.get(), "createCiFBEncActivator");
if (!GetActivator)
{
MessageBox(
NULL,
L" CiFbEnc_x86.dll "
"createCiFBEncActivator"
" - , tdump.",
L" ",
MB_OK|MB_ICONERROR);
return;
}
CI::ICiFbEncActivator* pActivator = NULL;
GetActivator(&pActivator);
if (!pActivator) { ShowMessage("ERROR GetActivator!"); return; }
// . . .
//
//
//
// . . .
//
pActivator->Destroy();
pActivator = NULL;
// Delphi
var
pActivator : ICiFbEncActivator;
res : Integer;
CreateActivator: TActivatorFunction;
mHandle : HINST;
. . .
begin
//
mHandle := LoadLibraryEx(
PChar('C:\TESTAPP\CiFbEnc_x86.dll'), 0, LOAD_WITH_ALTERED_SEARCH_PATH);
if mHandle = 0 then
begin
MessageBox(
Application.Handle,
' CiFbEnc_x86.dll fbclient.dll',
' ',
MB_OK OR MB_ICONERROR);
Exit;
end;
//
CreateActivator := GetProcAddress(mHandle, 'createCiFBEncActivator');
if not Assigned(CreateActivator) then
begin
MessageBox(
Application.Handle,
' CiFbEnc_x86.dll createCiFBEncActivator'
+
' - , tdump.',
' ',
MB_OK OR MB_ICONERROR);
Exit;
end;
pActivator := nil;
res := CreateActivator(pActivator);
if not Assigned(pActivator) then begin ShowMessage('ERROR CreateActivator!'); Exit; end;
// . . .
//
//
//
// . . .
//
pActivator.Destroy;
pActivator := nil;
FreeLibrary(mHandle);
end;
, .
.
// C++ Builder
. . .
//
pActivator->SetDBAccess("localhost:TESTDB", "SYSDBA", "masterkey");
// , Firebird
char stat_buf[1024] = { 0 };
size_t bufsize = sizeof(stat_buf);
int res = pActivator->GetStateSVC(stat_buf, bufsize);
String sStatMsg = (String)stat_buf;
if (Err_OK == res)
{
MessageBox(NULL, sStatMsg.c_str(), L" ", MB_OK|MB_ICONINFORMATION);
}
else
{
String sErrMsg = L"ERROR GetStateSVC: " + sStatMsg;
MessageBox(
NULL,
sErrMsg.c_str(),
L" ",
MB_OK|MB_ICONERROR);
}
. . .
// Delphi
var
. . .
stat_buf : array[0..1023] of AnsiChar;
bufsize : NativeUInt;
. . .
//
res := pActivator.SetDBAccess('localhost:TESTDB', 'SYSDBA', 'masterkey');
// , Firebird
bufsize := SizeOf(stat_buf);
ZeroMemory(@stat_buf, bufsize);
res := pActivator.GetStateSVC(stat_buf, bufsize);
if Err_OK = res then
begin
MessageBox(Application.Handle, PChar(String(stat_buf)),
' ', MB_OK OR MB_ICONINFORMATION);
end
else
begin
MessageBox(Application.Handle, PChar(String(stat_buf)),
'', MB_OK OR MB_ICONERROR);
end;
. . .
, , .
, . . . .
// C++ Builder
// - 192
const uint8_t key[24] =
{
0x06,0xDE,0x81,0xA1,0x30,0x55,0x1A,0xC9,
0x9C,0xA3,0x42,0xA9,0xB6,0x0F,0x54,0xF0,
0xB6,0xF9,0x70,0x18,0x85,0x04,0x83,0xBF
};
// Delphi
const
key : array [0..23] of Byte =
(
$06,$DE,$81,$A1,$30,$55,$1A,$C9,
$9C,$A3,$42,$A9,$B6,$0F,$54,$F0,
$B6,$F9,$70,$18,$85,$04,$83,$BF
);
, , , , . :
// C++ Builder
. . .
//
pActivator->SetDBAccess("localhost:TESTDB", "SYSDBA", "masterkey");
//
int res = pActivator->SetKey(&key, sizeof(key));
if (Err_OK != res) { ShowMessage("ERROR SetKey!"); pActivator->Destroy(); return; }
//
res = pActivator->Activate();
if (Err_OK != res)
{
//
char errmsg[512] = {0};
size_t esize = sizeof(errmsg);
pActivator->GetFBStat(errmsg, esize);
String sErrMsg = "ERROR Activate: " + String(errmsg);
MessageBox(
NULL,
sErrMsg.w_str(),
L" ",
MB_OK|MB_ICONERROR);
pActivator->Destroy();
return;
}
. . .
// Delphi
. . .
//
res := pActivator.SetDBAccess('localhost:TESTDB', 'SYSDBA', 'masterkey');
//
res := pActivator.SetKey(@key, Length(key));
if Err_OK <> res then begin ShowMessage('ERROR SetKey!'); pActivator.Destroy; Exit; end;
//
res := pActivator.Activate;
if Err_OK <> res then
begin
bufsize := SizeOf(errmsg);
ZeroMemory(@errmsg, bufsize);
pActivator.GetFBStat(errmsg, bufsize);
MessageBox(
Application.Handle,
PChar('ERROR Activate: ' + String(errmsg)),
' ',
MB_OK OR MB_ICONERROR);
pActivator.Destroy;
Exit;
end;
. . .
, . . Firebird. . Firebird . Firebird.
Encrypt Decrypt. , :
// C++ Builder
//
res = pActivator->Encrypt();
. . .
//
res = pActivator->Decrypt();
// Delphi
//
res := pActivator.Encrypt;
. . .
//
res := pActivator.Decrypt;
.
. , .
, Connect .
. . .
C++ Builder// C++ Builder
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//
std::unique_ptr mHandle(
::LoadLibraryEx(L"C:\\TESTAPP\\CiFbEnc_x86.dll", 0,
LOAD_WITH_ALTERED_SEARCH_PATH),
&::FreeLibrary);
if (!mHandle)
{
MessageBox(
NULL,
L" CiFbEnc_x86.dll fbclient.dll",
L" ",
MB_OK|MB_ICONERROR);
return;
}
//
typedef CALL_CONV int(__stdcall *CREATEFUNCPTR)(CI::ICiFbEncActivator**);
CREATEFUNCPTR GetActivator =
(CREATEFUNCPTR)::GetProcAddress(mHandle.get(), "createCiFBEncActivator");
if (!GetActivator)
{
MessageBox(
NULL,
L" CiFbEnc_x86.dll"
" createCiFBEncActivator"
" - , tdump.",
L" ",
MB_OK|MB_ICONERROR);
return;
}
CI::ICiFbEncActivator* pActivator = NULL;
GetActivator(&pActivator);
if (!pActivator) { ShowMessage("ERROR GetActivator!"); return; }
//
pActivator->SetDBAccess("localhost:TESTDB", "SYSDBA", "masterkey");
//
int res = pActivator->SetKey(&key, sizeof(key));
if (Err_OK != res) { ShowMessage("ERROR SetKey!"); pActivator->Destroy();return; }
//
res = pActivator->Activate();
if (Err_OK != res)
{
//
char errmsg[512] = {0};
size_t esize = sizeof(errmsg);
pActivator->GetFBStat(errmsg, esize);
String sErrMsg = "ERROR Activate: " + String(errmsg);
MessageBox(
NULL,
sErrMsg.w_str(),
L" ",
MB_OK|MB_ICONERROR);
pActivator->Destroy();
return;
}
//
try
{
FDConnection1->Connected = true;
FDTable1->Active = true;
}
catch(EFDDBEngineException &e)
{
String sErrMsg = L" . " + e.Message;
MessageBox(
NULL,
sErrMsg.w_str(),
L" ",
MB_OK|MB_ICONERROR);
}
//
pActivator->Destroy();
pActivator = NULL;
}
Delphi// Delphi
procedure TForm2.Button1Click(Sender: TObject);
var
pActivator : ICiFbEncActivator;
res : Integer;
CreateActivator: TActivatorFunction;
mHandle : HINST;
errmsg : array[0..511] of AnsiChar;
bufsize : NativeUInt;
begin
//
mHandle := LoadLibraryEx(PChar('C:\TESTAPP\CiFbEnc_x86.dll'), 0,
LOAD_WITH_ALTERED_SEARCH_PATH);
if mHandle = 0 then
begin
MessageBox(
Application.Handle,
' CiFbEnc_x86.dll fbclient.dll',
' ',
MB_OK OR MB_ICONERROR);
Exit;
end;
//
CreateActivator := GetProcAddress(mHandle, 'createCiFBEncActivator');
if not Assigned(CreateActivator) then
begin
MessageBox(
Application.Handle,
' CiFbEnc_x86.dll createCiFBEncActivator'
+
' - , tdump.',
' ',
MB_OK OR MB_ICONERROR);
Exit;
end;
pActivator := nil;
res := CreateActivator(pActivator);
if not Assigned(pActivator) then begin ShowMessage('ERROR CreateActivator!');Exit; end;
//
res := pActivator.SetDBAccess('localhost:TESTDB', 'SYSDBA', 'masterkey');
//
res := pActivator.SetKey(@key, Length(key));
if Err_OK <> res then begin ShowMessage('ERROR SetKey!'); pActivator.Destroy;Exit; end;
//
res := pActivator.Activate;
if Err_OK <> res then
begin
bufsize := SizeOf(errmsg);
ZeroMemory(@errmsg, bufsize);
pActivator.GetFBStat(errmsg, bufsize);
MessageBox(
Application.Handle,
PChar('ERROR Activate: ' + String(errmsg)),
' ',
MB_OK OR MB_ICONERROR);
pActivator.Destroy;
Exit;
end;
//
try
FDConnection1.Connected := True;
FDTable1.Active := True;
except
on E: EFDDBEngineException do begin
MessageBox(
Application.Handle,
PChar(' . ' + String(E.Message)),
' ',
MB_OK OR MB_ICONERROR);
end;
end;
//
pActivator.Destroy;
pActivator := nil;
FreeLibrary(mHandle);
end;
.
.
-
.
https://habrahabr.ru/post/331002/