Скрыть пароль пользователя подключения в памяти в delphi TadoConnection
Я сделал пример приложения в Delphi xe10 и зашифровал идентификатор пользователя и пароль, а также имя базы данных и расшифровал при подключении. Проблема в том, что когда я открываю exe-процесс в памяти с помощью сканера памяти, я могу легко найти их все, выполнив поиск в некоторой части соединения. строка, это так легко найти данные безопасного соединения в Win приложениях, или я сделал что-то не так?
3 ответа
Не вводите пароль в строку подключения. Вместо этого назначьте обработчик события OnWillConnect для TADOConnection и укажите пароль в предоставленном параметре.
Думая из коробки.... почему вы хотите скрыть пароль?
Если база данных находится на компьютере пользователя, то он / она может открыть базу данных просто с помощью режима аутентификации Windows, используя SQL Management Studio без пароля!
Если база данных находится на удаленном сервере, убедитесь, что лучше написать веб-сервис, который извлекает данные и отправляет результат в формате XML для вашей программы, а не для удаленного открытия базы данных.
Попробуйте защитить память. Используйте CryptProtectMemory и CryptUnprotectMemory.
https://msdn.microsoft.com/de-de/library/windows/desktop/aa380262(v=vs.85).aspx
Вот небольшой фрагмент из моего класса. Играть с этим:
uses
Winapi.Windows,
System.SysUtils;
....
TMyMemEncryptBlaBla = class
private
//......
public
function MemEncrypt(const StrInp: String; CryptFlags: DWORD = 0): TBytes;
function MemDecrypt(const EncInp: TBytes; CryptFlags: DWORD = 0): String;
end;
{
BOOL WINAPI CryptProtectMemory(_Inout_ LPVOID pData,
_In_ DWORD cbData,
_In_ DWORD dwFlags );
}
function CryptProtectMemory(Data: Pointer; Size: DWORD; Flags: DWORD) : BOOL; stdcall;
{
BOOL WINAPI CryptUnprotectMemory(_Inout_ LPVOID pData,
_In_ DWORD cbData,
_In_ DWORD dwFlags );
}
function CryptUnProtectMemory(Data: Pointer; Size : DWORD;Flags: DWORD) : BOOL; stdcall;
// CryptProtectMemory and CryptUnprotectMemory.
CRYPTPROTECTMEMORY_SAME_PROCESS = 0; // Set as default
CRYPTPROTECTMEMORY_CROSS_PROCESS = 1;
CRYPTPROTECTMEMORY_SAME_LOGON = 2;
CRYPTPROTECTMEMORY_BLOCK_SIZE = 16;
implementation
function CryptProtectMemory; external 'Crypt32.dll' Name 'CryptProtectMemory';
function CryptUnProtectMemory; external 'Crypt32.dll' Name 'CryptUnprotectMemory';
// encrypt
function TMyMemEncryptBlaBla.MemEncrypt(const StrInp: String; CryptFlags: DWORD): TBytes;
begin
Result := TEncoding.Unicode.GetBytes(StrInp);
try
if Length(Result) mod CRYPTPROTECTMEMORY_BLOCK_SIZE <> 0 then
SetLength(Result, ((Length(Result) div CRYPTPROTECTMEMORY_BLOCK_SIZE) + 1) * CRYPTPROTECTMEMORY_BLOCK_SIZE);
except
on E:Exception do
begin
MessageBox(0, PChar(E.Message), PChar('E_OUTOFMEMORY'), MB_ICONERROR or MB_OK);
end;
end;
try
if not CryptProtectMemory(Result, Length(Result), CryptFlags) then
begin
MessageBox(0, PChar('MemCrypt: ' + SysErrorMessage(GetLastError)), PChar('MemEncrypt failed'), MB_ICONERROR or MB_OK);
ZeroMemory(Result, Length(Result));
end;
except
on E:Exception do
begin
MessageBox(0, PChar(E.Message), PChar('MemEncrypt Exception'), MB_ICONERROR or MB_OK);
end;
end;
end;
//decrypt
function TMyMemEncryptBlaBla.MemDecrypt(const EncInp: TBytes; CryptFlags: DWORD): String;
var
DecTmp: TBytes;
begin
DecTmp := Copy(EncInp);
try
if CryptUnprotectMemory(DecTmp, Length(DecTmp), CryptFlags) then
Result := TEncoding.Unicode.GetString(DecTmp)
else
MessageBox(0, PChar('MemDecrypt: ' + SysErrorMessage(GetLastError)), PChar('MemDecrypt failed'), MB_ICONERROR or MB_OK);
ZeroMemory(DecTmp, Length(DecTmp));
except
on E:Exception do
MessageBox(0, PChar(E.Message), PChar('MemDecrypt Exception'), MB_ICONERROR or MB_OK);
end;
end;
end.
Axel