Windows Credential Storage/de
Deutsch · English
(Windows only)
Mit der Windows Anmeldeinformationsverwaltung (EN: Credential Manager) kann eine Anwendung sensible Benutzernamen und Kennworte sicher speichern ohne diese in einer offen einsehbaren Konfigurationsdatei ablegen zu müssen.
Die hier bereitgestellte Unit stellt drei Funktionen bereit um die Kennworte zu lesen, schreiben und zu löschen. Bei jedem Aufruf muss eine Identifikation der Anmeldeinformationen (Parameter Target) mitgegeben werden.
unit uwincred;
// Original Source https://stackoverflow.com/questions/13145112/secure-way-to-store-password-in-windows
// Angepasst für Free Pascal
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, windows, JwaWinCred;
function CredReadGenericCredentials(const Target: UnicodeString; var Username, Password: UnicodeString): Boolean;
function CredWriteGenericCredentials(const Target, Username, Password: UnicodeString): Boolean;
function CredDeleteGenericCredentials(const Target: UnicodeString): Boolean;
implementation
function WideCharToWideString(s: PWideChar; UnicodeCharCount: SizeInt): UnicodeString;
begin
SetLength(Result{%H-}, UnicodeCharCount);
strmove(PWideChar(Result), s, UnicodeCharCount);
end;
function CredReadGenericCredentials(const Target: UnicodeString; var Username, Password: UnicodeString): Boolean;
var
credential: PCREDENTIALW;
le: DWORD;
s: UnicodeString;
begin
Result := False;
credential := nil;
if not CredReadW(PWideChar(Target), CRED_TYPE_GENERIC, 0, {var}credential) then
begin
le := GetLastError;
s := 'Could not get "'+Target+'" generic credentials: '+SysErrorMessage(le)+' '+IntToStr(le);
OutputDebugStringW(PWideChar(s));
Exit;
end;
try
username := Credential^.UserName;
password := WideCharToWideString(PWideChar(Credential^.CredentialBlob), Credential^.CredentialBlobSize div 2); //By convention blobs that contain strings do not have a trailing NULL.
finally
CredFree(Credential);
end;
Result := True;
end;
function CredWriteGenericCredentials(const Target, Username, Password: UnicodeString): Boolean;
var
Credentials: CREDENTIALW;
begin
ZeroMemory(@Credentials, SizeOf(Credentials));
Credentials.TargetName := PWideChar(Target); //cannot be longer than CRED_MAX_GENERIC_TARGET_NAME_LENGTH (32767) characters. Recommended format "Company_Target"
Credentials.Type_ := CRED_TYPE_GENERIC;
Credentials.UserName := PWideChar(Username);
Credentials.Persist := CRED_PERSIST_LOCAL_MACHINE;
Credentials.CredentialBlob := PByte(Password);
Credentials.CredentialBlobSize := 2*(Length(Password)); //By convention no trailing null. Cannot be longer than CRED_MAX_CREDENTIAL_BLOB_SIZE (512) bytes
Credentials.UserName := PWideChar(Username);
Result := CredWriteW(@Credentials, 0);
end;
function CredDeleteGenericCredentials(const Target: UnicodeString): Boolean;
begin
Result := CredDeleteW(PWideChar(Target), CRED_TYPE_GENERIC, 0);
end;
end.Die Verwendung funktioniert wie folgend. Als Target wird der Programmname verwendet.
var
StoredUserName, StoredPassword: UnicodeString;
begin
StoredUserName := '';
StoredPassword := '';
// Anmeldeinformationen lesen
CredReadGenericCredentials(Application.ExeName, StoredUserName, StoredPassword);
// Anmeldeinformationen speichern
CredWriteGenericCredentials(Application.ExeName, StoredUserName, StoredPassword);
// Anmeldeinformationen löschen
CredDeleteGenericCredentials(Application.ExeName);
end;From the Free Pascal wiki, page "Windows Credential Storage/de", as it stood on 2022-09-17 after a change by Socke, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's Licensing page. If you have concerns about this material, message the admin.